]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Fix volume-init for ALC259 with invalid widget caps
[mirror_ubuntu-eoan-kernel.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
ce764ab2
TI
302struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306};
307
d922b51d 308enum {
3b8510ce
TI
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
d922b51d
TI
312};
313
1da177e4
LT
314struct alc_spec {
315 /* codec parameterization */
a9111321 316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 317 unsigned int num_mixers;
a9111321 318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 320
2d9c6482 321 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
322 * don't forget NULL
323 * termination!
e9edcee0
TI
324 */
325 unsigned int num_init_verbs;
1da177e4 326
aa563af7 327 char stream_name_analog[32]; /* analog PCM stream */
a9111321
TI
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 332
aa563af7 333 char stream_name_digital[32]; /* digital PCM stream */
a9111321
TI
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
1da177e4
LT
336
337 /* playback */
16ded525
TI
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
341 */
6330079f 342 hda_nid_t alt_dac_nid;
6a05ac4a 343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 344 int dig_out_type;
1da177e4
LT
345
346 /* capture */
347 unsigned int num_adc_nids;
4c6d72d1
TI
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
16ded525 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1f0f4b80 351 hda_nid_t mixer_nid; /* analog-mixer NID */
1da177e4 352
840b64c0
TI
353 /* capture setup for dynamic dual-adc switch */
354 unsigned int cur_adc_idx;
355 hda_nid_t cur_adc;
356 unsigned int cur_adc_stream_tag;
357 unsigned int cur_adc_format;
358
1da177e4 359 /* capture source */
a1e8d2da 360 unsigned int num_mux_defs;
1da177e4
LT
361 const struct hda_input_mux *input_mux;
362 unsigned int cur_mux[3];
6c819492 363 struct alc_mic_route ext_mic;
8ed99d97 364 struct alc_mic_route dock_mic;
6c819492 365 struct alc_mic_route int_mic;
1da177e4
LT
366
367 /* channel model */
d2a6d7dc 368 const struct hda_channel_mode *channel_mode;
1da177e4 369 int num_channel_mode;
4e195a7b 370 int need_dac_fix;
3b315d70
HM
371 int const_channel_count;
372 int ext_channel_count;
1da177e4
LT
373
374 /* PCM information */
4c5186ed 375 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 376
e9edcee0
TI
377 /* dynamic controls, init_verbs and input_mux */
378 struct auto_pin_cfg autocfg;
da00c244 379 struct alc_customize_define cdefine;
603c4019 380 struct snd_array kctls;
61b9b9b1 381 struct hda_input_mux private_imux[3];
41923e44 382 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
383 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
384 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 385
ae6b813a
TI
386 /* hooks */
387 void (*init_hook)(struct hda_codec *codec);
388 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 389#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 390 void (*power_hook)(struct hda_codec *codec);
f5de24b0 391#endif
1c716153 392 void (*shutup)(struct hda_codec *codec);
ae6b813a 393
834be88d 394 /* for pin sensing */
834be88d 395 unsigned int jack_present: 1;
e6a5e1b7 396 unsigned int line_jack_present:1;
e9427969 397 unsigned int master_mute:1;
6c819492 398 unsigned int auto_mic:1;
d922b51d 399 unsigned int automute:1; /* HP automute enabled */
e6a5e1b7
TI
400 unsigned int detect_line:1; /* Line-out detection enabled */
401 unsigned int automute_lines:1; /* automute line-out as well */
ae8a60a5 402 unsigned int automute_hp_lo:1; /* both HP and LO available */
cb53c626 403
e64f14f4
TI
404 /* other flags */
405 unsigned int no_analog :1; /* digital I/O only */
840b64c0 406 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
584c0c4c 407 unsigned int single_input_src:1;
d922b51d
TI
408
409 /* auto-mute control */
410 int automute_mode;
3b8510ce 411 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
d922b51d 412
4a79ba34 413 int init_amp;
d433a678 414 int codec_variant; /* flag for other variants */
e64f14f4 415
2134ea4f
TI
416 /* for virtual master */
417 hda_nid_t vmaster_nid;
cb53c626
TI
418#ifdef CONFIG_SND_HDA_POWER_SAVE
419 struct hda_loopback_check loopback;
420#endif
2c3bf9ab
TI
421
422 /* for PLL fix */
423 hda_nid_t pll_nid;
424 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
425
426 /* fix-up list */
427 int fixup_id;
428 const struct alc_fixup *fixup_list;
429 const char *fixup_name;
ce764ab2
TI
430
431 /* multi-io */
432 int multi_ios;
433 struct alc_multi_io multi_io[4];
df694daa
KY
434};
435
436/*
437 * configuration template - to be copied to the spec instance
438 */
439struct alc_config_preset {
a9111321 440 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
9c7f852e
TI
441 * with spec
442 */
a9111321 443 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
444 const struct hda_verb *init_verbs[5];
445 unsigned int num_dacs;
4c6d72d1 446 const hda_nid_t *dac_nids;
df694daa
KY
447 hda_nid_t dig_out_nid; /* optional */
448 hda_nid_t hp_nid; /* optional */
4c6d72d1 449 const hda_nid_t *slave_dig_outs;
df694daa 450 unsigned int num_adc_nids;
4c6d72d1
TI
451 const hda_nid_t *adc_nids;
452 const hda_nid_t *capsrc_nids;
df694daa
KY
453 hda_nid_t dig_in_nid;
454 unsigned int num_channel_mode;
455 const struct hda_channel_mode *channel_mode;
4e195a7b 456 int need_dac_fix;
3b315d70 457 int const_channel_count;
a1e8d2da 458 unsigned int num_mux_defs;
df694daa 459 const struct hda_input_mux *input_mux;
ae6b813a 460 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 461 void (*setup)(struct hda_codec *);
ae6b813a 462 void (*init_hook)(struct hda_codec *);
cb53c626 463#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 464 const struct hda_amp_list *loopbacks;
c97259df 465 void (*power_hook)(struct hda_codec *codec);
cb53c626 466#endif
1da177e4
LT
467};
468
1da177e4
LT
469
470/*
471 * input MUX handling
472 */
9c7f852e
TI
473static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
474 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
475{
476 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
477 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
478 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
479 if (mux_idx >= spec->num_mux_defs)
480 mux_idx = 0;
5311114d
TI
481 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
482 mux_idx = 0;
a1e8d2da 483 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
484}
485
9c7f852e
TI
486static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
487 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
488{
489 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
490 struct alc_spec *spec = codec->spec;
491 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
492
493 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
494 return 0;
495}
496
9c7f852e
TI
497static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
499{
500 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
501 struct alc_spec *spec = codec->spec;
cd896c33 502 const struct hda_input_mux *imux;
1da177e4 503 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 504 unsigned int mux_idx;
e1406348
TI
505 hda_nid_t nid = spec->capsrc_nids ?
506 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 507 unsigned int type;
1da177e4 508
cd896c33
TI
509 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
510 imux = &spec->input_mux[mux_idx];
5311114d
TI
511 if (!imux->num_items && mux_idx > 0)
512 imux = &spec->input_mux[0];
cd896c33 513
a22d543a 514 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 515 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
516 /* Matrix-mixer style (e.g. ALC882) */
517 unsigned int *cur_val = &spec->cur_mux[adc_idx];
518 unsigned int i, idx;
519
520 idx = ucontrol->value.enumerated.item[0];
521 if (idx >= imux->num_items)
522 idx = imux->num_items - 1;
523 if (*cur_val == idx)
524 return 0;
525 for (i = 0; i < imux->num_items; i++) {
526 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
527 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
528 imux->items[i].index,
529 HDA_AMP_MUTE, v);
530 }
531 *cur_val = idx;
532 return 1;
533 } else {
534 /* MUX style (e.g. ALC880) */
cd896c33 535 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
536 &spec->cur_mux[adc_idx]);
537 }
538}
e9edcee0 539
1da177e4
LT
540/*
541 * channel mode setting
542 */
9c7f852e
TI
543static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
545{
546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
547 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
548 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
549 spec->num_channel_mode);
1da177e4
LT
550}
551
9c7f852e
TI
552static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
554{
555 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
556 struct alc_spec *spec = codec->spec;
d2a6d7dc 557 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 558 spec->num_channel_mode,
3b315d70 559 spec->ext_channel_count);
1da177e4
LT
560}
561
9c7f852e
TI
562static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
564{
565 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
566 struct alc_spec *spec = codec->spec;
4e195a7b
TI
567 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
568 spec->num_channel_mode,
3b315d70
HM
569 &spec->ext_channel_count);
570 if (err >= 0 && !spec->const_channel_count) {
571 spec->multiout.max_channels = spec->ext_channel_count;
572 if (spec->need_dac_fix)
573 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
574 }
4e195a7b 575 return err;
1da177e4
LT
576}
577
a9430dd8 578/*
4c5186ed 579 * Control the mode of pin widget settings via the mixer. "pc" is used
25985edc 580 * instead of "%" to avoid consequences of accidentally treating the % as
4c5186ed
JW
581 * being part of a format specifier. Maximum allowed length of a value is
582 * 63 characters plus NULL terminator.
7cf51e48
JW
583 *
584 * Note: some retasking pin complexes seem to ignore requests for input
585 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
586 * are requested. Therefore order this list so that this behaviour will not
587 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
588 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
589 * March 2006.
4c5186ed 590 */
a9111321 591static const char * const alc_pin_mode_names[] = {
7cf51e48
JW
592 "Mic 50pc bias", "Mic 80pc bias",
593 "Line in", "Line out", "Headphone out",
4c5186ed 594};
a9111321 595static const unsigned char alc_pin_mode_values[] = {
7cf51e48 596 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
597};
598/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
599 * in the pin being assumed to be exclusively an input or an output pin. In
600 * addition, "input" pins may or may not process the mic bias option
601 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
602 * accept requests for bias as of chip versions up to March 2006) and/or
603 * wiring in the computer.
a9430dd8 604 */
a1e8d2da
JW
605#define ALC_PIN_DIR_IN 0x00
606#define ALC_PIN_DIR_OUT 0x01
607#define ALC_PIN_DIR_INOUT 0x02
608#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
609#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 610
ea1fb29a 611/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
612 * For each direction the minimum and maximum values are given.
613 */
a9111321 614static const signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
615 { 0, 2 }, /* ALC_PIN_DIR_IN */
616 { 3, 4 }, /* ALC_PIN_DIR_OUT */
617 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
618 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
619 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
620};
621#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
622#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
623#define alc_pin_mode_n_items(_dir) \
624 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
625
9c7f852e
TI
626static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
627 struct snd_ctl_elem_info *uinfo)
a9430dd8 628{
4c5186ed
JW
629 unsigned int item_num = uinfo->value.enumerated.item;
630 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
631
632 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 633 uinfo->count = 1;
4c5186ed
JW
634 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
635
636 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
637 item_num = alc_pin_mode_min(dir);
638 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
639 return 0;
640}
641
9c7f852e
TI
642static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
a9430dd8 644{
4c5186ed 645 unsigned int i;
a9430dd8
JW
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 648 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 649 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
650 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
651 AC_VERB_GET_PIN_WIDGET_CONTROL,
652 0x00);
a9430dd8 653
4c5186ed
JW
654 /* Find enumerated value for current pinctl setting */
655 i = alc_pin_mode_min(dir);
4b35d2ca 656 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 657 i++;
9c7f852e 658 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
659 return 0;
660}
661
9c7f852e
TI
662static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
663 struct snd_ctl_elem_value *ucontrol)
a9430dd8 664{
4c5186ed 665 signed int change;
a9430dd8
JW
666 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
667 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
668 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
669 long val = *ucontrol->value.integer.value;
9c7f852e
TI
670 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
671 AC_VERB_GET_PIN_WIDGET_CONTROL,
672 0x00);
a9430dd8 673
f12ab1e0 674 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
675 val = alc_pin_mode_min(dir);
676
677 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
678 if (change) {
679 /* Set pin mode to that requested */
82beb8fd
TI
680 snd_hda_codec_write_cache(codec, nid, 0,
681 AC_VERB_SET_PIN_WIDGET_CONTROL,
682 alc_pin_mode_values[val]);
cdcd9268 683
ea1fb29a 684 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
685 * for the requested pin mode. Enum values of 2 or less are
686 * input modes.
687 *
688 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
689 * reduces noise slightly (particularly on input) so we'll
690 * do it. However, having both input and output buffers
691 * enabled simultaneously doesn't seem to be problematic if
692 * this turns out to be necessary in the future.
cdcd9268
JW
693 */
694 if (val <= 2) {
47fd830a
TI
695 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
696 HDA_AMP_MUTE, HDA_AMP_MUTE);
697 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
698 HDA_AMP_MUTE, 0);
cdcd9268 699 } else {
47fd830a
TI
700 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
701 HDA_AMP_MUTE, HDA_AMP_MUTE);
702 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
703 HDA_AMP_MUTE, 0);
cdcd9268
JW
704 }
705 }
a9430dd8
JW
706 return change;
707}
708
4c5186ed 709#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 710 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 711 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
712 .info = alc_pin_mode_info, \
713 .get = alc_pin_mode_get, \
714 .put = alc_pin_mode_put, \
715 .private_value = nid | (dir<<16) }
df694daa 716
5c8f858d
JW
717/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
718 * together using a mask with more than one bit set. This control is
719 * currently used only by the ALC260 test model. At this stage they are not
720 * needed for any "production" models.
721 */
722#ifdef CONFIG_SND_DEBUG
a5ce8890 723#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 724
9c7f852e
TI
725static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
726 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
727{
728 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
729 hda_nid_t nid = kcontrol->private_value & 0xffff;
730 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
731 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
732 unsigned int val = snd_hda_codec_read(codec, nid, 0,
733 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
734
735 *valp = (val & mask) != 0;
736 return 0;
737}
9c7f852e
TI
738static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
739 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
740{
741 signed int change;
742 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
743 hda_nid_t nid = kcontrol->private_value & 0xffff;
744 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
745 long val = *ucontrol->value.integer.value;
9c7f852e
TI
746 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
747 AC_VERB_GET_GPIO_DATA,
748 0x00);
5c8f858d
JW
749
750 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
751 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
752 if (val == 0)
5c8f858d
JW
753 gpio_data &= ~mask;
754 else
755 gpio_data |= mask;
82beb8fd
TI
756 snd_hda_codec_write_cache(codec, nid, 0,
757 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
758
759 return change;
760}
761#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
762 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 763 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
764 .info = alc_gpio_data_info, \
765 .get = alc_gpio_data_get, \
766 .put = alc_gpio_data_put, \
767 .private_value = nid | (mask<<16) }
768#endif /* CONFIG_SND_DEBUG */
769
92621f13
JW
770/* A switch control to allow the enabling of the digital IO pins on the
771 * ALC260. This is incredibly simplistic; the intention of this control is
772 * to provide something in the test model allowing digital outputs to be
773 * identified if present. If models are found which can utilise these
774 * outputs a more complete mixer control can be devised for those models if
775 * necessary.
776 */
777#ifdef CONFIG_SND_DEBUG
a5ce8890 778#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 779
9c7f852e
TI
780static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
781 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
782{
783 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
784 hda_nid_t nid = kcontrol->private_value & 0xffff;
785 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
786 long *valp = ucontrol->value.integer.value;
9c7f852e 787 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 788 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
789
790 *valp = (val & mask) != 0;
791 return 0;
792}
9c7f852e
TI
793static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
795{
796 signed int change;
797 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
798 hda_nid_t nid = kcontrol->private_value & 0xffff;
799 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
800 long val = *ucontrol->value.integer.value;
9c7f852e 801 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 802 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 803 0x00);
92621f13
JW
804
805 /* Set/unset the masked control bit(s) as needed */
9c7f852e 806 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
807 if (val==0)
808 ctrl_data &= ~mask;
809 else
810 ctrl_data |= mask;
82beb8fd
TI
811 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
812 ctrl_data);
92621f13
JW
813
814 return change;
815}
816#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
817 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 818 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
819 .info = alc_spdif_ctrl_info, \
820 .get = alc_spdif_ctrl_get, \
821 .put = alc_spdif_ctrl_put, \
822 .private_value = nid | (mask<<16) }
823#endif /* CONFIG_SND_DEBUG */
824
f8225f6d
JW
825/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
826 * Again, this is only used in the ALC26x test models to help identify when
827 * the EAPD line must be asserted for features to work.
828 */
829#ifdef CONFIG_SND_DEBUG
830#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
831
832static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
833 struct snd_ctl_elem_value *ucontrol)
834{
835 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
836 hda_nid_t nid = kcontrol->private_value & 0xffff;
837 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
838 long *valp = ucontrol->value.integer.value;
839 unsigned int val = snd_hda_codec_read(codec, nid, 0,
840 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
841
842 *valp = (val & mask) != 0;
843 return 0;
844}
845
846static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
847 struct snd_ctl_elem_value *ucontrol)
848{
849 int change;
850 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
851 hda_nid_t nid = kcontrol->private_value & 0xffff;
852 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
853 long val = *ucontrol->value.integer.value;
854 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
855 AC_VERB_GET_EAPD_BTLENABLE,
856 0x00);
857
858 /* Set/unset the masked control bit(s) as needed */
859 change = (!val ? 0 : mask) != (ctrl_data & mask);
860 if (!val)
861 ctrl_data &= ~mask;
862 else
863 ctrl_data |= mask;
864 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
865 ctrl_data);
866
867 return change;
868}
869
870#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
871 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 872 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
873 .info = alc_eapd_ctrl_info, \
874 .get = alc_eapd_ctrl_get, \
875 .put = alc_eapd_ctrl_put, \
876 .private_value = nid | (mask<<16) }
877#endif /* CONFIG_SND_DEBUG */
878
23f0c048
TI
879/*
880 * set up the input pin config (depending on the given auto-pin type)
881 */
882static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
883 int auto_pin_type)
884{
885 unsigned int val = PIN_IN;
886
86e2959a 887 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 888 unsigned int pincap;
954a29c8
TI
889 unsigned int oldval;
890 oldval = snd_hda_codec_read(codec, nid, 0,
891 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 892 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 893 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
894 /* if the default pin setup is vref50, we give it priority */
895 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 896 val = PIN_VREF80;
461c6c3a
TI
897 else if (pincap & AC_PINCAP_VREF_50)
898 val = PIN_VREF50;
899 else if (pincap & AC_PINCAP_VREF_100)
900 val = PIN_VREF100;
901 else if (pincap & AC_PINCAP_VREF_GRD)
902 val = PIN_VREFGRD;
23f0c048
TI
903 }
904 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
905}
906
f6837bbd
TI
907static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
908{
909 struct alc_spec *spec = codec->spec;
910 struct auto_pin_cfg *cfg = &spec->autocfg;
911
912 if (!cfg->line_outs) {
913 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
914 cfg->line_out_pins[cfg->line_outs])
915 cfg->line_outs++;
916 }
917 if (!cfg->speaker_outs) {
918 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
919 cfg->speaker_pins[cfg->speaker_outs])
920 cfg->speaker_outs++;
921 }
922 if (!cfg->hp_outs) {
923 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
924 cfg->hp_pins[cfg->hp_outs])
925 cfg->hp_outs++;
926 }
927}
928
d88897ea
TI
929/*
930 */
a9111321 931static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
d88897ea
TI
932{
933 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
934 return;
935 spec->mixers[spec->num_mixers++] = mix;
936}
937
938static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
939{
940 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
941 return;
942 spec->init_verbs[spec->num_init_verbs++] = verb;
943}
944
df694daa
KY
945/*
946 * set up from the preset table
947 */
e9c364c0 948static void setup_preset(struct hda_codec *codec,
9c7f852e 949 const struct alc_config_preset *preset)
df694daa 950{
e9c364c0 951 struct alc_spec *spec = codec->spec;
df694daa
KY
952 int i;
953
954 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 955 add_mixer(spec, preset->mixers[i]);
f9e336f6 956 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
957 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
958 i++)
d88897ea 959 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 960
df694daa
KY
961 spec->channel_mode = preset->channel_mode;
962 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 963 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 964 spec->const_channel_count = preset->const_channel_count;
df694daa 965
3b315d70
HM
966 if (preset->const_channel_count)
967 spec->multiout.max_channels = preset->const_channel_count;
968 else
969 spec->multiout.max_channels = spec->channel_mode[0].channels;
970 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
971
972 spec->multiout.num_dacs = preset->num_dacs;
973 spec->multiout.dac_nids = preset->dac_nids;
974 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 975 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 976 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 977
a1e8d2da 978 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 979 if (!spec->num_mux_defs)
a1e8d2da 980 spec->num_mux_defs = 1;
df694daa
KY
981 spec->input_mux = preset->input_mux;
982
983 spec->num_adc_nids = preset->num_adc_nids;
984 spec->adc_nids = preset->adc_nids;
e1406348 985 spec->capsrc_nids = preset->capsrc_nids;
df694daa 986 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
987
988 spec->unsol_event = preset->unsol_event;
989 spec->init_hook = preset->init_hook;
cb53c626 990#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 991 spec->power_hook = preset->power_hook;
cb53c626
TI
992 spec->loopback.amplist = preset->loopbacks;
993#endif
e9c364c0
TI
994
995 if (preset->setup)
996 preset->setup(codec);
f6837bbd
TI
997
998 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
999}
1000
bc9f98a9 1001/* Enable GPIO mask and set output */
a9111321 1002static const struct hda_verb alc_gpio1_init_verbs[] = {
bc9f98a9
KY
1003 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1004 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1005 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1006 { }
1007};
1008
a9111321 1009static const struct hda_verb alc_gpio2_init_verbs[] = {
bc9f98a9
KY
1010 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1011 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1012 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1013 { }
1014};
1015
a9111321 1016static const struct hda_verb alc_gpio3_init_verbs[] = {
bdd148a3
KY
1017 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1018 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1019 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1020 { }
1021};
1022
2c3bf9ab
TI
1023/*
1024 * Fix hardware PLL issue
1025 * On some codecs, the analog PLL gating control must be off while
1026 * the default value is 1.
1027 */
1028static void alc_fix_pll(struct hda_codec *codec)
1029{
1030 struct alc_spec *spec = codec->spec;
1031 unsigned int val;
1032
1033 if (!spec->pll_nid)
1034 return;
1035 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1036 spec->pll_coef_idx);
1037 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1038 AC_VERB_GET_PROC_COEF, 0);
1039 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1040 spec->pll_coef_idx);
1041 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1042 val & ~(1 << spec->pll_coef_bit));
1043}
1044
1045static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1046 unsigned int coef_idx, unsigned int coef_bit)
1047{
1048 struct alc_spec *spec = codec->spec;
1049 spec->pll_nid = nid;
1050 spec->pll_coef_idx = coef_idx;
1051 spec->pll_coef_bit = coef_bit;
1052 alc_fix_pll(codec);
1053}
1054
9ad0e496
KY
1055static int alc_init_jacks(struct hda_codec *codec)
1056{
cd372fb3 1057#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1058 struct alc_spec *spec = codec->spec;
1059 int err;
1060 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1061 unsigned int mic_nid = spec->ext_mic.pin;
8ed99d97 1062 unsigned int dock_nid = spec->dock_mic.pin;
9ad0e496 1063
265a0247 1064 if (hp_nid) {
cd372fb3
TI
1065 err = snd_hda_input_jack_add(codec, hp_nid,
1066 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1067 if (err < 0)
1068 return err;
cd372fb3 1069 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1070 }
9ad0e496 1071
265a0247 1072 if (mic_nid) {
cd372fb3
TI
1073 err = snd_hda_input_jack_add(codec, mic_nid,
1074 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1075 if (err < 0)
1076 return err;
cd372fb3 1077 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1078 }
8ed99d97
TI
1079 if (dock_nid) {
1080 err = snd_hda_input_jack_add(codec, dock_nid,
1081 SND_JACK_MICROPHONE, NULL);
1082 if (err < 0)
1083 return err;
1084 snd_hda_input_jack_report(codec, dock_nid);
1085 }
cd372fb3 1086#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1087 return 0;
1088}
9ad0e496 1089
e6a5e1b7 1090static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
c9b58006 1091{
e6a5e1b7 1092 int i, present = 0;
c9b58006 1093
e6a5e1b7
TI
1094 for (i = 0; i < num_pins; i++) {
1095 hda_nid_t nid = pins[i];
bb35febd
TI
1096 if (!nid)
1097 break;
cd372fb3 1098 snd_hda_input_jack_report(codec, nid);
e6a5e1b7 1099 present |= snd_hda_jack_detect(codec, nid);
bb35febd 1100 }
e6a5e1b7
TI
1101 return present;
1102}
bb35febd 1103
e6a5e1b7 1104static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
e9427969 1105 bool mute, bool hp_out)
e6a5e1b7
TI
1106{
1107 struct alc_spec *spec = codec->spec;
1108 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
e9427969 1109 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
e6a5e1b7
TI
1110 int i;
1111
1112 for (i = 0; i < num_pins; i++) {
1113 hda_nid_t nid = pins[i];
a9fd4f3f
TI
1114 if (!nid)
1115 break;
3b8510ce
TI
1116 switch (spec->automute_mode) {
1117 case ALC_AUTOMUTE_PIN:
bb35febd 1118 snd_hda_codec_write(codec, nid, 0,
e6a5e1b7
TI
1119 AC_VERB_SET_PIN_WIDGET_CONTROL,
1120 pin_bits);
3b8510ce
TI
1121 break;
1122 case ALC_AUTOMUTE_AMP:
bb35febd 1123 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
e6a5e1b7 1124 HDA_AMP_MUTE, mute_bits);
3b8510ce
TI
1125 break;
1126 case ALC_AUTOMUTE_MIXER:
1127 nid = spec->automute_mixer_nid[i];
1128 if (!nid)
1129 break;
1130 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
e6a5e1b7 1131 HDA_AMP_MUTE, mute_bits);
3b8510ce 1132 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
e6a5e1b7 1133 HDA_AMP_MUTE, mute_bits);
3b8510ce 1134 break;
bb35febd 1135 }
a9fd4f3f 1136 }
c9b58006
KY
1137}
1138
e6a5e1b7
TI
1139/* Toggle internal speakers muting */
1140static void update_speakers(struct hda_codec *codec)
1141{
1142 struct alc_spec *spec = codec->spec;
1a1455de 1143 int on;
e6a5e1b7 1144
c0a20263
TI
1145 /* Control HP pins/amps depending on master_mute state;
1146 * in general, HP pins/amps control should be enabled in all cases,
1147 * but currently set only for master_mute, just to be safe
1148 */
1149 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1150 spec->autocfg.hp_pins, spec->master_mute, true);
1151
1a1455de
TI
1152 if (!spec->automute)
1153 on = 0;
1154 else
1155 on = spec->jack_present | spec->line_jack_present;
1156 on |= spec->master_mute;
e6a5e1b7 1157 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1a1455de 1158 spec->autocfg.speaker_pins, on, false);
e6a5e1b7
TI
1159
1160 /* toggle line-out mutes if needed, too */
1a1455de
TI
1161 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1162 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1163 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
e6a5e1b7 1164 return;
1a1455de
TI
1165 if (!spec->automute_lines || !spec->automute)
1166 on = 0;
1167 else
1168 on = spec->jack_present;
1169 on |= spec->master_mute;
e6a5e1b7 1170 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1a1455de 1171 spec->autocfg.line_out_pins, on, false);
e6a5e1b7
TI
1172}
1173
1174static void alc_hp_automute(struct hda_codec *codec)
1175{
1176 struct alc_spec *spec = codec->spec;
1177
1178 if (!spec->automute)
1179 return;
1180 spec->jack_present =
1181 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1182 spec->autocfg.hp_pins);
1183 update_speakers(codec);
1184}
1185
1186static void alc_line_automute(struct hda_codec *codec)
1187{
1188 struct alc_spec *spec = codec->spec;
1189
1190 if (!spec->automute || !spec->detect_line)
1191 return;
1192 spec->line_jack_present =
1193 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1194 spec->autocfg.line_out_pins);
1195 update_speakers(codec);
1196}
1197
6c819492
TI
1198static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1199 hda_nid_t nid)
1200{
1201 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1202 int i, nums;
1203
1204 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1205 for (i = 0; i < nums; i++)
1206 if (conn[i] == nid)
1207 return i;
1208 return -1;
1209}
1210
840b64c0
TI
1211/* switch the current ADC according to the jack state */
1212static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1213{
1214 struct alc_spec *spec = codec->spec;
1215 unsigned int present;
1216 hda_nid_t new_adc;
1217
1218 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1219 if (present)
1220 spec->cur_adc_idx = 1;
1221 else
1222 spec->cur_adc_idx = 0;
1223 new_adc = spec->adc_nids[spec->cur_adc_idx];
1224 if (spec->cur_adc && spec->cur_adc != new_adc) {
1225 /* stream is running, let's swap the current ADC */
f0cea797 1226 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1227 spec->cur_adc = new_adc;
1228 snd_hda_codec_setup_stream(codec, new_adc,
1229 spec->cur_adc_stream_tag, 0,
1230 spec->cur_adc_format);
1231 }
1232}
1233
7fb0d78f
KY
1234static void alc_mic_automute(struct hda_codec *codec)
1235{
1236 struct alc_spec *spec = codec->spec;
8ed99d97 1237 struct alc_mic_route *dead1, *dead2, *alive;
6c819492
TI
1238 unsigned int present, type;
1239 hda_nid_t cap_nid;
1240
b59bdf3b
TI
1241 if (!spec->auto_mic)
1242 return;
6c819492
TI
1243 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1244 return;
1245 if (snd_BUG_ON(!spec->adc_nids))
1246 return;
1247
840b64c0
TI
1248 if (spec->dual_adc_switch) {
1249 alc_dual_mic_adc_auto_switch(codec);
1250 return;
1251 }
1252
6c819492
TI
1253 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1254
8ed99d97
TI
1255 alive = &spec->int_mic;
1256 dead1 = &spec->ext_mic;
1257 dead2 = &spec->dock_mic;
1258
864f92be 1259 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1260 if (present) {
1261 alive = &spec->ext_mic;
8ed99d97
TI
1262 dead1 = &spec->int_mic;
1263 dead2 = &spec->dock_mic;
1264 }
1265 if (!present && spec->dock_mic.pin > 0) {
1266 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1267 if (present) {
1268 alive = &spec->dock_mic;
1269 dead1 = &spec->int_mic;
1270 dead2 = &spec->ext_mic;
1271 }
1272 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
6c819492
TI
1273 }
1274
6c819492
TI
1275 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1276 if (type == AC_WID_AUD_MIX) {
1277 /* Matrix-mixer style (e.g. ALC882) */
1278 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1279 alive->mux_idx,
1280 HDA_AMP_MUTE, 0);
8ed99d97
TI
1281 if (dead1->pin > 0)
1282 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1283 dead1->mux_idx,
1284 HDA_AMP_MUTE, HDA_AMP_MUTE);
1285 if (dead2->pin > 0)
1286 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1287 dead2->mux_idx,
1288 HDA_AMP_MUTE, HDA_AMP_MUTE);
6c819492
TI
1289 } else {
1290 /* MUX style (e.g. ALC880) */
1291 snd_hda_codec_write_cache(codec, cap_nid, 0,
1292 AC_VERB_SET_CONNECT_SEL,
1293 alive->mux_idx);
1294 }
cd372fb3 1295 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1296
1297 /* FIXME: analog mixer */
7fb0d78f
KY
1298}
1299
c9b58006
KY
1300/* unsolicited event for HP jack sensing */
1301static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1302{
1303 if (codec->vendor_id == 0x10ec0880)
1304 res >>= 28;
1305 else
1306 res >>= 26;
a9fd4f3f
TI
1307 switch (res) {
1308 case ALC880_HP_EVENT:
d922b51d 1309 alc_hp_automute(codec);
a9fd4f3f 1310 break;
e6a5e1b7
TI
1311 case ALC880_FRONT_EVENT:
1312 alc_line_automute(codec);
1313 break;
a9fd4f3f 1314 case ALC880_MIC_EVENT:
7fb0d78f 1315 alc_mic_automute(codec);
a9fd4f3f
TI
1316 break;
1317 }
7fb0d78f
KY
1318}
1319
1320static void alc_inithook(struct hda_codec *codec)
1321{
d922b51d 1322 alc_hp_automute(codec);
e6a5e1b7 1323 alc_line_automute(codec);
7fb0d78f 1324 alc_mic_automute(codec);
c9b58006
KY
1325}
1326
f9423e7a
KY
1327/* additional initialization for ALC888 variants */
1328static void alc888_coef_init(struct hda_codec *codec)
1329{
1330 unsigned int tmp;
1331
1332 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1333 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1334 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1335 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1336 /* alc888S-VC */
1337 snd_hda_codec_read(codec, 0x20, 0,
1338 AC_VERB_SET_PROC_COEF, 0x830);
1339 else
1340 /* alc888-VB */
1341 snd_hda_codec_read(codec, 0x20, 0,
1342 AC_VERB_SET_PROC_COEF, 0x3030);
1343}
1344
87a8c370
JK
1345static void alc889_coef_init(struct hda_codec *codec)
1346{
1347 unsigned int tmp;
1348
1349 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1350 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1351 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1352 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1353}
1354
3fb4a508
TI
1355/* turn on/off EAPD control (only if available) */
1356static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1357{
1358 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1359 return;
1360 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1361 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1362 on ? 2 : 0);
1363}
1364
691f1fcc
TI
1365/* turn on/off EAPD controls of the codec */
1366static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1367{
1368 /* We currently only handle front, HP */
39fa84e9
TI
1369 static hda_nid_t pins[] = {
1370 0x0f, 0x10, 0x14, 0x15, 0
1371 };
1372 hda_nid_t *p;
1373 for (p = pins; *p; p++)
1374 set_eapd(codec, *p, on);
691f1fcc
TI
1375}
1376
1c716153
TI
1377/* generic shutup callback;
1378 * just turning off EPAD and a little pause for avoiding pop-noise
1379 */
1380static void alc_eapd_shutup(struct hda_codec *codec)
1381{
1382 alc_auto_setup_eapd(codec, false);
1383 msleep(200);
1384}
1385
4a79ba34 1386static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1387{
4a79ba34 1388 unsigned int tmp;
bc9f98a9 1389
39fa84e9 1390 alc_auto_setup_eapd(codec, true);
4a79ba34
TI
1391 switch (type) {
1392 case ALC_INIT_GPIO1:
bc9f98a9
KY
1393 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1394 break;
4a79ba34 1395 case ALC_INIT_GPIO2:
bc9f98a9
KY
1396 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1397 break;
4a79ba34 1398 case ALC_INIT_GPIO3:
bdd148a3
KY
1399 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1400 break;
4a79ba34 1401 case ALC_INIT_DEFAULT:
c9b58006
KY
1402 switch (codec->vendor_id) {
1403 case 0x10ec0260:
1404 snd_hda_codec_write(codec, 0x1a, 0,
1405 AC_VERB_SET_COEF_INDEX, 7);
1406 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1407 AC_VERB_GET_PROC_COEF, 0);
1408 snd_hda_codec_write(codec, 0x1a, 0,
1409 AC_VERB_SET_COEF_INDEX, 7);
1410 snd_hda_codec_write(codec, 0x1a, 0,
1411 AC_VERB_SET_PROC_COEF,
1412 tmp | 0x2010);
1413 break;
1414 case 0x10ec0262:
1415 case 0x10ec0880:
1416 case 0x10ec0882:
1417 case 0x10ec0883:
1418 case 0x10ec0885:
4a5a4c56 1419 case 0x10ec0887:
20b67ddd 1420 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1421 alc889_coef_init(codec);
c9b58006 1422 break;
f9423e7a 1423 case 0x10ec0888:
4a79ba34 1424 alc888_coef_init(codec);
f9423e7a 1425 break;
0aea778e 1426#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1427 case 0x10ec0267:
1428 case 0x10ec0268:
1429 snd_hda_codec_write(codec, 0x20, 0,
1430 AC_VERB_SET_COEF_INDEX, 7);
1431 tmp = snd_hda_codec_read(codec, 0x20, 0,
1432 AC_VERB_GET_PROC_COEF, 0);
1433 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1434 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1435 snd_hda_codec_write(codec, 0x20, 0,
1436 AC_VERB_SET_PROC_COEF,
1437 tmp | 0x3000);
1438 break;
0aea778e 1439#endif /* XXX */
bc9f98a9 1440 }
4a79ba34
TI
1441 break;
1442 }
1443}
1444
1a1455de
TI
1445static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1446 struct snd_ctl_elem_info *uinfo)
1447{
ae8a60a5
TI
1448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1449 struct alc_spec *spec = codec->spec;
1450 static const char * const texts2[] = {
1451 "Disabled", "Enabled"
1452 };
1453 static const char * const texts3[] = {
1a1455de
TI
1454 "Disabled", "Speaker Only", "Line-Out+Speaker"
1455 };
ae8a60a5 1456 const char * const *texts;
1a1455de
TI
1457
1458 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1459 uinfo->count = 1;
ae8a60a5
TI
1460 if (spec->automute_hp_lo) {
1461 uinfo->value.enumerated.items = 3;
1462 texts = texts3;
1463 } else {
1464 uinfo->value.enumerated.items = 2;
1465 texts = texts2;
1466 }
1467 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1468 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1a1455de
TI
1469 strcpy(uinfo->value.enumerated.name,
1470 texts[uinfo->value.enumerated.item]);
1471 return 0;
1472}
1473
1474static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1475 struct snd_ctl_elem_value *ucontrol)
1476{
1477 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1478 struct alc_spec *spec = codec->spec;
1479 unsigned int val;
1480 if (!spec->automute)
1481 val = 0;
1482 else if (!spec->automute_lines)
1483 val = 1;
1484 else
1485 val = 2;
1486 ucontrol->value.enumerated.item[0] = val;
1487 return 0;
1488}
1489
1490static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1491 struct snd_ctl_elem_value *ucontrol)
1492{
1493 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1494 struct alc_spec *spec = codec->spec;
1495
1496 switch (ucontrol->value.enumerated.item[0]) {
1497 case 0:
1498 if (!spec->automute)
1499 return 0;
1500 spec->automute = 0;
1501 break;
1502 case 1:
1503 if (spec->automute && !spec->automute_lines)
1504 return 0;
1505 spec->automute = 1;
1506 spec->automute_lines = 0;
1507 break;
1508 case 2:
ae8a60a5
TI
1509 if (!spec->automute_hp_lo)
1510 return -EINVAL;
1a1455de
TI
1511 if (spec->automute && spec->automute_lines)
1512 return 0;
1513 spec->automute = 1;
1514 spec->automute_lines = 1;
1515 break;
1516 default:
1517 return -EINVAL;
1518 }
1519 update_speakers(codec);
1520 return 1;
1521}
1522
a9111321 1523static const struct snd_kcontrol_new alc_automute_mode_enum = {
1a1455de
TI
1524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1525 .name = "Auto-Mute Mode",
1526 .info = alc_automute_mode_info,
1527 .get = alc_automute_mode_get,
1528 .put = alc_automute_mode_put,
1529};
1530
1531static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1532
1533static int alc_add_automute_mode_enum(struct hda_codec *codec)
1534{
1535 struct alc_spec *spec = codec->spec;
1536 struct snd_kcontrol_new *knew;
1537
1538 knew = alc_kcontrol_new(spec);
1539 if (!knew)
1540 return -ENOMEM;
1541 *knew = alc_automute_mode_enum;
1542 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1543 if (!knew->name)
1544 return -ENOMEM;
1545 return 0;
1546}
1547
4a79ba34
TI
1548static void alc_init_auto_hp(struct hda_codec *codec)
1549{
1550 struct alc_spec *spec = codec->spec;
bb35febd 1551 struct auto_pin_cfg *cfg = &spec->autocfg;
1daf5f46 1552 int present = 0;
bb35febd 1553 int i;
4a79ba34 1554
1daf5f46
TI
1555 if (cfg->hp_pins[0])
1556 present++;
1557 if (cfg->line_out_pins[0])
1558 present++;
1559 if (cfg->speaker_pins[0])
1560 present++;
1561 if (present < 2) /* need two different output types */
1562 return;
ae8a60a5
TI
1563 if (present == 3)
1564 spec->automute_hp_lo = 1; /* both HP and LO automute */
4a79ba34 1565
bb35febd 1566 if (!cfg->speaker_pins[0]) {
bb35febd
TI
1567 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1568 sizeof(cfg->speaker_pins));
1569 cfg->speaker_outs = cfg->line_outs;
1570 }
1571
1572 if (!cfg->hp_pins[0]) {
1573 memcpy(cfg->hp_pins, cfg->line_out_pins,
1574 sizeof(cfg->hp_pins));
1575 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1576 }
1577
bb35febd 1578 for (i = 0; i < cfg->hp_outs; i++) {
1a1455de 1579 hda_nid_t nid = cfg->hp_pins[i];
06dec228 1580 if (!is_jack_detectable(codec, nid))
1a1455de 1581 continue;
bb35febd 1582 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1a1455de
TI
1583 nid);
1584 snd_hda_codec_write_cache(codec, nid, 0,
4a79ba34
TI
1585 AC_VERB_SET_UNSOLICITED_ENABLE,
1586 AC_USRSP_EN | ALC880_HP_EVENT);
d922b51d
TI
1587 spec->automute = 1;
1588 spec->automute_mode = ALC_AUTOMUTE_PIN;
bb35febd 1589 }
1a1455de
TI
1590 if (spec->automute && cfg->line_out_pins[0] &&
1591 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1592 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1593 for (i = 0; i < cfg->line_outs; i++) {
1594 hda_nid_t nid = cfg->line_out_pins[i];
06dec228 1595 if (!is_jack_detectable(codec, nid))
1a1455de
TI
1596 continue;
1597 snd_printdd("realtek: Enable Line-Out auto-muting "
1598 "on NID 0x%x\n", nid);
1599 snd_hda_codec_write_cache(codec, nid, 0,
1600 AC_VERB_SET_UNSOLICITED_ENABLE,
1601 AC_USRSP_EN | ALC880_FRONT_EVENT);
1602 spec->detect_line = 1;
1603 }
52d3cb88 1604 spec->automute_lines = spec->detect_line;
ae8a60a5
TI
1605 }
1606
1607 if (spec->automute) {
1a1455de
TI
1608 /* create a control for automute mode */
1609 alc_add_automute_mode_enum(codec);
ae8a60a5 1610 spec->unsol_event = alc_sku_unsol_event;
1a1455de 1611 }
4a79ba34
TI
1612}
1613
6c819492
TI
1614static void alc_init_auto_mic(struct hda_codec *codec)
1615{
1616 struct alc_spec *spec = codec->spec;
1617 struct auto_pin_cfg *cfg = &spec->autocfg;
8ed99d97 1618 hda_nid_t fixed, ext, dock;
6c819492
TI
1619 int i;
1620
8ed99d97 1621 fixed = ext = dock = 0;
66ceeb6b
TI
1622 for (i = 0; i < cfg->num_inputs; i++) {
1623 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1624 unsigned int defcfg;
6c819492 1625 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1626 switch (snd_hda_get_input_pin_attr(defcfg)) {
1627 case INPUT_PIN_ATTR_INT:
6c819492
TI
1628 if (fixed)
1629 return; /* already occupied */
8ed99d97
TI
1630 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1631 return; /* invalid type */
6c819492
TI
1632 fixed = nid;
1633 break;
99ae28be
TI
1634 case INPUT_PIN_ATTR_UNUSED:
1635 return; /* invalid entry */
8ed99d97
TI
1636 case INPUT_PIN_ATTR_DOCK:
1637 if (dock)
1638 return; /* already occupied */
1639 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1640 return; /* invalid type */
1641 dock = nid;
1642 break;
99ae28be 1643 default:
6c819492
TI
1644 if (ext)
1645 return; /* already occupied */
8ed99d97
TI
1646 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1647 return; /* invalid type */
6c819492
TI
1648 ext = nid;
1649 break;
6c819492
TI
1650 }
1651 }
8ed99d97
TI
1652 if (!ext && dock) {
1653 ext = dock;
1654 dock = 0;
1655 }
eaa9b3a7
TI
1656 if (!ext || !fixed)
1657 return;
e35d9d6a 1658 if (!is_jack_detectable(codec, ext))
6c819492 1659 return; /* no unsol support */
8ed99d97
TI
1660 if (dock && !is_jack_detectable(codec, dock))
1661 return; /* no unsol support */
1662 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1663 ext, fixed, dock);
6c819492 1664 spec->ext_mic.pin = ext;
8ed99d97 1665 spec->dock_mic.pin = dock;
6c819492
TI
1666 spec->int_mic.pin = fixed;
1667 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
8ed99d97 1668 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
6c819492
TI
1669 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1670 spec->auto_mic = 1;
1671 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1672 AC_VERB_SET_UNSOLICITED_ENABLE,
1673 AC_USRSP_EN | ALC880_MIC_EVENT);
1674 spec->unsol_event = alc_sku_unsol_event;
1675}
1676
90622917
DH
1677/* Could be any non-zero and even value. When used as fixup, tells
1678 * the driver to ignore any present sku defines.
1679 */
1680#define ALC_FIXUP_SKU_IGNORE (2)
1681
da00c244
KY
1682static int alc_auto_parse_customize_define(struct hda_codec *codec)
1683{
1684 unsigned int ass, tmp, i;
7fb56223 1685 unsigned nid = 0;
da00c244
KY
1686 struct alc_spec *spec = codec->spec;
1687
b6cbe517
TI
1688 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1689
90622917
DH
1690 if (spec->cdefine.fixup) {
1691 ass = spec->cdefine.sku_cfg;
1692 if (ass == ALC_FIXUP_SKU_IGNORE)
1693 return -1;
1694 goto do_sku;
1695 }
1696
da00c244 1697 ass = codec->subsystem_id & 0xffff;
b6cbe517 1698 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1699 goto do_sku;
1700
1701 nid = 0x1d;
1702 if (codec->vendor_id == 0x10ec0260)
1703 nid = 0x17;
1704 ass = snd_hda_codec_get_pincfg(codec, nid);
1705
1706 if (!(ass & 1)) {
1707 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1708 codec->chip_name, ass);
1709 return -1;
1710 }
1711
1712 /* check sum */
1713 tmp = 0;
1714 for (i = 1; i < 16; i++) {
1715 if ((ass >> i) & 1)
1716 tmp++;
1717 }
1718 if (((ass >> 16) & 0xf) != tmp)
1719 return -1;
1720
1721 spec->cdefine.port_connectivity = ass >> 30;
1722 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1723 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1724 spec->cdefine.customization = ass >> 8;
1725do_sku:
1726 spec->cdefine.sku_cfg = ass;
1727 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1728 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1729 spec->cdefine.swap = (ass & 0x2) >> 1;
1730 spec->cdefine.override = ass & 0x1;
1731
1732 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1733 nid, spec->cdefine.sku_cfg);
1734 snd_printd("SKU: port_connectivity=0x%x\n",
1735 spec->cdefine.port_connectivity);
1736 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1737 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1738 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1739 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1740 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1741 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1742 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1743
1744 return 0;
1745}
1746
3af9ee6b
TI
1747static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1748{
1749 int i;
1750 for (i = 0; i < nums; i++)
1751 if (list[i] == nid)
1752 return true;
1753 return false;
1754}
1755
4a79ba34
TI
1756/* check subsystem ID and set up device-specific initialization;
1757 * return 1 if initialized, 0 if invalid SSID
1758 */
1759/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1760 * 31 ~ 16 : Manufacture ID
1761 * 15 ~ 8 : SKU ID
1762 * 7 ~ 0 : Assembly ID
1763 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1764 */
1765static int alc_subsystem_id(struct hda_codec *codec,
1766 hda_nid_t porta, hda_nid_t porte,
6227cdce 1767 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1768{
1769 unsigned int ass, tmp, i;
1770 unsigned nid;
1771 struct alc_spec *spec = codec->spec;
1772
90622917
DH
1773 if (spec->cdefine.fixup) {
1774 ass = spec->cdefine.sku_cfg;
1775 if (ass == ALC_FIXUP_SKU_IGNORE)
1776 return 0;
1777 goto do_sku;
1778 }
1779
4a79ba34
TI
1780 ass = codec->subsystem_id & 0xffff;
1781 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1782 goto do_sku;
1783
1784 /* invalid SSID, check the special NID pin defcfg instead */
1785 /*
def319f9 1786 * 31~30 : port connectivity
4a79ba34
TI
1787 * 29~21 : reserve
1788 * 20 : PCBEEP input
1789 * 19~16 : Check sum (15:1)
1790 * 15~1 : Custom
1791 * 0 : override
1792 */
1793 nid = 0x1d;
1794 if (codec->vendor_id == 0x10ec0260)
1795 nid = 0x17;
1796 ass = snd_hda_codec_get_pincfg(codec, nid);
1797 snd_printd("realtek: No valid SSID, "
1798 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1799 ass, nid);
6227cdce 1800 if (!(ass & 1))
4a79ba34
TI
1801 return 0;
1802 if ((ass >> 30) != 1) /* no physical connection */
1803 return 0;
1804
1805 /* check sum */
1806 tmp = 0;
1807 for (i = 1; i < 16; i++) {
1808 if ((ass >> i) & 1)
1809 tmp++;
1810 }
1811 if (((ass >> 16) & 0xf) != tmp)
1812 return 0;
1813do_sku:
1814 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1815 ass & 0xffff, codec->vendor_id);
1816 /*
1817 * 0 : override
1818 * 1 : Swap Jack
1819 * 2 : 0 --> Desktop, 1 --> Laptop
1820 * 3~5 : External Amplifier control
1821 * 7~6 : Reserved
1822 */
1823 tmp = (ass & 0x38) >> 3; /* external Amp control */
1824 switch (tmp) {
1825 case 1:
1826 spec->init_amp = ALC_INIT_GPIO1;
1827 break;
1828 case 3:
1829 spec->init_amp = ALC_INIT_GPIO2;
1830 break;
1831 case 7:
1832 spec->init_amp = ALC_INIT_GPIO3;
1833 break;
1834 case 5:
5a8cfb4e 1835 default:
4a79ba34 1836 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1837 break;
1838 }
ea1fb29a 1839
8c427226 1840 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1841 * when the external headphone out jack is plugged"
1842 */
8c427226 1843 if (!(ass & 0x8000))
4a79ba34 1844 return 1;
c9b58006
KY
1845 /*
1846 * 10~8 : Jack location
1847 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1848 * 14~13: Resvered
1849 * 15 : 1 --> enable the function "Mute internal speaker
1850 * when the external headphone out jack is plugged"
1851 */
c9b58006 1852 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1853 hda_nid_t nid;
c9b58006
KY
1854 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1855 if (tmp == 0)
01d4825d 1856 nid = porta;
c9b58006 1857 else if (tmp == 1)
01d4825d 1858 nid = porte;
c9b58006 1859 else if (tmp == 2)
01d4825d 1860 nid = portd;
6227cdce
KY
1861 else if (tmp == 3)
1862 nid = porti;
c9b58006 1863 else
4a79ba34 1864 return 1;
3af9ee6b
TI
1865 if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1866 spec->autocfg.line_outs))
1867 return 1;
01d4825d 1868 spec->autocfg.hp_pins[0] = nid;
c9b58006 1869 }
4a79ba34
TI
1870 return 1;
1871}
ea1fb29a 1872
4a79ba34 1873static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1874 hda_nid_t porta, hda_nid_t porte,
1875 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1876{
6227cdce 1877 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1878 struct alc_spec *spec = codec->spec;
1879 snd_printd("realtek: "
1880 "Enable default setup for auto mode as fallback\n");
1881 spec->init_amp = ALC_INIT_DEFAULT;
4a79ba34 1882 }
1a1455de
TI
1883
1884 alc_init_auto_hp(codec);
1885 alc_init_auto_mic(codec);
bc9f98a9
KY
1886}
1887
f95474ec 1888/*
f8f25ba3 1889 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1890 */
1891
1892struct alc_pincfg {
1893 hda_nid_t nid;
1894 u32 val;
1895};
1896
e1eb5f10
TB
1897struct alc_model_fixup {
1898 const int id;
1899 const char *name;
1900};
1901
f8f25ba3 1902struct alc_fixup {
b5bfbc67 1903 int type;
361fe6e9
TI
1904 bool chained;
1905 int chain_id;
b5bfbc67
TI
1906 union {
1907 unsigned int sku;
1908 const struct alc_pincfg *pins;
1909 const struct hda_verb *verbs;
1910 void (*func)(struct hda_codec *codec,
1911 const struct alc_fixup *fix,
1912 int action);
1913 } v;
f8f25ba3
TI
1914};
1915
b5bfbc67
TI
1916enum {
1917 ALC_FIXUP_INVALID,
1918 ALC_FIXUP_SKU,
1919 ALC_FIXUP_PINS,
1920 ALC_FIXUP_VERBS,
1921 ALC_FIXUP_FUNC,
1922};
1923
1924enum {
1925 ALC_FIXUP_ACT_PRE_PROBE,
1926 ALC_FIXUP_ACT_PROBE,
58701120 1927 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1928};
1929
1930static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1931{
b5bfbc67
TI
1932 struct alc_spec *spec = codec->spec;
1933 int id = spec->fixup_id;
aa1d0c52 1934#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1935 const char *modelname = spec->fixup_name;
aa1d0c52 1936#endif
b5bfbc67 1937 int depth = 0;
f95474ec 1938
b5bfbc67
TI
1939 if (!spec->fixup_list)
1940 return;
1941
1942 while (id >= 0) {
1943 const struct alc_fixup *fix = spec->fixup_list + id;
1944 const struct alc_pincfg *cfg;
1945
1946 switch (fix->type) {
1947 case ALC_FIXUP_SKU:
1948 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1949 break;;
1950 snd_printdd(KERN_INFO "hda_codec: %s: "
1951 "Apply sku override for %s\n",
1952 codec->chip_name, modelname);
1953 spec->cdefine.sku_cfg = fix->v.sku;
1954 spec->cdefine.fixup = 1;
1955 break;
1956 case ALC_FIXUP_PINS:
1957 cfg = fix->v.pins;
1958 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1959 break;
1960 snd_printdd(KERN_INFO "hda_codec: %s: "
1961 "Apply pincfg for %s\n",
1962 codec->chip_name, modelname);
1963 for (; cfg->nid; cfg++)
1964 snd_hda_codec_set_pincfg(codec, cfg->nid,
1965 cfg->val);
1966 break;
1967 case ALC_FIXUP_VERBS:
1968 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1969 break;
1970 snd_printdd(KERN_INFO "hda_codec: %s: "
1971 "Apply fix-verbs for %s\n",
1972 codec->chip_name, modelname);
1973 add_verb(codec->spec, fix->v.verbs);
1974 break;
1975 case ALC_FIXUP_FUNC:
1976 if (!fix->v.func)
1977 break;
1978 snd_printdd(KERN_INFO "hda_codec: %s: "
1979 "Apply fix-func for %s\n",
1980 codec->chip_name, modelname);
1981 fix->v.func(codec, fix, action);
1982 break;
1983 default:
1984 snd_printk(KERN_ERR "hda_codec: %s: "
1985 "Invalid fixup type %d\n",
1986 codec->chip_name, fix->type);
1987 break;
1988 }
24af2b1c 1989 if (!fix->chained)
b5bfbc67
TI
1990 break;
1991 if (++depth > 10)
1992 break;
24af2b1c 1993 id = fix->chain_id;
9d57883f 1994 }
f95474ec
TI
1995}
1996
e1eb5f10 1997static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1998 const struct alc_model_fixup *models,
1999 const struct snd_pci_quirk *quirk,
2000 const struct alc_fixup *fixlist)
e1eb5f10 2001{
b5bfbc67
TI
2002 struct alc_spec *spec = codec->spec;
2003 int id = -1;
2004 const char *name = NULL;
e1eb5f10 2005
e1eb5f10
TB
2006 if (codec->modelname && models) {
2007 while (models->name) {
2008 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
2009 id = models->id;
2010 name = models->name;
e1eb5f10
TB
2011 break;
2012 }
2013 models++;
2014 }
b5bfbc67
TI
2015 }
2016 if (id < 0) {
2017 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2018 if (quirk) {
2019 id = quirk->value;
2020#ifdef CONFIG_SND_DEBUG_VERBOSE
2021 name = quirk->name;
2022#endif
2023 }
2024 }
2025
2026 spec->fixup_id = id;
2027 if (id >= 0) {
2028 spec->fixup_list = fixlist;
2029 spec->fixup_name = name;
e1eb5f10 2030 }
f95474ec
TI
2031}
2032
274693f3
KY
2033static int alc_read_coef_idx(struct hda_codec *codec,
2034 unsigned int coef_idx)
2035{
2036 unsigned int val;
2037 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2038 coef_idx);
2039 val = snd_hda_codec_read(codec, 0x20, 0,
2040 AC_VERB_GET_PROC_COEF, 0);
2041 return val;
2042}
2043
977ddd6b
KY
2044static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2045 unsigned int coef_val)
2046{
2047 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2048 coef_idx);
2049 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2050 coef_val);
2051}
2052
757899ac
TI
2053/* set right pin controls for digital I/O */
2054static void alc_auto_init_digital(struct hda_codec *codec)
2055{
2056 struct alc_spec *spec = codec->spec;
2057 int i;
1f0f4b80 2058 hda_nid_t pin, dac;
757899ac
TI
2059
2060 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2061 pin = spec->autocfg.dig_out_pins[i];
1f0f4b80
TI
2062 if (!pin)
2063 continue;
2064 snd_hda_codec_write(codec, pin, 0,
2065 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2066 if (!i)
2067 dac = spec->multiout.dig_out_nid;
2068 else
2069 dac = spec->slave_dig_outs[i - 1];
2070 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
2071 continue;
2072 snd_hda_codec_write(codec, dac, 0,
2073 AC_VERB_SET_AMP_GAIN_MUTE,
2074 AMP_OUT_UNMUTE);
757899ac
TI
2075 }
2076 pin = spec->autocfg.dig_in_pin;
2077 if (pin)
2078 snd_hda_codec_write(codec, pin, 0,
2079 AC_VERB_SET_PIN_WIDGET_CONTROL,
2080 PIN_IN);
2081}
2082
2083/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2084static void alc_auto_parse_digital(struct hda_codec *codec)
2085{
2086 struct alc_spec *spec = codec->spec;
2087 int i, err;
2088 hda_nid_t dig_nid;
2089
2090 /* support multiple SPDIFs; the secondary is set up as a slave */
2091 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2092 err = snd_hda_get_connections(codec,
2093 spec->autocfg.dig_out_pins[i],
2094 &dig_nid, 1);
2095 if (err < 0)
2096 continue;
2097 if (!i) {
2098 spec->multiout.dig_out_nid = dig_nid;
2099 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2100 } else {
2101 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2102 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2103 break;
2104 spec->slave_dig_outs[i - 1] = dig_nid;
2105 }
2106 }
2107
2108 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
2109 dig_nid = codec->start_nid;
2110 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2111 unsigned int wcaps = get_wcaps(codec, dig_nid);
2112 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2113 continue;
2114 if (!(wcaps & AC_WCAP_DIGITAL))
2115 continue;
2116 if (!(wcaps & AC_WCAP_CONN_LIST))
2117 continue;
2118 err = get_connection_index(codec, dig_nid,
2119 spec->autocfg.dig_in_pin);
2120 if (err >= 0) {
2121 spec->dig_in_nid = dig_nid;
2122 break;
2123 }
2124 }
757899ac
TI
2125 }
2126}
2127
ef8ef5fb
VP
2128/*
2129 * ALC888
2130 */
2131
2132/*
2133 * 2ch mode
2134 */
a9111321 2135static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
ef8ef5fb
VP
2136/* Mic-in jack as mic in */
2137 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2138 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2139/* Line-in jack as Line in */
2140 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2141 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2142/* Line-Out as Front */
2143 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2144 { } /* end */
2145};
2146
2147/*
2148 * 4ch mode
2149 */
a9111321 2150static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
ef8ef5fb
VP
2151/* Mic-in jack as mic in */
2152 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2153 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2154/* Line-in jack as Surround */
2155 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2156 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2157/* Line-Out as Front */
2158 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2159 { } /* end */
2160};
2161
2162/*
2163 * 6ch mode
2164 */
a9111321 2165static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
ef8ef5fb
VP
2166/* Mic-in jack as CLFE */
2167 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2168 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2169/* Line-in jack as Surround */
2170 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2171 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2172/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2173 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2174 { } /* end */
2175};
2176
2177/*
2178 * 8ch mode
2179 */
a9111321 2180static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
ef8ef5fb
VP
2181/* Mic-in jack as CLFE */
2182 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2183 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2184/* Line-in jack as Surround */
2185 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2186 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2187/* Line-Out as Side */
2188 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2189 { } /* end */
2190};
2191
a9111321 2192static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
ef8ef5fb
VP
2193 { 2, alc888_4ST_ch2_intel_init },
2194 { 4, alc888_4ST_ch4_intel_init },
2195 { 6, alc888_4ST_ch6_intel_init },
2196 { 8, alc888_4ST_ch8_intel_init },
2197};
2198
2199/*
2200 * ALC888 Fujitsu Siemens Amillo xa3530
2201 */
2202
a9111321 2203static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
ef8ef5fb
VP
2204/* Front Mic: set to PIN_IN (empty by default) */
2205 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2206/* Connect Internal HP to Front */
2207 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2209 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2210/* Connect Bass HP to Front */
2211 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2212 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2213 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2214/* Connect Line-Out side jack (SPDIF) to Side */
2215 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2216 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2217 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2218/* Connect Mic jack to CLFE */
2219 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2221 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2222/* Connect Line-in jack to Surround */
2223 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2224 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2226/* Connect HP out jack to Front */
2227 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2228 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2230/* Enable unsolicited event for HP jack and Line-out jack */
2231 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2232 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2233 {}
2234};
2235
4f5d1706 2236static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
2237{
2238 struct alc_spec *spec = codec->spec;
2239
2240 spec->autocfg.hp_pins[0] = 0x15;
2241 spec->autocfg.speaker_pins[0] = 0x14;
2242 spec->autocfg.speaker_pins[1] = 0x16;
2243 spec->autocfg.speaker_pins[2] = 0x17;
2244 spec->autocfg.speaker_pins[3] = 0x19;
2245 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
2246 spec->automute = 1;
2247 spec->automute_mode = ALC_AUTOMUTE_AMP;
6732bd0d
WF
2248}
2249
2250static void alc889_intel_init_hook(struct hda_codec *codec)
2251{
2252 alc889_coef_init(codec);
d922b51d 2253 alc_hp_automute(codec);
6732bd0d
WF
2254}
2255
4f5d1706 2256static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2257{
2258 struct alc_spec *spec = codec->spec;
2259
2260 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2261 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2262 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2263 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
d922b51d
TI
2264 spec->automute = 1;
2265 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f 2266}
ef8ef5fb 2267
5b2d1eca
VP
2268/*
2269 * ALC888 Acer Aspire 4930G model
2270 */
2271
a9111321 2272static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
5b2d1eca
VP
2273/* Front Mic: set to PIN_IN (empty by default) */
2274 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2275/* Unselect Front Mic by default in input mixer 3 */
2276 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2277/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2278 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2279/* Connect Internal HP to front */
2280 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2281 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2282 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2283/* Connect HP out to front */
2284 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2285 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2286 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2287 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2288 { }
2289};
2290
d2fd4b09
TV
2291/*
2292 * ALC888 Acer Aspire 6530G model
2293 */
2294
a9111321 2295static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2296/* Route to built-in subwoofer as well as speakers */
2297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2299 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2300 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2301/* Bias voltage on for external mic port */
2302 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2303/* Front Mic: set to PIN_IN (empty by default) */
2304 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2305/* Unselect Front Mic by default in input mixer 3 */
2306 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2307/* Enable unsolicited event for HP jack */
2308 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2309/* Enable speaker output */
2310 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2311 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2312 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2313/* Enable headphone output */
2314 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2315 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2316 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2317 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2318 { }
2319};
2320
d9477207
DK
2321/*
2322 *ALC888 Acer Aspire 7730G model
2323 */
2324
a9111321 2325static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
d9477207
DK
2326/* Bias voltage on for external mic port */
2327 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2328/* Front Mic: set to PIN_IN (empty by default) */
2329 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2330/* Unselect Front Mic by default in input mixer 3 */
2331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2332/* Enable unsolicited event for HP jack */
2333 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2334/* Enable speaker output */
2335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2337 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2338/* Enable headphone output */
2339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2340 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2341 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2342 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2343/*Enable internal subwoofer */
2344 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2345 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2346 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2347 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2348 { }
2349};
2350
3b315d70 2351/*
018df418 2352 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2353 */
2354
a9111321 2355static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2356/* Front Mic: set to PIN_IN (empty by default) */
2357 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2358/* Unselect Front Mic by default in input mixer 3 */
2359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2360/* Enable unsolicited event for HP jack */
2361 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2362/* Connect Internal Front to Front */
2363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2365 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2366/* Connect Internal Rear to Rear */
2367 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2368 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2369 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2370/* Connect Internal CLFE to CLFE */
2371 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2372 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2373 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2374/* Connect HP out to Front */
018df418 2375 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2376 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2377 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2378/* Enable all DACs */
2379/* DAC DISABLE/MUTE 1? */
2380/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2381 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2382 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2383/* DAC DISABLE/MUTE 2? */
2384/* some bit here disables the other DACs. Init=0x4900 */
2385 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2386 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2387/* DMIC fix
2388 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2389 * which makes the stereo useless. However, either the mic or the ALC889
2390 * makes the signal become a difference/sum signal instead of standard
2391 * stereo, which is annoying. So instead we flip this bit which makes the
2392 * codec replicate the sum signal to both channels, turning it into a
2393 * normal mono mic.
2394 */
2395/* DMIC_CONTROL? Init value = 0x0001 */
2396 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2397 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2398 { }
2399};
2400
a9111321 2401static const struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2402 /* Front mic only available on one ADC */
2403 {
2404 .num_items = 4,
2405 .items = {
2406 { "Mic", 0x0 },
2407 { "Line", 0x2 },
2408 { "CD", 0x4 },
2409 { "Front Mic", 0xb },
2410 },
2411 },
2412 {
2413 .num_items = 3,
2414 .items = {
2415 { "Mic", 0x0 },
2416 { "Line", 0x2 },
2417 { "CD", 0x4 },
2418 },
2419 }
2420};
2421
a9111321 2422static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
d2fd4b09
TV
2423 /* Interal mic only available on one ADC */
2424 {
684a8842 2425 .num_items = 5,
d2fd4b09 2426 .items = {
8607f7c4 2427 { "Mic", 0x0 },
684a8842 2428 { "Line In", 0x2 },
d2fd4b09 2429 { "CD", 0x4 },
684a8842 2430 { "Input Mix", 0xa },
28c4edb7 2431 { "Internal Mic", 0xb },
d2fd4b09
TV
2432 },
2433 },
2434 {
684a8842 2435 .num_items = 4,
d2fd4b09 2436 .items = {
8607f7c4 2437 { "Mic", 0x0 },
684a8842 2438 { "Line In", 0x2 },
d2fd4b09 2439 { "CD", 0x4 },
684a8842 2440 { "Input Mix", 0xa },
d2fd4b09
TV
2441 },
2442 }
2443};
2444
a9111321 2445static const struct hda_input_mux alc889_capture_sources[3] = {
018df418
HM
2446 /* Digital mic only available on first "ADC" */
2447 {
2448 .num_items = 5,
2449 .items = {
2450 { "Mic", 0x0 },
2451 { "Line", 0x2 },
2452 { "CD", 0x4 },
2453 { "Front Mic", 0xb },
2454 { "Input Mix", 0xa },
2455 },
2456 },
2457 {
2458 .num_items = 4,
2459 .items = {
2460 { "Mic", 0x0 },
2461 { "Line", 0x2 },
2462 { "CD", 0x4 },
2463 { "Input Mix", 0xa },
2464 },
2465 },
2466 {
2467 .num_items = 4,
2468 .items = {
2469 { "Mic", 0x0 },
2470 { "Line", 0x2 },
2471 { "CD", 0x4 },
2472 { "Input Mix", 0xa },
2473 },
2474 }
2475};
2476
a9111321 2477static const struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2478 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2479 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2481 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2482 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2483 HDA_OUTPUT),
2484 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2485 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2486 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2487 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2488 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2489 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2490 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2491 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2492 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2494 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2495 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2496 { } /* end */
2497};
2498
a9111321 2499static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
460c92fa
ŁW
2500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2502 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2503 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2504 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2505 HDA_OUTPUT),
786c51f9
ŁW
2506 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2507 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2508 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2509 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2510 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2511 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2512 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2513 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2514 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2515 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2517 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2518 { } /* end */
2519};
2520
a9111321 2521static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
556eea9a
HM
2522 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2523 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2524 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2525 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2526 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2527 HDA_OUTPUT),
2528 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2529 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2530 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2531 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2532 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2534 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2535 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2536 { } /* end */
2537};
2538
2539
4f5d1706 2540static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2541{
a9fd4f3f 2542 struct alc_spec *spec = codec->spec;
5b2d1eca 2543
a9fd4f3f
TI
2544 spec->autocfg.hp_pins[0] = 0x15;
2545 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2546 spec->autocfg.speaker_pins[1] = 0x16;
2547 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2548 spec->automute = 1;
2549 spec->automute_mode = ALC_AUTOMUTE_AMP;
5b2d1eca
VP
2550}
2551
4f5d1706 2552static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2553{
2554 struct alc_spec *spec = codec->spec;
2555
2556 spec->autocfg.hp_pins[0] = 0x15;
2557 spec->autocfg.speaker_pins[0] = 0x14;
2558 spec->autocfg.speaker_pins[1] = 0x16;
2559 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2560 spec->automute = 1;
2561 spec->automute_mode = ALC_AUTOMUTE_AMP;
320d5920
EL
2562}
2563
d9477207
DK
2564static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2565{
2566 struct alc_spec *spec = codec->spec;
2567
2568 spec->autocfg.hp_pins[0] = 0x15;
2569 spec->autocfg.speaker_pins[0] = 0x14;
2570 spec->autocfg.speaker_pins[1] = 0x16;
2571 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2572 spec->automute = 1;
2573 spec->automute_mode = ALC_AUTOMUTE_AMP;
d9477207
DK
2574}
2575
4f5d1706 2576static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2577{
2578 struct alc_spec *spec = codec->spec;
2579
2580 spec->autocfg.hp_pins[0] = 0x15;
2581 spec->autocfg.speaker_pins[0] = 0x14;
2582 spec->autocfg.speaker_pins[1] = 0x16;
2583 spec->autocfg.speaker_pins[2] = 0x1b;
d922b51d
TI
2584 spec->automute = 1;
2585 spec->automute_mode = ALC_AUTOMUTE_AMP;
3b315d70
HM
2586}
2587
1da177e4 2588/*
e9edcee0
TI
2589 * ALC880 3-stack model
2590 *
2591 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2592 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2593 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2594 */
2595
4c6d72d1 2596static const hda_nid_t alc880_dac_nids[4] = {
e9edcee0
TI
2597 /* front, rear, clfe, rear_surr */
2598 0x02, 0x05, 0x04, 0x03
2599};
2600
4c6d72d1 2601static const hda_nid_t alc880_adc_nids[3] = {
e9edcee0
TI
2602 /* ADC0-2 */
2603 0x07, 0x08, 0x09,
2604};
2605
2606/* The datasheet says the node 0x07 is connected from inputs,
2607 * but it shows zero connection in the real implementation on some devices.
df694daa 2608 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2609 */
4c6d72d1 2610static const hda_nid_t alc880_adc_nids_alt[2] = {
e9edcee0
TI
2611 /* ADC1-2 */
2612 0x08, 0x09,
2613};
2614
2615#define ALC880_DIGOUT_NID 0x06
2616#define ALC880_DIGIN_NID 0x0a
2617
a9111321 2618static const struct hda_input_mux alc880_capture_source = {
e9edcee0
TI
2619 .num_items = 4,
2620 .items = {
2621 { "Mic", 0x0 },
2622 { "Front Mic", 0x3 },
2623 { "Line", 0x2 },
2624 { "CD", 0x4 },
2625 },
2626};
2627
2628/* channel source setting (2/6 channel selection for 3-stack) */
2629/* 2ch mode */
a9111321 2630static const struct hda_verb alc880_threestack_ch2_init[] = {
e9edcee0
TI
2631 /* set line-in to input, mute it */
2632 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2633 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2634 /* set mic-in to input vref 80%, mute it */
2635 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2636 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2637 { } /* end */
2638};
2639
2640/* 6ch mode */
a9111321 2641static const struct hda_verb alc880_threestack_ch6_init[] = {
e9edcee0
TI
2642 /* set line-in to output, unmute it */
2643 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2644 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2645 /* set mic-in to output, unmute it */
2646 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2647 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2648 { } /* end */
2649};
2650
a9111321 2651static const struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2652 { 2, alc880_threestack_ch2_init },
2653 { 6, alc880_threestack_ch6_init },
2654};
2655
a9111321 2656static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2657 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2658 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2659 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2660 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2661 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2662 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2663 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2664 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2665 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2666 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2667 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2668 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2669 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2670 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2671 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2672 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2673 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2674 {
2675 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2676 .name = "Channel Mode",
df694daa
KY
2677 .info = alc_ch_mode_info,
2678 .get = alc_ch_mode_get,
2679 .put = alc_ch_mode_put,
e9edcee0
TI
2680 },
2681 { } /* end */
2682};
2683
2684/* capture mixer elements */
f9e336f6
TI
2685static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2686 struct snd_ctl_elem_info *uinfo)
2687{
2688 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2689 struct alc_spec *spec = codec->spec;
2690 int err;
1da177e4 2691
5a9e02e9 2692 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2693 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2694 HDA_INPUT);
2695 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2696 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2697 return err;
2698}
2699
2700static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2701 unsigned int size, unsigned int __user *tlv)
2702{
2703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2704 struct alc_spec *spec = codec->spec;
2705 int err;
1da177e4 2706
5a9e02e9 2707 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2708 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2709 HDA_INPUT);
2710 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2711 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2712 return err;
2713}
2714
2715typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2716 struct snd_ctl_elem_value *ucontrol);
2717
2718static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2719 struct snd_ctl_elem_value *ucontrol,
2720 getput_call_t func)
2721{
2722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2723 struct alc_spec *spec = codec->spec;
2724 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2725 int err;
2726
5a9e02e9 2727 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2728 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2729 3, 0, HDA_INPUT);
2730 err = func(kcontrol, ucontrol);
5a9e02e9 2731 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2732 return err;
2733}
2734
2735static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2736 struct snd_ctl_elem_value *ucontrol)
2737{
2738 return alc_cap_getput_caller(kcontrol, ucontrol,
2739 snd_hda_mixer_amp_volume_get);
2740}
2741
2742static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2743 struct snd_ctl_elem_value *ucontrol)
2744{
2745 return alc_cap_getput_caller(kcontrol, ucontrol,
2746 snd_hda_mixer_amp_volume_put);
2747}
2748
2749/* capture mixer elements */
2750#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2751
2752static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2753 struct snd_ctl_elem_value *ucontrol)
2754{
2755 return alc_cap_getput_caller(kcontrol, ucontrol,
2756 snd_hda_mixer_amp_switch_get);
2757}
2758
2759static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2760 struct snd_ctl_elem_value *ucontrol)
2761{
2762 return alc_cap_getput_caller(kcontrol, ucontrol,
2763 snd_hda_mixer_amp_switch_put);
2764}
2765
a23b688f 2766#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2767 { \
2768 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2769 .name = "Capture Switch", \
2770 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2771 .count = num, \
2772 .info = alc_cap_sw_info, \
2773 .get = alc_cap_sw_get, \
2774 .put = alc_cap_sw_put, \
2775 }, \
2776 { \
2777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2778 .name = "Capture Volume", \
2779 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2780 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2781 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2782 .count = num, \
2783 .info = alc_cap_vol_info, \
2784 .get = alc_cap_vol_get, \
2785 .put = alc_cap_vol_put, \
2786 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2787 }
2788
2789#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2790 { \
2791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2792 /* .name = "Capture Source", */ \
2793 .name = "Input Source", \
2794 .count = num, \
2795 .info = alc_mux_enum_info, \
2796 .get = alc_mux_enum_get, \
2797 .put = alc_mux_enum_put, \
a23b688f
TI
2798 }
2799
2800#define DEFINE_CAPMIX(num) \
a9111321 2801static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
a23b688f
TI
2802 _DEFINE_CAPMIX(num), \
2803 _DEFINE_CAPSRC(num), \
2804 { } /* end */ \
2805}
2806
2807#define DEFINE_CAPMIX_NOSRC(num) \
a9111321 2808static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
a23b688f
TI
2809 _DEFINE_CAPMIX(num), \
2810 { } /* end */ \
f9e336f6
TI
2811}
2812
2813/* up to three ADCs */
2814DEFINE_CAPMIX(1);
2815DEFINE_CAPMIX(2);
2816DEFINE_CAPMIX(3);
a23b688f
TI
2817DEFINE_CAPMIX_NOSRC(1);
2818DEFINE_CAPMIX_NOSRC(2);
2819DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2820
2821/*
2822 * ALC880 5-stack model
2823 *
9c7f852e
TI
2824 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2825 * Side = 0x02 (0xd)
e9edcee0
TI
2826 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2827 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2828 */
2829
2830/* additional mixers to alc880_three_stack_mixer */
a9111321 2831static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2832 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2833 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2834 { } /* end */
2835};
2836
e9edcee0
TI
2837/* channel source setting (6/8 channel selection for 5-stack) */
2838/* 6ch mode */
a9111321 2839static const struct hda_verb alc880_fivestack_ch6_init[] = {
e9edcee0
TI
2840 /* set line-in to input, mute it */
2841 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2842 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2843 { } /* end */
2844};
2845
e9edcee0 2846/* 8ch mode */
a9111321 2847static const struct hda_verb alc880_fivestack_ch8_init[] = {
e9edcee0
TI
2848 /* set line-in to output, unmute it */
2849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2850 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2851 { } /* end */
2852};
2853
a9111321 2854static const struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2855 { 6, alc880_fivestack_ch6_init },
2856 { 8, alc880_fivestack_ch8_init },
2857};
2858
2859
2860/*
2861 * ALC880 6-stack model
2862 *
9c7f852e
TI
2863 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2864 * Side = 0x05 (0x0f)
e9edcee0
TI
2865 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2866 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2867 */
2868
4c6d72d1 2869static const hda_nid_t alc880_6st_dac_nids[4] = {
e9edcee0
TI
2870 /* front, rear, clfe, rear_surr */
2871 0x02, 0x03, 0x04, 0x05
f12ab1e0 2872};
e9edcee0 2873
a9111321 2874static const struct hda_input_mux alc880_6stack_capture_source = {
e9edcee0
TI
2875 .num_items = 4,
2876 .items = {
2877 { "Mic", 0x0 },
2878 { "Front Mic", 0x1 },
2879 { "Line", 0x2 },
2880 { "CD", 0x4 },
2881 },
2882};
2883
2884/* fixed 8-channels */
a9111321 2885static const struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2886 { 8, NULL },
2887};
2888
a9111321 2889static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2890 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2891 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2892 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2893 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2894 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2895 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2896 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2897 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2898 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2899 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2900 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2901 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2902 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2903 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2906 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2907 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2908 {
2909 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2910 .name = "Channel Mode",
df694daa
KY
2911 .info = alc_ch_mode_info,
2912 .get = alc_ch_mode_get,
2913 .put = alc_ch_mode_put,
16ded525
TI
2914 },
2915 { } /* end */
2916};
2917
e9edcee0
TI
2918
2919/*
2920 * ALC880 W810 model
2921 *
2922 * W810 has rear IO for:
2923 * Front (DAC 02)
2924 * Surround (DAC 03)
2925 * Center/LFE (DAC 04)
2926 * Digital out (06)
2927 *
2928 * The system also has a pair of internal speakers, and a headphone jack.
2929 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2930 *
e9edcee0
TI
2931 * There is a variable resistor to control the speaker or headphone
2932 * volume. This is a hardware-only device without a software API.
2933 *
2934 * Plugging headphones in will disable the internal speakers. This is
2935 * implemented in hardware, not via the driver using jack sense. In
2936 * a similar fashion, plugging into the rear socket marked "front" will
2937 * disable both the speakers and headphones.
2938 *
2939 * For input, there's a microphone jack, and an "audio in" jack.
2940 * These may not do anything useful with this driver yet, because I
2941 * haven't setup any initialization verbs for these yet...
2942 */
2943
4c6d72d1 2944static const hda_nid_t alc880_w810_dac_nids[3] = {
e9edcee0
TI
2945 /* front, rear/surround, clfe */
2946 0x02, 0x03, 0x04
16ded525
TI
2947};
2948
e9edcee0 2949/* fixed 6 channels */
a9111321 2950static const struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2951 { 6, NULL }
2952};
2953
2954/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
a9111321 2955static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2956 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2957 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2958 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2959 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2960 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2961 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2962 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2963 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2964 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2965 { } /* end */
2966};
2967
2968
2969/*
2970 * Z710V model
2971 *
2972 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2973 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2974 * Line = 0x1a
e9edcee0
TI
2975 */
2976
4c6d72d1 2977static const hda_nid_t alc880_z71v_dac_nids[1] = {
e9edcee0
TI
2978 0x02
2979};
2980#define ALC880_Z71V_HP_DAC 0x03
2981
2982/* fixed 2 channels */
a9111321 2983static const struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2984 { 2, NULL }
2985};
2986
a9111321 2987static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2988 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2989 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2990 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2991 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2992 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2993 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2996 { } /* end */
2997};
2998
e9edcee0 2999
e9edcee0
TI
3000/*
3001 * ALC880 F1734 model
3002 *
3003 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3004 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3005 */
3006
4c6d72d1 3007static const hda_nid_t alc880_f1734_dac_nids[1] = {
e9edcee0
TI
3008 0x03
3009};
3010#define ALC880_F1734_HP_DAC 0x02
3011
a9111321 3012static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 3013 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3014 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
3015 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3016 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
3017 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3018 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
3019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
3021 { } /* end */
3022};
3023
a9111321 3024static const struct hda_input_mux alc880_f1734_capture_source = {
937b4160
TI
3025 .num_items = 2,
3026 .items = {
3027 { "Mic", 0x1 },
3028 { "CD", 0x4 },
3029 },
3030};
3031
e9edcee0 3032
e9edcee0
TI
3033/*
3034 * ALC880 ASUS model
3035 *
3036 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3037 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3038 * Mic = 0x18, Line = 0x1a
3039 */
3040
3041#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3042#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3043
a9111321 3044static const struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 3045 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3046 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 3047 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3048 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3049 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3050 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3051 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3052 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
3053 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3054 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3055 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3056 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
3057 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3058 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3059 {
3060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3061 .name = "Channel Mode",
df694daa
KY
3062 .info = alc_ch_mode_info,
3063 .get = alc_ch_mode_get,
3064 .put = alc_ch_mode_put,
16ded525
TI
3065 },
3066 { } /* end */
3067};
e9edcee0 3068
e9edcee0
TI
3069/*
3070 * ALC880 ASUS W1V model
3071 *
3072 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3073 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3074 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3075 */
3076
3077/* additional mixers to alc880_asus_mixer */
a9111321 3078static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
3079 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3080 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3081 { } /* end */
3082};
3083
df694daa 3084/* TCL S700 */
a9111321 3085static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
df694daa
KY
3086 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3087 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3088 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3089 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3090 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3093 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3094 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
3095 { } /* end */
3096};
3097
ccc656ce 3098/* Uniwill */
a9111321 3099static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
3100 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3101 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3102 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3103 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3104 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3105 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3106 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3107 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3108 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3109 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3111 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3114 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3115 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
3116 {
3117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3118 .name = "Channel Mode",
3119 .info = alc_ch_mode_info,
3120 .get = alc_ch_mode_get,
3121 .put = alc_ch_mode_put,
3122 },
3123 { } /* end */
3124};
3125
a9111321 3126static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2cf9f0fc
TD
3127 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3128 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3129 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3130 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3131 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3132 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
3133 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3134 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
3135 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3136 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
3137 { } /* end */
3138};
3139
a9111321 3140static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
3141 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3142 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3143 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3144 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3146 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3147 { } /* end */
3148};
3149
2134ea4f
TI
3150/*
3151 * virtual master controls
3152 */
3153
3154/*
3155 * slave controls for virtual master
3156 */
ea734963 3157static const char * const alc_slave_vols[] = {
2134ea4f
TI
3158 "Front Playback Volume",
3159 "Surround Playback Volume",
3160 "Center Playback Volume",
3161 "LFE Playback Volume",
3162 "Side Playback Volume",
3163 "Headphone Playback Volume",
3164 "Speaker Playback Volume",
3165 "Mono Playback Volume",
2134ea4f
TI
3166 "Line-Out Playback Volume",
3167 NULL,
3168};
3169
ea734963 3170static const char * const alc_slave_sws[] = {
2134ea4f
TI
3171 "Front Playback Switch",
3172 "Surround Playback Switch",
3173 "Center Playback Switch",
3174 "LFE Playback Switch",
3175 "Side Playback Switch",
3176 "Headphone Playback Switch",
3177 "Speaker Playback Switch",
3178 "Mono Playback Switch",
edb54a55 3179 "IEC958 Playback Switch",
23033b2b 3180 "Line-Out Playback Switch",
2134ea4f
TI
3181 NULL,
3182};
3183
1da177e4 3184/*
e9edcee0 3185 * build control elements
1da177e4 3186 */
603c4019 3187
5b0cb1d8
JK
3188#define NID_MAPPING (-1)
3189
3190#define SUBDEV_SPEAKER_ (0 << 6)
3191#define SUBDEV_HP_ (1 << 6)
3192#define SUBDEV_LINE_ (2 << 6)
3193#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3194#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3195#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3196
603c4019
TI
3197static void alc_free_kctls(struct hda_codec *codec);
3198
67d634c0 3199#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1 3200/* additional beep mixers; the actual parameters are overwritten at build */
a9111321 3201static const struct snd_kcontrol_new alc_beep_mixer[] = {
45bdd1c1 3202 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 3203 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
3204 { } /* end */
3205};
67d634c0 3206#endif
45bdd1c1 3207
1da177e4
LT
3208static int alc_build_controls(struct hda_codec *codec)
3209{
3210 struct alc_spec *spec = codec->spec;
2f44f847 3211 struct snd_kcontrol *kctl = NULL;
a9111321 3212 const struct snd_kcontrol_new *knew;
5b0cb1d8
JK
3213 int i, j, err;
3214 unsigned int u;
3215 hda_nid_t nid;
1da177e4
LT
3216
3217 for (i = 0; i < spec->num_mixers; i++) {
3218 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3219 if (err < 0)
3220 return err;
3221 }
f9e336f6
TI
3222 if (spec->cap_mixer) {
3223 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3224 if (err < 0)
3225 return err;
3226 }
1da177e4 3227 if (spec->multiout.dig_out_nid) {
9c7f852e 3228 err = snd_hda_create_spdif_out_ctls(codec,
74b654c9 3229 spec->multiout.dig_out_nid,
9c7f852e 3230 spec->multiout.dig_out_nid);
1da177e4
LT
3231 if (err < 0)
3232 return err;
e64f14f4
TI
3233 if (!spec->no_analog) {
3234 err = snd_hda_create_spdif_share_sw(codec,
3235 &spec->multiout);
3236 if (err < 0)
3237 return err;
3238 spec->multiout.share_spdif = 1;
3239 }
1da177e4
LT
3240 }
3241 if (spec->dig_in_nid) {
3242 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3243 if (err < 0)
3244 return err;
3245 }
2134ea4f 3246
67d634c0 3247#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3248 /* create beep controls if needed */
3249 if (spec->beep_amp) {
a9111321 3250 const struct snd_kcontrol_new *knew;
45bdd1c1
TI
3251 for (knew = alc_beep_mixer; knew->name; knew++) {
3252 struct snd_kcontrol *kctl;
3253 kctl = snd_ctl_new1(knew, codec);
3254 if (!kctl)
3255 return -ENOMEM;
3256 kctl->private_value = spec->beep_amp;
5e26dfd0 3257 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3258 if (err < 0)
3259 return err;
3260 }
3261 }
67d634c0 3262#endif
45bdd1c1 3263
2134ea4f 3264 /* if we have no master control, let's create it */
e64f14f4
TI
3265 if (!spec->no_analog &&
3266 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3267 unsigned int vmaster_tlv[4];
2134ea4f 3268 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3269 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3270 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3271 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3272 if (err < 0)
3273 return err;
3274 }
e64f14f4
TI
3275 if (!spec->no_analog &&
3276 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3277 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3278 NULL, alc_slave_sws);
3279 if (err < 0)
3280 return err;
3281 }
3282
5b0cb1d8 3283 /* assign Capture Source enums to NID */
fbe618f2
TI
3284 if (spec->capsrc_nids || spec->adc_nids) {
3285 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3286 if (!kctl)
3287 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3288 for (i = 0; kctl && i < kctl->count; i++) {
4c6d72d1 3289 const hda_nid_t *nids = spec->capsrc_nids;
fbe618f2
TI
3290 if (!nids)
3291 nids = spec->adc_nids;
3292 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3293 if (err < 0)
3294 return err;
3295 }
5b0cb1d8
JK
3296 }
3297 if (spec->cap_mixer) {
3298 const char *kname = kctl ? kctl->id.name : NULL;
3299 for (knew = spec->cap_mixer; knew->name; knew++) {
3300 if (kname && strcmp(knew->name, kname) == 0)
3301 continue;
3302 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3303 for (i = 0; kctl && i < kctl->count; i++) {
3304 err = snd_hda_add_nid(codec, kctl, i,
3305 spec->adc_nids[i]);
3306 if (err < 0)
3307 return err;
3308 }
3309 }
3310 }
3311
3312 /* other nid->control mapping */
3313 for (i = 0; i < spec->num_mixers; i++) {
3314 for (knew = spec->mixers[i]; knew->name; knew++) {
3315 if (knew->iface != NID_MAPPING)
3316 continue;
3317 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3318 if (kctl == NULL)
3319 continue;
3320 u = knew->subdevice;
3321 for (j = 0; j < 4; j++, u >>= 8) {
3322 nid = u & 0x3f;
3323 if (nid == 0)
3324 continue;
3325 switch (u & 0xc0) {
3326 case SUBDEV_SPEAKER_:
3327 nid = spec->autocfg.speaker_pins[nid];
3328 break;
3329 case SUBDEV_LINE_:
3330 nid = spec->autocfg.line_out_pins[nid];
3331 break;
3332 case SUBDEV_HP_:
3333 nid = spec->autocfg.hp_pins[nid];
3334 break;
3335 default:
3336 continue;
3337 }
3338 err = snd_hda_add_nid(codec, kctl, 0, nid);
3339 if (err < 0)
3340 return err;
3341 }
3342 u = knew->private_value;
3343 for (j = 0; j < 4; j++, u >>= 8) {
3344 nid = u & 0xff;
3345 if (nid == 0)
3346 continue;
3347 err = snd_hda_add_nid(codec, kctl, 0, nid);
3348 if (err < 0)
3349 return err;
3350 }
3351 }
3352 }
bae84e70
TI
3353
3354 alc_free_kctls(codec); /* no longer needed */
3355
1da177e4
LT
3356 return 0;
3357}
3358
e9edcee0 3359
1da177e4
LT
3360/*
3361 * initialize the codec volumes, etc
3362 */
3363
e9edcee0
TI
3364/*
3365 * generic initialization of ADC, input mixers and output mixers
3366 */
a9111321 3367static const struct hda_verb alc880_volume_init_verbs[] = {
e9edcee0
TI
3368 /*
3369 * Unmute ADC0-2 and set the default input to mic-in
3370 */
71fe7b82 3371 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3372 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3373 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3375 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3377
e9edcee0
TI
3378 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3379 * mixer widget
9c7f852e
TI
3380 * Note: PASD motherboards uses the Line In 2 as the input for front
3381 * panel mic (mic 2)
1da177e4 3382 */
e9edcee0 3383 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3388 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3389 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3390 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3391
e9edcee0
TI
3392 /*
3393 * Set up output mixers (0x0c - 0x0f)
1da177e4 3394 */
e9edcee0
TI
3395 /* set vol=0 to output mixers */
3396 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3397 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3398 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3399 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3400 /* set up input amps for analog loopback */
3401 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3404 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3405 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3406 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3407 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3408 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3409 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3410
3411 { }
3412};
3413
e9edcee0
TI
3414/*
3415 * 3-stack pin configuration:
3416 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3417 */
a9111321 3418static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
e9edcee0
TI
3419 /*
3420 * preset connection lists of input pins
3421 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3422 */
3423 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3424 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3425 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3426
3427 /*
3428 * Set pin mode and muting
3429 */
3430 /* set front pin widgets 0x14 for output */
05acb863 3431 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3432 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3433 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3434 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3435 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3436 /* Mic2 (as headphone out) for HP output */
3437 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3438 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3439 /* Line In pin widget for input */
05acb863 3440 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3441 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3442 /* Line2 (as front mic) pin widget for input and vref at 80% */
3443 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3444 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3445 /* CD pin widget for input */
05acb863 3446 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3447
e9edcee0
TI
3448 { }
3449};
1da177e4 3450
e9edcee0
TI
3451/*
3452 * 5-stack pin configuration:
3453 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3454 * line-in/side = 0x1a, f-mic = 0x1b
3455 */
a9111321 3456static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
e9edcee0
TI
3457 /*
3458 * preset connection lists of input pins
3459 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3460 */
e9edcee0
TI
3461 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3462 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3463
e9edcee0
TI
3464 /*
3465 * Set pin mode and muting
1da177e4 3466 */
e9edcee0
TI
3467 /* set pin widgets 0x14-0x17 for output */
3468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3470 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3471 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3472 /* unmute pins for output (no gain on this amp) */
3473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3474 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3475 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3476 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3477
3478 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3479 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3480 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3481 /* Mic2 (as headphone out) for HP output */
3482 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3483 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3484 /* Line In pin widget for input */
3485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3486 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3487 /* Line2 (as front mic) pin widget for input and vref at 80% */
3488 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3489 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3490 /* CD pin widget for input */
3491 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3492
3493 { }
3494};
3495
e9edcee0
TI
3496/*
3497 * W810 pin configuration:
3498 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3499 */
a9111321 3500static const struct hda_verb alc880_pin_w810_init_verbs[] = {
e9edcee0
TI
3501 /* hphone/speaker input selector: front DAC */
3502 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3503
05acb863 3504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3506 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3507 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3508 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3509 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3510
e9edcee0 3511 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3512 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3513
1da177e4
LT
3514 { }
3515};
3516
e9edcee0
TI
3517/*
3518 * Z71V pin configuration:
3519 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3520 */
a9111321 3521static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3522 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3523 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3525 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3526
16ded525 3527 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3530 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3531
3532 { }
3533};
3534
e9edcee0
TI
3535/*
3536 * 6-stack pin configuration:
9c7f852e
TI
3537 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3538 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0 3539 */
a9111321 3540static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
e9edcee0
TI
3541 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3542
16ded525 3543 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3544 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3545 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3547 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3548 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3549 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3550 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3551
16ded525 3552 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3554 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3556 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3557 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3558 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3559 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3560 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3561
e9edcee0
TI
3562 { }
3563};
3564
ccc656ce
KY
3565/*
3566 * Uniwill pin configuration:
3567 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3568 * line = 0x1a
3569 */
a9111321 3570static const struct hda_verb alc880_uniwill_init_verbs[] = {
ccc656ce
KY
3571 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3572
3573 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3574 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3575 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3577 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3578 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3579 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3580 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3583 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3585 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3586 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3587
3588 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3589 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3590 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3591 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3592 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3593 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3594 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3595 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3596 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3597
3598 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3599 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3600
3601 { }
3602};
3603
3604/*
3605* Uniwill P53
ea1fb29a 3606* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce 3607 */
a9111321 3608static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
ccc656ce
KY
3609 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3610
3611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3612 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3613 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3614 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3615 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3616 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3617 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3619 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3620 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3621 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3622 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3623
3624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3626 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3627 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3628 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3630
3631 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3632 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3633
3634 { }
3635};
3636
a9111321 3637static const struct hda_verb alc880_beep_init_verbs[] = {
2cf9f0fc
TD
3638 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3639 { }
3640};
3641
458a4fab 3642/* auto-toggle front mic */
eeb43387 3643static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3644{
3645 unsigned int present;
3646 unsigned char bits;
ccc656ce 3647
864f92be 3648 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3649 bits = present ? HDA_AMP_MUTE : 0;
3650 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3651}
3652
4f5d1706 3653static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3654{
a9fd4f3f
TI
3655 struct alc_spec *spec = codec->spec;
3656
3657 spec->autocfg.hp_pins[0] = 0x14;
3658 spec->autocfg.speaker_pins[0] = 0x15;
3659 spec->autocfg.speaker_pins[0] = 0x16;
d922b51d
TI
3660 spec->automute = 1;
3661 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
3662}
3663
3664static void alc880_uniwill_init_hook(struct hda_codec *codec)
3665{
d922b51d 3666 alc_hp_automute(codec);
eeb43387 3667 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3668}
3669
3670static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3671 unsigned int res)
3672{
3673 /* Looks like the unsol event is incompatible with the standard
3674 * definition. 4bit tag is placed at 28 bit!
3675 */
458a4fab 3676 switch (res >> 28) {
458a4fab 3677 case ALC880_MIC_EVENT:
eeb43387 3678 alc88x_simple_mic_automute(codec);
458a4fab 3679 break;
a9fd4f3f 3680 default:
d922b51d 3681 alc_sku_unsol_event(codec, res);
a9fd4f3f 3682 break;
458a4fab 3683 }
ccc656ce
KY
3684}
3685
4f5d1706 3686static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3687{
a9fd4f3f 3688 struct alc_spec *spec = codec->spec;
ccc656ce 3689
a9fd4f3f
TI
3690 spec->autocfg.hp_pins[0] = 0x14;
3691 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
3692 spec->automute = 1;
3693 spec->automute_mode = ALC_AUTOMUTE_AMP;
ccc656ce
KY
3694}
3695
3696static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3697{
3698 unsigned int present;
ea1fb29a 3699
ccc656ce 3700 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3701 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3702 present &= HDA_AMP_VOLMASK;
3703 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3704 HDA_AMP_VOLMASK, present);
3705 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3706 HDA_AMP_VOLMASK, present);
ccc656ce 3707}
47fd830a 3708
ccc656ce
KY
3709static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3710 unsigned int res)
3711{
3712 /* Looks like the unsol event is incompatible with the standard
3713 * definition. 4bit tag is placed at 28 bit!
3714 */
f12ab1e0 3715 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3716 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f 3717 else
d922b51d 3718 alc_sku_unsol_event(codec, res);
ccc656ce
KY
3719}
3720
e9edcee0
TI
3721/*
3722 * F1734 pin configuration:
3723 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3724 */
a9111321 3725static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3726 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3727 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3728 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3729 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3730 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3731
e9edcee0 3732 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3733 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3734 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3736
e9edcee0
TI
3737 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3738 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3739 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3740 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3741 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3743 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3744 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3745 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3746
937b4160
TI
3747 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3748 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3749
dfc0ff62
TI
3750 { }
3751};
3752
e9edcee0
TI
3753/*
3754 * ASUS pin configuration:
3755 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3756 */
a9111321 3757static const struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3758 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3759 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3760 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3761 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3762
3763 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3764 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3768 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3769 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3771
3772 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3773 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3774 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3775 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3777 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3778 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3779 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3780 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3781
e9edcee0
TI
3782 { }
3783};
16ded525 3784
e9edcee0 3785/* Enable GPIO mask and set output */
bc9f98a9
KY
3786#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3787#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3788#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3789
3790/* Clevo m520g init */
a9111321 3791static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
df694daa
KY
3792 /* headphone output */
3793 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3794 /* line-out */
3795 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3796 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3797 /* Line-in */
3798 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3799 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3800 /* CD */
3801 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3802 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3803 /* Mic1 (rear panel) */
3804 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3805 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3806 /* Mic2 (front panel) */
3807 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3808 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3809 /* headphone */
3810 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3811 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3812 /* change to EAPD mode */
3813 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3814 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3815
3816 { }
16ded525
TI
3817};
3818
a9111321 3819static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3820 /* change to EAPD mode */
3821 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3822 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3823
df694daa
KY
3824 /* Headphone output */
3825 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3826 /* Front output*/
3827 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3828 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3829
3830 /* Line In pin widget for input */
3831 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3832 /* CD pin widget for input */
3833 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3834 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3835 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3836
3837 /* change to EAPD mode */
3838 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3839 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3840
3841 { }
3842};
16ded525 3843
e9edcee0 3844/*
ae6b813a
TI
3845 * LG m1 express dual
3846 *
3847 * Pin assignment:
3848 * Rear Line-In/Out (blue): 0x14
3849 * Build-in Mic-In: 0x15
3850 * Speaker-out: 0x17
3851 * HP-Out (green): 0x1b
3852 * Mic-In/Out (red): 0x19
3853 * SPDIF-Out: 0x1e
3854 */
3855
3856/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
4c6d72d1 3857static const hda_nid_t alc880_lg_dac_nids[3] = {
ae6b813a
TI
3858 0x05, 0x02, 0x03
3859};
3860
3861/* seems analog CD is not working */
a9111321 3862static const struct hda_input_mux alc880_lg_capture_source = {
ae6b813a
TI
3863 .num_items = 3,
3864 .items = {
3865 { "Mic", 0x1 },
3866 { "Line", 0x5 },
3867 { "Internal Mic", 0x6 },
3868 },
3869};
3870
3871/* 2,4,6 channel modes */
a9111321 3872static const struct hda_verb alc880_lg_ch2_init[] = {
ae6b813a
TI
3873 /* set line-in and mic-in to input */
3874 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3875 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3876 { }
3877};
3878
a9111321 3879static const struct hda_verb alc880_lg_ch4_init[] = {
ae6b813a
TI
3880 /* set line-in to out and mic-in to input */
3881 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3882 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3883 { }
3884};
3885
a9111321 3886static const struct hda_verb alc880_lg_ch6_init[] = {
ae6b813a
TI
3887 /* set line-in and mic-in to output */
3888 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3889 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3890 { }
3891};
3892
a9111321 3893static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
ae6b813a
TI
3894 { 2, alc880_lg_ch2_init },
3895 { 4, alc880_lg_ch4_init },
3896 { 6, alc880_lg_ch6_init },
3897};
3898
a9111321 3899static const struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3900 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3901 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3902 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3903 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3904 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3905 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3906 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3907 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3908 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3909 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3910 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3911 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3912 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3913 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3914 {
3915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3916 .name = "Channel Mode",
3917 .info = alc_ch_mode_info,
3918 .get = alc_ch_mode_get,
3919 .put = alc_ch_mode_put,
3920 },
3921 { } /* end */
3922};
3923
a9111321 3924static const struct hda_verb alc880_lg_init_verbs[] = {
ae6b813a
TI
3925 /* set capture source to mic-in */
3926 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3927 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3929 /* mute all amp mixer inputs */
3930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3933 /* line-in to input */
3934 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3935 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3936 /* built-in mic */
3937 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3938 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3939 /* speaker-out */
3940 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3941 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3942 /* mic-in to input */
3943 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3944 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3945 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3946 /* HP-out */
3947 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3948 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3949 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3950 /* jack sense */
a9fd4f3f 3951 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3952 { }
3953};
3954
3955/* toggle speaker-output according to the hp-jack state */
4f5d1706 3956static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3957{
a9fd4f3f 3958 struct alc_spec *spec = codec->spec;
ae6b813a 3959
a9fd4f3f
TI
3960 spec->autocfg.hp_pins[0] = 0x1b;
3961 spec->autocfg.speaker_pins[0] = 0x17;
d922b51d
TI
3962 spec->automute = 1;
3963 spec->automute_mode = ALC_AUTOMUTE_AMP;
ae6b813a
TI
3964}
3965
d681518a
TI
3966/*
3967 * LG LW20
3968 *
3969 * Pin assignment:
3970 * Speaker-out: 0x14
3971 * Mic-In: 0x18
e4f41da9
CM
3972 * Built-in Mic-In: 0x19
3973 * Line-In: 0x1b
3974 * HP-Out: 0x1a
d681518a
TI
3975 * SPDIF-Out: 0x1e
3976 */
3977
a9111321 3978static const struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3979 .num_items = 3,
d681518a
TI
3980 .items = {
3981 { "Mic", 0x0 },
3982 { "Internal Mic", 0x1 },
e4f41da9 3983 { "Line In", 0x2 },
d681518a
TI
3984 },
3985};
3986
0a8c5da3
CM
3987#define alc880_lg_lw_modes alc880_threestack_modes
3988
a9111321 3989static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3990 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3991 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3992 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3993 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3994 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3995 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3996 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3997 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
4000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4002 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4003 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
4004 {
4005 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4006 .name = "Channel Mode",
4007 .info = alc_ch_mode_info,
4008 .get = alc_ch_mode_get,
4009 .put = alc_ch_mode_put,
4010 },
d681518a
TI
4011 { } /* end */
4012};
4013
a9111321 4014static const struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
4015 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4016 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4017 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4018
d681518a
TI
4019 /* set capture source to mic-in */
4020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4021 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4022 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 4023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
4024 /* speaker-out */
4025 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4026 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4027 /* HP-out */
d681518a
TI
4028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4029 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4030 /* mic-in to input */
4031 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4032 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4033 /* built-in mic */
4034 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4035 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4036 /* jack sense */
a9fd4f3f 4037 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
4038 { }
4039};
4040
4041/* toggle speaker-output according to the hp-jack state */
4f5d1706 4042static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 4043{
a9fd4f3f 4044 struct alc_spec *spec = codec->spec;
d681518a 4045
a9fd4f3f
TI
4046 spec->autocfg.hp_pins[0] = 0x1b;
4047 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
4048 spec->automute = 1;
4049 spec->automute_mode = ALC_AUTOMUTE_AMP;
d681518a
TI
4050}
4051
a9111321 4052static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
df99cd33
TI
4053 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4054 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4055 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4056 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4057 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4058 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4059 { } /* end */
4060};
4061
a9111321 4062static const struct hda_input_mux alc880_medion_rim_capture_source = {
df99cd33
TI
4063 .num_items = 2,
4064 .items = {
4065 { "Mic", 0x0 },
4066 { "Internal Mic", 0x1 },
4067 },
4068};
4069
a9111321 4070static const struct hda_verb alc880_medion_rim_init_verbs[] = {
df99cd33
TI
4071 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4072
4073 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4074 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4075
4076 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4077 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4078 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4079 /* Mic2 (as headphone out) for HP output */
4080 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4081 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4082 /* Internal Speaker */
4083 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4085
4086 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4087 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4088
4089 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4090 { }
4091};
4092
4093/* toggle speaker-output according to the hp-jack state */
4094static void alc880_medion_rim_automute(struct hda_codec *codec)
4095{
a9fd4f3f 4096 struct alc_spec *spec = codec->spec;
d922b51d 4097 alc_hp_automute(codec);
a9fd4f3f
TI
4098 /* toggle EAPD */
4099 if (spec->jack_present)
df99cd33
TI
4100 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4101 else
4102 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4103}
4104
4105static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4106 unsigned int res)
4107{
4108 /* Looks like the unsol event is incompatible with the standard
4109 * definition. 4bit tag is placed at 28 bit!
4110 */
4111 if ((res >> 28) == ALC880_HP_EVENT)
4112 alc880_medion_rim_automute(codec);
4113}
4114
4f5d1706 4115static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
4116{
4117 struct alc_spec *spec = codec->spec;
4118
4119 spec->autocfg.hp_pins[0] = 0x14;
4120 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
4121 spec->automute = 1;
4122 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f
TI
4123}
4124
cb53c626 4125#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 4126static const struct hda_amp_list alc880_loopbacks[] = {
cb53c626
TI
4127 { 0x0b, HDA_INPUT, 0 },
4128 { 0x0b, HDA_INPUT, 1 },
4129 { 0x0b, HDA_INPUT, 2 },
4130 { 0x0b, HDA_INPUT, 3 },
4131 { 0x0b, HDA_INPUT, 4 },
4132 { } /* end */
4133};
4134
a9111321 4135static const struct hda_amp_list alc880_lg_loopbacks[] = {
cb53c626
TI
4136 { 0x0b, HDA_INPUT, 1 },
4137 { 0x0b, HDA_INPUT, 6 },
4138 { 0x0b, HDA_INPUT, 7 },
4139 { } /* end */
4140};
4141#endif
4142
ae6b813a
TI
4143/*
4144 * Common callbacks
e9edcee0
TI
4145 */
4146
584c0c4c
TI
4147static void alc_init_special_input_src(struct hda_codec *codec);
4148
1da177e4
LT
4149static int alc_init(struct hda_codec *codec)
4150{
4151 struct alc_spec *spec = codec->spec;
e9edcee0
TI
4152 unsigned int i;
4153
2c3bf9ab 4154 alc_fix_pll(codec);
4a79ba34 4155 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 4156
e9edcee0
TI
4157 for (i = 0; i < spec->num_init_verbs; i++)
4158 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 4159 alc_init_special_input_src(codec);
ae6b813a
TI
4160
4161 if (spec->init_hook)
4162 spec->init_hook(codec);
4163
58701120
TI
4164 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4165
9e5341b9 4166 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
4167 return 0;
4168}
4169
ae6b813a
TI
4170static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4171{
4172 struct alc_spec *spec = codec->spec;
4173
4174 if (spec->unsol_event)
4175 spec->unsol_event(codec, res);
4176}
4177
cb53c626
TI
4178#ifdef CONFIG_SND_HDA_POWER_SAVE
4179static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4180{
4181 struct alc_spec *spec = codec->spec;
4182 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4183}
4184#endif
4185
1da177e4
LT
4186/*
4187 * Analog playback callbacks
4188 */
4189static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4190 struct hda_codec *codec,
c8b6bf9b 4191 struct snd_pcm_substream *substream)
1da177e4
LT
4192{
4193 struct alc_spec *spec = codec->spec;
9a08160b
TI
4194 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4195 hinfo);
1da177e4
LT
4196}
4197
4198static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4199 struct hda_codec *codec,
4200 unsigned int stream_tag,
4201 unsigned int format,
c8b6bf9b 4202 struct snd_pcm_substream *substream)
1da177e4
LT
4203{
4204 struct alc_spec *spec = codec->spec;
9c7f852e
TI
4205 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4206 stream_tag, format, substream);
1da177e4
LT
4207}
4208
4209static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4210 struct hda_codec *codec,
c8b6bf9b 4211 struct snd_pcm_substream *substream)
1da177e4
LT
4212{
4213 struct alc_spec *spec = codec->spec;
4214 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4215}
4216
4217/*
4218 * Digital out
4219 */
4220static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4221 struct hda_codec *codec,
c8b6bf9b 4222 struct snd_pcm_substream *substream)
1da177e4
LT
4223{
4224 struct alc_spec *spec = codec->spec;
4225 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4226}
4227
6b97eb45
TI
4228static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4229 struct hda_codec *codec,
4230 unsigned int stream_tag,
4231 unsigned int format,
4232 struct snd_pcm_substream *substream)
4233{
4234 struct alc_spec *spec = codec->spec;
4235 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4236 stream_tag, format, substream);
4237}
4238
9b5f12e5
TI
4239static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4240 struct hda_codec *codec,
4241 struct snd_pcm_substream *substream)
4242{
4243 struct alc_spec *spec = codec->spec;
4244 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4245}
4246
1da177e4
LT
4247static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4248 struct hda_codec *codec,
c8b6bf9b 4249 struct snd_pcm_substream *substream)
1da177e4
LT
4250{
4251 struct alc_spec *spec = codec->spec;
4252 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4253}
4254
4255/*
4256 * Analog capture
4257 */
6330079f 4258static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4259 struct hda_codec *codec,
4260 unsigned int stream_tag,
4261 unsigned int format,
c8b6bf9b 4262 struct snd_pcm_substream *substream)
1da177e4
LT
4263{
4264 struct alc_spec *spec = codec->spec;
4265
6330079f 4266 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4267 stream_tag, 0, format);
4268 return 0;
4269}
4270
6330079f 4271static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4272 struct hda_codec *codec,
c8b6bf9b 4273 struct snd_pcm_substream *substream)
1da177e4
LT
4274{
4275 struct alc_spec *spec = codec->spec;
4276
888afa15
TI
4277 snd_hda_codec_cleanup_stream(codec,
4278 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4279 return 0;
4280}
4281
840b64c0
TI
4282/* analog capture with dynamic dual-adc changes */
4283static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4284 struct hda_codec *codec,
4285 unsigned int stream_tag,
4286 unsigned int format,
4287 struct snd_pcm_substream *substream)
4288{
4289 struct alc_spec *spec = codec->spec;
4290 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4291 spec->cur_adc_stream_tag = stream_tag;
4292 spec->cur_adc_format = format;
4293 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4294 return 0;
4295}
4296
4297static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4298 struct hda_codec *codec,
4299 struct snd_pcm_substream *substream)
4300{
4301 struct alc_spec *spec = codec->spec;
4302 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4303 spec->cur_adc = 0;
4304 return 0;
4305}
4306
a9111321 4307static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
840b64c0
TI
4308 .substreams = 1,
4309 .channels_min = 2,
4310 .channels_max = 2,
4311 .nid = 0, /* fill later */
4312 .ops = {
4313 .prepare = dualmic_capture_pcm_prepare,
4314 .cleanup = dualmic_capture_pcm_cleanup
4315 },
4316};
1da177e4
LT
4317
4318/*
4319 */
a9111321 4320static const struct hda_pcm_stream alc880_pcm_analog_playback = {
1da177e4
LT
4321 .substreams = 1,
4322 .channels_min = 2,
4323 .channels_max = 8,
e9edcee0 4324 /* NID is set in alc_build_pcms */
1da177e4
LT
4325 .ops = {
4326 .open = alc880_playback_pcm_open,
4327 .prepare = alc880_playback_pcm_prepare,
4328 .cleanup = alc880_playback_pcm_cleanup
4329 },
4330};
4331
a9111321 4332static const struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4333 .substreams = 1,
4334 .channels_min = 2,
4335 .channels_max = 2,
4336 /* NID is set in alc_build_pcms */
4337};
4338
a9111321 4339static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
6330079f
TI
4340 .substreams = 1,
4341 .channels_min = 2,
4342 .channels_max = 2,
4343 /* NID is set in alc_build_pcms */
4344};
4345
a9111321 4346static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
6330079f 4347 .substreams = 2, /* can be overridden */
1da177e4
LT
4348 .channels_min = 2,
4349 .channels_max = 2,
e9edcee0 4350 /* NID is set in alc_build_pcms */
1da177e4 4351 .ops = {
6330079f
TI
4352 .prepare = alc880_alt_capture_pcm_prepare,
4353 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4354 },
4355};
4356
a9111321 4357static const struct hda_pcm_stream alc880_pcm_digital_playback = {
1da177e4
LT
4358 .substreams = 1,
4359 .channels_min = 2,
4360 .channels_max = 2,
4361 /* NID is set in alc_build_pcms */
4362 .ops = {
4363 .open = alc880_dig_playback_pcm_open,
6b97eb45 4364 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4365 .prepare = alc880_dig_playback_pcm_prepare,
4366 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4367 },
4368};
4369
a9111321 4370static const struct hda_pcm_stream alc880_pcm_digital_capture = {
1da177e4
LT
4371 .substreams = 1,
4372 .channels_min = 2,
4373 .channels_max = 2,
4374 /* NID is set in alc_build_pcms */
4375};
4376
4c5186ed 4377/* Used by alc_build_pcms to flag that a PCM has no playback stream */
a9111321 4378static const struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4379 .substreams = 0,
4380 .channels_min = 0,
4381 .channels_max = 0,
4382};
4383
1da177e4
LT
4384static int alc_build_pcms(struct hda_codec *codec)
4385{
4386 struct alc_spec *spec = codec->spec;
4387 struct hda_pcm *info = spec->pcm_rec;
4388 int i;
4389
4390 codec->num_pcms = 1;
4391 codec->pcm_info = info;
4392
e64f14f4
TI
4393 if (spec->no_analog)
4394 goto skip_analog;
4395
812a2cca
TI
4396 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4397 "%s Analog", codec->chip_name);
1da177e4 4398 info->name = spec->stream_name_analog;
274693f3 4399
4a471b7d 4400 if (spec->stream_analog_playback) {
da3cec35
TI
4401 if (snd_BUG_ON(!spec->multiout.dac_nids))
4402 return -EINVAL;
4a471b7d
TI
4403 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4404 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4405 }
4406 if (spec->stream_analog_capture) {
da3cec35
TI
4407 if (snd_BUG_ON(!spec->adc_nids))
4408 return -EINVAL;
4a471b7d
TI
4409 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4410 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4411 }
4412
4413 if (spec->channel_mode) {
4414 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4415 for (i = 0; i < spec->num_channel_mode; i++) {
4416 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4417 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4418 }
1da177e4
LT
4419 }
4420 }
4421
e64f14f4 4422 skip_analog:
e08a007d 4423 /* SPDIF for stream index #1 */
1da177e4 4424 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4425 snprintf(spec->stream_name_digital,
4426 sizeof(spec->stream_name_digital),
4427 "%s Digital", codec->chip_name);
e08a007d 4428 codec->num_pcms = 2;
b25c9da1 4429 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4430 info = spec->pcm_rec + 1;
1da177e4 4431 info->name = spec->stream_name_digital;
8c441982
TI
4432 if (spec->dig_out_type)
4433 info->pcm_type = spec->dig_out_type;
4434 else
4435 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4436 if (spec->multiout.dig_out_nid &&
4437 spec->stream_digital_playback) {
1da177e4
LT
4438 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4439 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4440 }
4a471b7d
TI
4441 if (spec->dig_in_nid &&
4442 spec->stream_digital_capture) {
1da177e4
LT
4443 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4444 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4445 }
963f803f
TI
4446 /* FIXME: do we need this for all Realtek codec models? */
4447 codec->spdif_status_reset = 1;
1da177e4
LT
4448 }
4449
e64f14f4
TI
4450 if (spec->no_analog)
4451 return 0;
4452
e08a007d
TI
4453 /* If the use of more than one ADC is requested for the current
4454 * model, configure a second analog capture-only PCM.
4455 */
4456 /* Additional Analaog capture for index #2 */
6330079f
TI
4457 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4458 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4459 codec->num_pcms = 3;
c06134d7 4460 info = spec->pcm_rec + 2;
e08a007d 4461 info->name = spec->stream_name_analog;
6330079f
TI
4462 if (spec->alt_dac_nid) {
4463 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4464 *spec->stream_analog_alt_playback;
4465 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4466 spec->alt_dac_nid;
4467 } else {
4468 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4469 alc_pcm_null_stream;
4470 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4471 }
ce85c9ac 4472 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
6330079f
TI
4473 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4474 *spec->stream_analog_alt_capture;
4475 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4476 spec->adc_nids[1];
4477 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4478 spec->num_adc_nids - 1;
4479 } else {
4480 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4481 alc_pcm_null_stream;
4482 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4483 }
4484 }
4485
1da177e4
LT
4486 return 0;
4487}
4488
a4e09aa3
TI
4489static inline void alc_shutup(struct hda_codec *codec)
4490{
1c716153
TI
4491 struct alc_spec *spec = codec->spec;
4492
4493 if (spec && spec->shutup)
4494 spec->shutup(codec);
a4e09aa3
TI
4495 snd_hda_shutup_pins(codec);
4496}
4497
603c4019
TI
4498static void alc_free_kctls(struct hda_codec *codec)
4499{
4500 struct alc_spec *spec = codec->spec;
4501
4502 if (spec->kctls.list) {
4503 struct snd_kcontrol_new *kctl = spec->kctls.list;
4504 int i;
4505 for (i = 0; i < spec->kctls.used; i++)
4506 kfree(kctl[i].name);
4507 }
4508 snd_array_free(&spec->kctls);
4509}
4510
1da177e4
LT
4511static void alc_free(struct hda_codec *codec)
4512{
e9edcee0 4513 struct alc_spec *spec = codec->spec;
e9edcee0 4514
f12ab1e0 4515 if (!spec)
e9edcee0
TI
4516 return;
4517
a4e09aa3 4518 alc_shutup(codec);
cd372fb3 4519 snd_hda_input_jack_free(codec);
603c4019 4520 alc_free_kctls(codec);
e9edcee0 4521 kfree(spec);
680cd536 4522 snd_hda_detach_beep_device(codec);
1da177e4
LT
4523}
4524
f5de24b0 4525#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4526static void alc_power_eapd(struct hda_codec *codec)
4527{
691f1fcc 4528 alc_auto_setup_eapd(codec, false);
c97259df
DC
4529}
4530
f5de24b0
HM
4531static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4532{
4533 struct alc_spec *spec = codec->spec;
a4e09aa3 4534 alc_shutup(codec);
f5de24b0 4535 if (spec && spec->power_hook)
c97259df 4536 spec->power_hook(codec);
f5de24b0
HM
4537 return 0;
4538}
4539#endif
4540
e044c39a 4541#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4542static int alc_resume(struct hda_codec *codec)
4543{
1c716153 4544 msleep(150); /* to avoid pop noise */
e044c39a
TI
4545 codec->patch_ops.init(codec);
4546 snd_hda_codec_resume_amp(codec);
4547 snd_hda_codec_resume_cache(codec);
9e5341b9 4548 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4549 return 0;
4550}
e044c39a
TI
4551#endif
4552
1da177e4
LT
4553/*
4554 */
a9111321 4555static const struct hda_codec_ops alc_patch_ops = {
1da177e4
LT
4556 .build_controls = alc_build_controls,
4557 .build_pcms = alc_build_pcms,
4558 .init = alc_init,
4559 .free = alc_free,
ae6b813a 4560 .unsol_event = alc_unsol_event,
e044c39a
TI
4561#ifdef SND_HDA_NEEDS_RESUME
4562 .resume = alc_resume,
4563#endif
cb53c626 4564#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4565 .suspend = alc_suspend,
cb53c626
TI
4566 .check_power_status = alc_check_power_status,
4567#endif
c97259df 4568 .reboot_notify = alc_shutup,
1da177e4
LT
4569};
4570
c027ddcd
KY
4571/* replace the codec chip_name with the given string */
4572static int alc_codec_rename(struct hda_codec *codec, const char *name)
4573{
4574 kfree(codec->chip_name);
4575 codec->chip_name = kstrdup(name, GFP_KERNEL);
4576 if (!codec->chip_name) {
4577 alc_free(codec);
4578 return -ENOMEM;
4579 }
4580 return 0;
4581}
4582
2fa522be
TI
4583/*
4584 * Test configuration for debugging
4585 *
4586 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4587 * enum controls.
4588 */
4589#ifdef CONFIG_SND_DEBUG
4c6d72d1 4590static const hda_nid_t alc880_test_dac_nids[4] = {
2fa522be
TI
4591 0x02, 0x03, 0x04, 0x05
4592};
4593
a9111321 4594static const struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4595 .num_items = 7,
2fa522be
TI
4596 .items = {
4597 { "In-1", 0x0 },
4598 { "In-2", 0x1 },
4599 { "In-3", 0x2 },
4600 { "In-4", 0x3 },
4601 { "CD", 0x4 },
ae6b813a
TI
4602 { "Front", 0x5 },
4603 { "Surround", 0x6 },
2fa522be
TI
4604 },
4605};
4606
a9111321 4607static const struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4608 { 2, NULL },
fd2c326d 4609 { 4, NULL },
2fa522be 4610 { 6, NULL },
fd2c326d 4611 { 8, NULL },
2fa522be
TI
4612};
4613
9c7f852e
TI
4614static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4615 struct snd_ctl_elem_info *uinfo)
2fa522be 4616{
4c6d72d1 4617 static const char * const texts[] = {
2fa522be
TI
4618 "N/A", "Line Out", "HP Out",
4619 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4620 };
4621 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4622 uinfo->count = 1;
4623 uinfo->value.enumerated.items = 8;
4624 if (uinfo->value.enumerated.item >= 8)
4625 uinfo->value.enumerated.item = 7;
4626 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4627 return 0;
4628}
4629
9c7f852e
TI
4630static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4631 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4632{
4633 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4634 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4635 unsigned int pin_ctl, item = 0;
4636
4637 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4638 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4639 if (pin_ctl & AC_PINCTL_OUT_EN) {
4640 if (pin_ctl & AC_PINCTL_HP_EN)
4641 item = 2;
4642 else
4643 item = 1;
4644 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4645 switch (pin_ctl & AC_PINCTL_VREFEN) {
4646 case AC_PINCTL_VREF_HIZ: item = 3; break;
4647 case AC_PINCTL_VREF_50: item = 4; break;
4648 case AC_PINCTL_VREF_GRD: item = 5; break;
4649 case AC_PINCTL_VREF_80: item = 6; break;
4650 case AC_PINCTL_VREF_100: item = 7; break;
4651 }
4652 }
4653 ucontrol->value.enumerated.item[0] = item;
4654 return 0;
4655}
4656
9c7f852e
TI
4657static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4658 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4659{
4660 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4661 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4c6d72d1 4662 static const unsigned int ctls[] = {
2fa522be
TI
4663 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4664 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4665 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4666 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4667 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4668 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4669 };
4670 unsigned int old_ctl, new_ctl;
4671
4672 old_ctl = snd_hda_codec_read(codec, nid, 0,
4673 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4674 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4675 if (old_ctl != new_ctl) {
82beb8fd
TI
4676 int val;
4677 snd_hda_codec_write_cache(codec, nid, 0,
4678 AC_VERB_SET_PIN_WIDGET_CONTROL,
4679 new_ctl);
47fd830a
TI
4680 val = ucontrol->value.enumerated.item[0] >= 3 ?
4681 HDA_AMP_MUTE : 0;
4682 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4683 HDA_AMP_MUTE, val);
2fa522be
TI
4684 return 1;
4685 }
4686 return 0;
4687}
4688
9c7f852e
TI
4689static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4690 struct snd_ctl_elem_info *uinfo)
2fa522be 4691{
4c6d72d1 4692 static const char * const texts[] = {
2fa522be
TI
4693 "Front", "Surround", "CLFE", "Side"
4694 };
4695 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4696 uinfo->count = 1;
4697 uinfo->value.enumerated.items = 4;
4698 if (uinfo->value.enumerated.item >= 4)
4699 uinfo->value.enumerated.item = 3;
4700 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4701 return 0;
4702}
4703
9c7f852e
TI
4704static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4705 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4706{
4707 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4708 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4709 unsigned int sel;
4710
4711 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4712 ucontrol->value.enumerated.item[0] = sel & 3;
4713 return 0;
4714}
4715
9c7f852e
TI
4716static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4717 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4718{
4719 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4720 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4721 unsigned int sel;
4722
4723 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4724 if (ucontrol->value.enumerated.item[0] != sel) {
4725 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4726 snd_hda_codec_write_cache(codec, nid, 0,
4727 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4728 return 1;
4729 }
4730 return 0;
4731}
4732
4733#define PIN_CTL_TEST(xname,nid) { \
4734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4735 .name = xname, \
5b0cb1d8 4736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4737 .info = alc_test_pin_ctl_info, \
4738 .get = alc_test_pin_ctl_get, \
4739 .put = alc_test_pin_ctl_put, \
4740 .private_value = nid \
4741 }
4742
4743#define PIN_SRC_TEST(xname,nid) { \
4744 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4745 .name = xname, \
5b0cb1d8 4746 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4747 .info = alc_test_pin_src_info, \
4748 .get = alc_test_pin_src_get, \
4749 .put = alc_test_pin_src_put, \
4750 .private_value = nid \
4751 }
4752
a9111321 4753static const struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4754 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4755 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4756 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4757 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4758 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4759 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4760 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4761 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4762 PIN_CTL_TEST("Front Pin Mode", 0x14),
4763 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4764 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4765 PIN_CTL_TEST("Side Pin Mode", 0x17),
4766 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4767 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4768 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4769 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4770 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4771 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4772 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4773 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4774 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4775 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4776 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4777 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4778 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4779 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4780 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4781 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4782 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4783 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4784 {
4785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4786 .name = "Channel Mode",
df694daa
KY
4787 .info = alc_ch_mode_info,
4788 .get = alc_ch_mode_get,
4789 .put = alc_ch_mode_put,
2fa522be
TI
4790 },
4791 { } /* end */
4792};
4793
a9111321 4794static const struct hda_verb alc880_test_init_verbs[] = {
2fa522be 4795 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4798 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4799 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4800 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4801 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4802 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4803 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4804 /* Vol output for 0x0c-0x0f */
05acb863
TI
4805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4807 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4809 /* Set output pins 0x14-0x17 */
05acb863
TI
4810 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4811 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4812 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4813 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4814 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4815 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4817 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4818 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4819 /* Set input pins 0x18-0x1c */
16ded525
TI
4820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4821 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4822 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4823 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4824 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4825 /* Mute input pins 0x18-0x1b */
05acb863
TI
4826 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4827 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4828 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4829 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4830 /* ADC set up */
05acb863 4831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4832 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4834 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4835 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4836 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4837 /* Analog input/passthru */
4838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4842 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4843 { }
4844};
4845#endif
4846
1da177e4
LT
4847/*
4848 */
4849
ea734963 4850static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4851 [ALC880_3ST] = "3stack",
4852 [ALC880_TCL_S700] = "tcl",
4853 [ALC880_3ST_DIG] = "3stack-digout",
4854 [ALC880_CLEVO] = "clevo",
4855 [ALC880_5ST] = "5stack",
4856 [ALC880_5ST_DIG] = "5stack-digout",
4857 [ALC880_W810] = "w810",
4858 [ALC880_Z71V] = "z71v",
4859 [ALC880_6ST] = "6stack",
4860 [ALC880_6ST_DIG] = "6stack-digout",
4861 [ALC880_ASUS] = "asus",
4862 [ALC880_ASUS_W1V] = "asus-w1v",
4863 [ALC880_ASUS_DIG] = "asus-dig",
4864 [ALC880_ASUS_DIG2] = "asus-dig2",
4865 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4866 [ALC880_UNIWILL_P53] = "uniwill-p53",
4867 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4868 [ALC880_F1734] = "F1734",
4869 [ALC880_LG] = "lg",
4870 [ALC880_LG_LW] = "lg-lw",
df99cd33 4871 [ALC880_MEDION_RIM] = "medion",
2fa522be 4872#ifdef CONFIG_SND_DEBUG
f5fcc13c 4873 [ALC880_TEST] = "test",
2fa522be 4874#endif
f5fcc13c
TI
4875 [ALC880_AUTO] = "auto",
4876};
4877
a9111321 4878static const struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4879 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4880 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4881 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4882 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4883 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4884 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4885 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4886 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4887 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c 4888 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
f5fcc13c
TI
4889 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4890 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4891 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4892 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4893 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4894 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4895 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4896 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4897 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4898 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4899 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4900 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4901 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4902 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4903 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4904 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4905 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4906 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4907 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4908 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4909 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4910 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4911 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4912 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4913 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4914 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4915 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4916 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4917 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4918 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
4919 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4920 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4921 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4922 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4923 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4924 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4925 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4926 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4927 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4928 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4929 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4930 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4931 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4932 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4933 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4934 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4935 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4936 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4937 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4938 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4939 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4940 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4941 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4942 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4943 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4944 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4945 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4946 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4947 /* default Intel */
4948 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4949 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4950 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4951 {}
4952};
4953
16ded525 4954/*
df694daa 4955 * ALC880 codec presets
16ded525 4956 */
a9111321 4957static const struct alc_config_preset alc880_presets[] = {
16ded525 4958 [ALC880_3ST] = {
e9edcee0 4959 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4960 .init_verbs = { alc880_volume_init_verbs,
4961 alc880_pin_3stack_init_verbs },
16ded525 4962 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4963 .dac_nids = alc880_dac_nids,
16ded525
TI
4964 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4965 .channel_mode = alc880_threestack_modes,
4e195a7b 4966 .need_dac_fix = 1,
16ded525
TI
4967 .input_mux = &alc880_capture_source,
4968 },
4969 [ALC880_3ST_DIG] = {
e9edcee0 4970 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4971 .init_verbs = { alc880_volume_init_verbs,
4972 alc880_pin_3stack_init_verbs },
16ded525 4973 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4974 .dac_nids = alc880_dac_nids,
4975 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4976 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4977 .channel_mode = alc880_threestack_modes,
4e195a7b 4978 .need_dac_fix = 1,
16ded525
TI
4979 .input_mux = &alc880_capture_source,
4980 },
df694daa
KY
4981 [ALC880_TCL_S700] = {
4982 .mixers = { alc880_tcl_s700_mixer },
4983 .init_verbs = { alc880_volume_init_verbs,
4984 alc880_pin_tcl_S700_init_verbs,
4985 alc880_gpio2_init_verbs },
4986 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4987 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4988 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4989 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4990 .hp_nid = 0x03,
4991 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4992 .channel_mode = alc880_2_jack_modes,
4993 .input_mux = &alc880_capture_source,
4994 },
16ded525 4995 [ALC880_5ST] = {
f12ab1e0
TI
4996 .mixers = { alc880_three_stack_mixer,
4997 alc880_five_stack_mixer},
4998 .init_verbs = { alc880_volume_init_verbs,
4999 alc880_pin_5stack_init_verbs },
16ded525
TI
5000 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5001 .dac_nids = alc880_dac_nids,
16ded525
TI
5002 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5003 .channel_mode = alc880_fivestack_modes,
5004 .input_mux = &alc880_capture_source,
5005 },
5006 [ALC880_5ST_DIG] = {
f12ab1e0
TI
5007 .mixers = { alc880_three_stack_mixer,
5008 alc880_five_stack_mixer },
5009 .init_verbs = { alc880_volume_init_verbs,
5010 alc880_pin_5stack_init_verbs },
16ded525
TI
5011 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5012 .dac_nids = alc880_dac_nids,
5013 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5014 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5015 .channel_mode = alc880_fivestack_modes,
5016 .input_mux = &alc880_capture_source,
5017 },
b6482d48
TI
5018 [ALC880_6ST] = {
5019 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5020 .init_verbs = { alc880_volume_init_verbs,
5021 alc880_pin_6stack_init_verbs },
b6482d48
TI
5022 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5023 .dac_nids = alc880_6st_dac_nids,
5024 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5025 .channel_mode = alc880_sixstack_modes,
5026 .input_mux = &alc880_6stack_capture_source,
5027 },
16ded525 5028 [ALC880_6ST_DIG] = {
e9edcee0 5029 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5030 .init_verbs = { alc880_volume_init_verbs,
5031 alc880_pin_6stack_init_verbs },
16ded525
TI
5032 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5033 .dac_nids = alc880_6st_dac_nids,
5034 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5035 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5036 .channel_mode = alc880_sixstack_modes,
5037 .input_mux = &alc880_6stack_capture_source,
5038 },
5039 [ALC880_W810] = {
e9edcee0 5040 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
5041 .init_verbs = { alc880_volume_init_verbs,
5042 alc880_pin_w810_init_verbs,
b0af0de5 5043 alc880_gpio2_init_verbs },
16ded525
TI
5044 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5045 .dac_nids = alc880_w810_dac_nids,
5046 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5047 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5048 .channel_mode = alc880_w810_modes,
5049 .input_mux = &alc880_capture_source,
5050 },
5051 [ALC880_Z71V] = {
e9edcee0 5052 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
5053 .init_verbs = { alc880_volume_init_verbs,
5054 alc880_pin_z71v_init_verbs },
16ded525
TI
5055 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5056 .dac_nids = alc880_z71v_dac_nids,
5057 .dig_out_nid = ALC880_DIGOUT_NID,
5058 .hp_nid = 0x03,
e9edcee0
TI
5059 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5060 .channel_mode = alc880_2_jack_modes,
16ded525
TI
5061 .input_mux = &alc880_capture_source,
5062 },
5063 [ALC880_F1734] = {
e9edcee0 5064 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
5065 .init_verbs = { alc880_volume_init_verbs,
5066 alc880_pin_f1734_init_verbs },
e9edcee0
TI
5067 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5068 .dac_nids = alc880_f1734_dac_nids,
5069 .hp_nid = 0x02,
5070 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5071 .channel_mode = alc880_2_jack_modes,
937b4160
TI
5072 .input_mux = &alc880_f1734_capture_source,
5073 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5074 .setup = alc880_uniwill_p53_setup,
d922b51d 5075 .init_hook = alc_hp_automute,
16ded525
TI
5076 },
5077 [ALC880_ASUS] = {
e9edcee0 5078 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5079 .init_verbs = { alc880_volume_init_verbs,
5080 alc880_pin_asus_init_verbs,
e9edcee0
TI
5081 alc880_gpio1_init_verbs },
5082 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5083 .dac_nids = alc880_asus_dac_nids,
5084 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5085 .channel_mode = alc880_asus_modes,
4e195a7b 5086 .need_dac_fix = 1,
16ded525
TI
5087 .input_mux = &alc880_capture_source,
5088 },
5089 [ALC880_ASUS_DIG] = {
e9edcee0 5090 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5091 .init_verbs = { alc880_volume_init_verbs,
5092 alc880_pin_asus_init_verbs,
e9edcee0
TI
5093 alc880_gpio1_init_verbs },
5094 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5095 .dac_nids = alc880_asus_dac_nids,
16ded525 5096 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5097 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5098 .channel_mode = alc880_asus_modes,
4e195a7b 5099 .need_dac_fix = 1,
16ded525
TI
5100 .input_mux = &alc880_capture_source,
5101 },
df694daa
KY
5102 [ALC880_ASUS_DIG2] = {
5103 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5104 .init_verbs = { alc880_volume_init_verbs,
5105 alc880_pin_asus_init_verbs,
df694daa
KY
5106 alc880_gpio2_init_verbs }, /* use GPIO2 */
5107 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5108 .dac_nids = alc880_asus_dac_nids,
5109 .dig_out_nid = ALC880_DIGOUT_NID,
5110 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5111 .channel_mode = alc880_asus_modes,
4e195a7b 5112 .need_dac_fix = 1,
df694daa
KY
5113 .input_mux = &alc880_capture_source,
5114 },
16ded525 5115 [ALC880_ASUS_W1V] = {
e9edcee0 5116 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
5117 .init_verbs = { alc880_volume_init_verbs,
5118 alc880_pin_asus_init_verbs,
e9edcee0
TI
5119 alc880_gpio1_init_verbs },
5120 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5121 .dac_nids = alc880_asus_dac_nids,
16ded525 5122 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5123 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5124 .channel_mode = alc880_asus_modes,
4e195a7b 5125 .need_dac_fix = 1,
16ded525
TI
5126 .input_mux = &alc880_capture_source,
5127 },
5128 [ALC880_UNIWILL_DIG] = {
45bdd1c1 5129 .mixers = { alc880_asus_mixer },
ccc656ce
KY
5130 .init_verbs = { alc880_volume_init_verbs,
5131 alc880_pin_asus_init_verbs },
e9edcee0
TI
5132 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5133 .dac_nids = alc880_asus_dac_nids,
16ded525 5134 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5135 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5136 .channel_mode = alc880_asus_modes,
4e195a7b 5137 .need_dac_fix = 1,
16ded525
TI
5138 .input_mux = &alc880_capture_source,
5139 },
ccc656ce
KY
5140 [ALC880_UNIWILL] = {
5141 .mixers = { alc880_uniwill_mixer },
5142 .init_verbs = { alc880_volume_init_verbs,
5143 alc880_uniwill_init_verbs },
5144 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5145 .dac_nids = alc880_asus_dac_nids,
5146 .dig_out_nid = ALC880_DIGOUT_NID,
5147 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5148 .channel_mode = alc880_threestack_modes,
5149 .need_dac_fix = 1,
5150 .input_mux = &alc880_capture_source,
5151 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 5152 .setup = alc880_uniwill_setup,
a9fd4f3f 5153 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
5154 },
5155 [ALC880_UNIWILL_P53] = {
5156 .mixers = { alc880_uniwill_p53_mixer },
5157 .init_verbs = { alc880_volume_init_verbs,
5158 alc880_uniwill_p53_init_verbs },
5159 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5160 .dac_nids = alc880_asus_dac_nids,
5161 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
5162 .channel_mode = alc880_threestack_modes,
5163 .input_mux = &alc880_capture_source,
5164 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5165 .setup = alc880_uniwill_p53_setup,
d922b51d 5166 .init_hook = alc_hp_automute,
2cf9f0fc
TD
5167 },
5168 [ALC880_FUJITSU] = {
45bdd1c1 5169 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
5170 .init_verbs = { alc880_volume_init_verbs,
5171 alc880_uniwill_p53_init_verbs,
5172 alc880_beep_init_verbs },
5173 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5174 .dac_nids = alc880_dac_nids,
d53d7d9e 5175 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
5176 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5177 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
5178 .input_mux = &alc880_capture_source,
5179 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5180 .setup = alc880_uniwill_p53_setup,
d922b51d 5181 .init_hook = alc_hp_automute,
ccc656ce 5182 },
df694daa
KY
5183 [ALC880_CLEVO] = {
5184 .mixers = { alc880_three_stack_mixer },
5185 .init_verbs = { alc880_volume_init_verbs,
5186 alc880_pin_clevo_init_verbs },
5187 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5188 .dac_nids = alc880_dac_nids,
5189 .hp_nid = 0x03,
5190 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5191 .channel_mode = alc880_threestack_modes,
4e195a7b 5192 .need_dac_fix = 1,
df694daa
KY
5193 .input_mux = &alc880_capture_source,
5194 },
ae6b813a
TI
5195 [ALC880_LG] = {
5196 .mixers = { alc880_lg_mixer },
5197 .init_verbs = { alc880_volume_init_verbs,
5198 alc880_lg_init_verbs },
5199 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5200 .dac_nids = alc880_lg_dac_nids,
5201 .dig_out_nid = ALC880_DIGOUT_NID,
5202 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5203 .channel_mode = alc880_lg_ch_modes,
4e195a7b 5204 .need_dac_fix = 1,
ae6b813a 5205 .input_mux = &alc880_lg_capture_source,
d922b51d 5206 .unsol_event = alc_sku_unsol_event,
4f5d1706 5207 .setup = alc880_lg_setup,
d922b51d 5208 .init_hook = alc_hp_automute,
cb53c626
TI
5209#ifdef CONFIG_SND_HDA_POWER_SAVE
5210 .loopbacks = alc880_lg_loopbacks,
5211#endif
ae6b813a 5212 },
d681518a
TI
5213 [ALC880_LG_LW] = {
5214 .mixers = { alc880_lg_lw_mixer },
5215 .init_verbs = { alc880_volume_init_verbs,
5216 alc880_lg_lw_init_verbs },
0a8c5da3 5217 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5218 .dac_nids = alc880_dac_nids,
5219 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5220 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5221 .channel_mode = alc880_lg_lw_modes,
d681518a 5222 .input_mux = &alc880_lg_lw_capture_source,
d922b51d 5223 .unsol_event = alc_sku_unsol_event,
4f5d1706 5224 .setup = alc880_lg_lw_setup,
d922b51d 5225 .init_hook = alc_hp_automute,
d681518a 5226 },
df99cd33
TI
5227 [ALC880_MEDION_RIM] = {
5228 .mixers = { alc880_medion_rim_mixer },
5229 .init_verbs = { alc880_volume_init_verbs,
5230 alc880_medion_rim_init_verbs,
5231 alc_gpio2_init_verbs },
5232 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5233 .dac_nids = alc880_dac_nids,
5234 .dig_out_nid = ALC880_DIGOUT_NID,
5235 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5236 .channel_mode = alc880_2_jack_modes,
5237 .input_mux = &alc880_medion_rim_capture_source,
5238 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5239 .setup = alc880_medion_rim_setup,
5240 .init_hook = alc880_medion_rim_automute,
df99cd33 5241 },
16ded525
TI
5242#ifdef CONFIG_SND_DEBUG
5243 [ALC880_TEST] = {
e9edcee0
TI
5244 .mixers = { alc880_test_mixer },
5245 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5246 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5247 .dac_nids = alc880_test_dac_nids,
5248 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5249 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5250 .channel_mode = alc880_test_modes,
5251 .input_mux = &alc880_test_capture_source,
5252 },
5253#endif
5254};
5255
e9edcee0
TI
5256/*
5257 * Automatic parse of I/O pins from the BIOS configuration
5258 */
5259
e9edcee0
TI
5260enum {
5261 ALC_CTL_WIDGET_VOL,
5262 ALC_CTL_WIDGET_MUTE,
5263 ALC_CTL_BIND_MUTE,
5264};
a9111321 5265static const struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5266 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5267 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5268 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5269};
5270
ce764ab2
TI
5271static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5272{
5273 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5274 return snd_array_new(&spec->kctls);
5275}
5276
e9edcee0 5277/* add dynamic controls */
f12ab1e0 5278static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5279 int cidx, unsigned long val)
e9edcee0 5280{
c8b6bf9b 5281 struct snd_kcontrol_new *knew;
e9edcee0 5282
ce764ab2 5283 knew = alc_kcontrol_new(spec);
603c4019
TI
5284 if (!knew)
5285 return -ENOMEM;
e9edcee0 5286 *knew = alc880_control_templates[type];
543537bd 5287 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5288 if (!knew->name)
e9edcee0 5289 return -ENOMEM;
66ceeb6b 5290 knew->index = cidx;
4d02d1b6 5291 if (get_amp_nid_(val))
5e26dfd0 5292 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5293 knew->private_value = val;
e9edcee0
TI
5294 return 0;
5295}
5296
0afe5f89
TI
5297static int add_control_with_pfx(struct alc_spec *spec, int type,
5298 const char *pfx, const char *dir,
66ceeb6b 5299 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5300{
5301 char name[32];
5302 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5303 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5304}
5305
66ceeb6b
TI
5306#define add_pb_vol_ctrl(spec, type, pfx, val) \
5307 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5308#define add_pb_sw_ctrl(spec, type, pfx, val) \
5309 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5310#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5311 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5312#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5313 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5314
e9edcee0
TI
5315#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5316#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5317#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5318#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5319#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5320#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5321#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5322#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5323#define ALC880_PIN_CD_NID 0x1c
5324
5325/* fill in the dac_nids table from the parsed pin configuration */
cb053a82 5326static int alc880_auto_fill_dac_nids(struct hda_codec *codec)
e9edcee0 5327{
cb053a82
TI
5328 struct alc_spec *spec = codec->spec;
5329 const struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5330 hda_nid_t nid;
5331 int assigned[4];
5332 int i, j;
5333
5334 memset(assigned, 0, sizeof(assigned));
b0af0de5 5335 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5336
5337 /* check the pins hardwired to audio widget */
5338 for (i = 0; i < cfg->line_outs; i++) {
5339 nid = cfg->line_out_pins[i];
5340 if (alc880_is_fixed_pin(nid)) {
5341 int idx = alc880_fixed_pin_idx(nid);
dda14410 5342 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5343 assigned[idx] = 1;
5344 }
5345 }
5346 /* left pins can be connect to any audio widget */
5347 for (i = 0; i < cfg->line_outs; i++) {
5348 nid = cfg->line_out_pins[i];
5349 if (alc880_is_fixed_pin(nid))
5350 continue;
5351 /* search for an empty channel */
5352 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0 5353 if (!assigned[j]) {
dda14410 5354 spec->private_dac_nids[i] =
f12ab1e0 5355 alc880_idx_to_dac(j);
e9edcee0
TI
5356 assigned[j] = 1;
5357 break;
5358 }
5359 }
5360 }
5361 spec->multiout.num_dacs = cfg->line_outs;
5362 return 0;
5363}
5364
6843ca16
TI
5365static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5366 bool can_be_master, int *index)
bcb2f0f5 5367{
ce764ab2 5368 struct auto_pin_cfg *cfg = &spec->autocfg;
6843ca16
TI
5369 static const char * const chname[4] = {
5370 "Front", "Surround", NULL /*CLFE*/, "Side"
5371 };
ce764ab2 5372
6843ca16 5373 *index = 0;
ce764ab2
TI
5374 if (cfg->line_outs == 1 && !spec->multi_ios &&
5375 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
bcb2f0f5
TI
5376 return "Master";
5377
5378 switch (cfg->line_out_type) {
5379 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5380 if (cfg->line_outs == 1)
5381 return "Speaker";
5382 break;
bcb2f0f5 5383 case AUTO_PIN_HP_OUT:
6843ca16
TI
5384 /* for multi-io case, only the primary out */
5385 if (ch && spec->multi_ios)
5386 break;
5387 *index = ch;
bcb2f0f5
TI
5388 return "Headphone";
5389 default:
ce764ab2 5390 if (cfg->line_outs == 1 && !spec->multi_ios)
bcb2f0f5
TI
5391 return "PCM";
5392 break;
5393 }
6843ca16 5394 return chname[ch];
bcb2f0f5
TI
5395}
5396
e9edcee0 5397/* add playback controls from the parsed DAC table */
df694daa
KY
5398static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5399 const struct auto_pin_cfg *cfg)
e9edcee0 5400{
e9edcee0 5401 hda_nid_t nid;
ce764ab2 5402 int i, err, noutputs;
e9edcee0 5403
ce764ab2
TI
5404 noutputs = cfg->line_outs;
5405 if (spec->multi_ios > 0)
5406 noutputs += spec->multi_ios;
5407
5408 for (i = 0; i < noutputs; i++) {
6843ca16
TI
5409 const char *name;
5410 int index;
f12ab1e0 5411 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5412 continue;
5413 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
6843ca16
TI
5414 name = alc_get_line_out_pfx(spec, i, false, &index);
5415 if (!name) {
e9edcee0 5416 /* Center/LFE */
0afe5f89
TI
5417 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5418 "Center",
f12ab1e0
TI
5419 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5420 HDA_OUTPUT));
5421 if (err < 0)
e9edcee0 5422 return err;
0afe5f89
TI
5423 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5424 "LFE",
f12ab1e0
TI
5425 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5426 HDA_OUTPUT));
5427 if (err < 0)
e9edcee0 5428 return err;
0afe5f89
TI
5429 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5430 "Center",
f12ab1e0
TI
5431 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5432 HDA_INPUT));
5433 if (err < 0)
e9edcee0 5434 return err;
0afe5f89
TI
5435 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5436 "LFE",
f12ab1e0
TI
5437 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5438 HDA_INPUT));
5439 if (err < 0)
e9edcee0
TI
5440 return err;
5441 } else {
bcb2f0f5 5442 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5443 name, index,
f12ab1e0
TI
5444 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5445 HDA_OUTPUT));
5446 if (err < 0)
e9edcee0 5447 return err;
bcb2f0f5 5448 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5449 name, index,
f12ab1e0
TI
5450 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5451 HDA_INPUT));
5452 if (err < 0)
e9edcee0
TI
5453 return err;
5454 }
5455 }
e9edcee0
TI
5456 return 0;
5457}
5458
8d88bc3d
TI
5459/* add playback controls for speaker and HP outputs */
5460static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5461 const char *pfx)
e9edcee0
TI
5462{
5463 hda_nid_t nid;
5464 int err;
5465
f12ab1e0 5466 if (!pin)
e9edcee0
TI
5467 return 0;
5468
5469 if (alc880_is_fixed_pin(pin)) {
5470 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5471 /* specify the DAC as the extra output */
f12ab1e0 5472 if (!spec->multiout.hp_nid)
e9edcee0 5473 spec->multiout.hp_nid = nid;
82bc955f
TI
5474 else
5475 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5476 /* control HP volume/switch on the output mixer amp */
5477 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5478 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5479 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5480 if (err < 0)
e9edcee0 5481 return err;
0afe5f89 5482 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5483 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5484 if (err < 0)
e9edcee0
TI
5485 return err;
5486 } else if (alc880_is_multi_pin(pin)) {
5487 /* set manual connection */
e9edcee0 5488 /* we have only a switch on HP-out PIN */
0afe5f89 5489 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5490 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5491 if (err < 0)
e9edcee0
TI
5492 return err;
5493 }
5494 return 0;
5495}
5496
5497/* create input playback/capture controls for the given pin */
f12ab1e0 5498static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5499 const char *ctlname, int ctlidx,
df694daa 5500 int idx, hda_nid_t mix_nid)
e9edcee0 5501{
df694daa 5502 int err;
e9edcee0 5503
66ceeb6b 5504 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5505 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5506 if (err < 0)
e9edcee0 5507 return err;
66ceeb6b 5508 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5509 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5510 if (err < 0)
e9edcee0
TI
5511 return err;
5512 return 0;
5513}
5514
05f5f477
TI
5515static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5516{
5517 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5518 return (pincap & AC_PINCAP_IN) != 0;
5519}
5520
e9edcee0 5521/* create playback/capture controls for input pins */
05f5f477
TI
5522static int alc_auto_create_input_ctls(struct hda_codec *codec,
5523 const struct auto_pin_cfg *cfg,
5524 hda_nid_t mixer,
5525 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5526{
05f5f477 5527 struct alc_spec *spec = codec->spec;
61b9b9b1 5528 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5529 int i, err, idx, type_idx = 0;
5530 const char *prev_label = NULL;
e9edcee0 5531
66ceeb6b 5532 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5533 hda_nid_t pin;
10a20af7 5534 const char *label;
05f5f477 5535
66ceeb6b 5536 pin = cfg->inputs[i].pin;
05f5f477
TI
5537 if (!alc_is_input_pin(codec, pin))
5538 continue;
5539
5322bf27
DH
5540 label = hda_get_autocfg_input_label(codec, cfg, i);
5541 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5542 type_idx++;
5543 else
5544 type_idx = 0;
5322bf27
DH
5545 prev_label = label;
5546
05f5f477
TI
5547 if (mixer) {
5548 idx = get_connection_index(codec, mixer, pin);
5549 if (idx >= 0) {
5550 err = new_analog_input(spec, pin,
10a20af7
TI
5551 label, type_idx,
5552 idx, mixer);
05f5f477
TI
5553 if (err < 0)
5554 return err;
5555 }
5556 }
5557
5558 if (!cap1)
5559 continue;
5560 idx = get_connection_index(codec, cap1, pin);
5561 if (idx < 0 && cap2)
5562 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5563 if (idx >= 0)
5564 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5565 }
5566 return 0;
5567}
5568
05f5f477
TI
5569static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5570 const struct auto_pin_cfg *cfg)
5571{
5572 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5573}
5574
f6c7e546
TI
5575static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5576 unsigned int pin_type)
5577{
5578 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5579 pin_type);
5580 /* unmute pin */
d260cdf6
TI
5581 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5582 AMP_OUT_UNMUTE);
f6c7e546
TI
5583}
5584
df694daa
KY
5585static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5586 hda_nid_t nid, int pin_type,
e9edcee0
TI
5587 int dac_idx)
5588{
f6c7e546 5589 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5590 /* need the manual connection? */
5591 if (alc880_is_multi_pin(nid)) {
5592 struct alc_spec *spec = codec->spec;
5593 int idx = alc880_multi_pin_idx(nid);
5594 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5595 AC_VERB_SET_CONNECT_SEL,
5596 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5597 }
5598}
5599
baba8ee9
TI
5600static int get_pin_type(int line_out_type)
5601{
5602 if (line_out_type == AUTO_PIN_HP_OUT)
5603 return PIN_HP;
5604 else
5605 return PIN_OUT;
5606}
5607
050ea753 5608static void alc880_auto_init_dac(struct hda_codec *codec, hda_nid_t dac)
1f0f4b80 5609{
050ea753
TI
5610 hda_nid_t nid, mix;
5611
5612 if (!dac)
1f0f4b80 5613 return;
050ea753
TI
5614 mix = alc880_idx_to_mixer(alc880_dac_to_idx(dac));
5615 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
5616 nid = dac;
5617 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
5618 nid = mix;
5619 else
5620 nid = 0;
5621 if (nid)
5622 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5623 AMP_OUT_ZERO);
5624 if (query_amp_caps(codec, mix, HDA_INPUT) & AC_AMPCAP_MUTE) {
5625 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5626 AMP_IN_UNMUTE(0));
5627 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5628 AMP_IN_UNMUTE(1));
5629 }
1f0f4b80
TI
5630}
5631
e9edcee0
TI
5632static void alc880_auto_init_multi_out(struct hda_codec *codec)
5633{
5634 struct alc_spec *spec = codec->spec;
5635 int i;
ea1fb29a 5636
e9edcee0
TI
5637 for (i = 0; i < spec->autocfg.line_outs; i++) {
5638 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5639 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5640 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0 5641 }
1f0f4b80
TI
5642 /* mute DACs */
5643 for (i = 0; i < spec->multiout.num_dacs; i++)
5644 alc880_auto_init_dac(codec, spec->multiout.dac_nids[i]);
e9edcee0
TI
5645}
5646
8d88bc3d 5647static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5648{
5649 struct alc_spec *spec = codec->spec;
5650 hda_nid_t pin;
1f0f4b80 5651 int i;
e9edcee0 5652
82bc955f 5653 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5654 if (pin) /* connect to front */
5655 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5656 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5657 if (pin) /* connect to front */
5658 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
1f0f4b80
TI
5659 /* mute DACs */
5660 alc880_auto_init_dac(codec, spec->multiout.hp_nid);
5661 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
5662 alc880_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
e9edcee0
TI
5663}
5664
5665static void alc880_auto_init_analog_input(struct hda_codec *codec)
5666{
5667 struct alc_spec *spec = codec->spec;
66ceeb6b 5668 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5669 int i;
5670
66ceeb6b
TI
5671 for (i = 0; i < cfg->num_inputs; i++) {
5672 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5673 if (alc_is_input_pin(codec, nid)) {
30ea098f 5674 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
1f0f4b80 5675 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
f12ab1e0
TI
5676 snd_hda_codec_write(codec, nid, 0,
5677 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5678 AMP_OUT_MUTE);
5679 }
5680 }
1f0f4b80
TI
5681
5682 /* mute all loopback inputs */
5683 if (spec->mixer_nid) {
5684 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
5685 for (i = 0; i < nums; i++)
5686 snd_hda_codec_write(codec, spec->mixer_nid, 0,
5687 AC_VERB_SET_AMP_GAIN_MUTE,
5688 AMP_IN_MUTE(i));
5689 }
e9edcee0
TI
5690}
5691
7f311a46
TI
5692static void alc880_auto_init_input_src(struct hda_codec *codec)
5693{
5694 struct alc_spec *spec = codec->spec;
5695 int c;
5696
5697 for (c = 0; c < spec->num_adc_nids; c++) {
5698 unsigned int mux_idx;
5699 const struct hda_input_mux *imux;
5700 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5701 imux = &spec->input_mux[mux_idx];
5702 if (!imux->num_items && mux_idx > 0)
5703 imux = &spec->input_mux[0];
5704 if (imux)
5705 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5706 AC_VERB_SET_CONNECT_SEL,
5707 imux->items[0].index);
1f0f4b80
TI
5708 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5709 AC_VERB_SET_AMP_GAIN_MUTE,
5710 AMP_IN_MUTE(0));
7f311a46
TI
5711 }
5712}
5713
cb053a82
TI
5714static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
5715 int (*fill_dac)(struct hda_codec *));
ce764ab2 5716
e9edcee0 5717/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5718/* return 1 if successful, 0 if the proper config is not found,
5719 * or a negative error code
5720 */
e9edcee0
TI
5721static int alc880_parse_auto_config(struct hda_codec *codec)
5722{
5723 struct alc_spec *spec = codec->spec;
757899ac 5724 int err;
4c6d72d1 5725 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5726
f12ab1e0
TI
5727 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5728 alc880_ignore);
5729 if (err < 0)
e9edcee0 5730 return err;
f12ab1e0 5731 if (!spec->autocfg.line_outs)
e9edcee0 5732 return 0; /* can't find valid BIOS pin config */
df694daa 5733
cb053a82 5734 err = alc880_auto_fill_dac_nids(codec);
ce764ab2
TI
5735 if (err < 0)
5736 return err;
cb053a82 5737 err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
f12ab1e0
TI
5738 if (err < 0)
5739 return err;
5740 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5741 if (err < 0)
5742 return err;
5743 err = alc880_auto_create_extra_out(spec,
5744 spec->autocfg.speaker_pins[0],
5745 "Speaker");
5746 if (err < 0)
5747 return err;
5748 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5749 "Headphone");
5750 if (err < 0)
5751 return err;
05f5f477 5752 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5753 if (err < 0)
e9edcee0
TI
5754 return err;
5755
5756 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5757
757899ac 5758 alc_auto_parse_digital(codec);
e9edcee0 5759
603c4019 5760 if (spec->kctls.list)
d88897ea 5761 add_mixer(spec, spec->kctls.list);
e9edcee0 5762
a1e8d2da 5763 spec->num_mux_defs = 1;
61b9b9b1 5764 spec->input_mux = &spec->private_imux[0];
e9edcee0 5765
6227cdce 5766 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5767
e9edcee0
TI
5768 return 1;
5769}
5770
ae6b813a
TI
5771/* additional initialization for auto-configuration model */
5772static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5773{
f6c7e546 5774 struct alc_spec *spec = codec->spec;
e9edcee0 5775 alc880_auto_init_multi_out(codec);
8d88bc3d 5776 alc880_auto_init_extra_out(codec);
e9edcee0 5777 alc880_auto_init_analog_input(codec);
7f311a46 5778 alc880_auto_init_input_src(codec);
757899ac 5779 alc_auto_init_digital(codec);
f6c7e546 5780 if (spec->unsol_event)
7fb0d78f 5781 alc_inithook(codec);
e9edcee0
TI
5782}
5783
b59bdf3b
TI
5784/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5785 * one of two digital mic pins, e.g. on ALC272
5786 */
5787static void fixup_automic_adc(struct hda_codec *codec)
5788{
5789 struct alc_spec *spec = codec->spec;
5790 int i;
5791
5792 for (i = 0; i < spec->num_adc_nids; i++) {
5793 hda_nid_t cap = spec->capsrc_nids ?
5794 spec->capsrc_nids[i] : spec->adc_nids[i];
5795 int iidx, eidx;
5796
5797 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5798 if (iidx < 0)
5799 continue;
5800 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5801 if (eidx < 0)
5802 continue;
5803 spec->int_mic.mux_idx = iidx;
5804 spec->ext_mic.mux_idx = eidx;
5805 if (spec->capsrc_nids)
5806 spec->capsrc_nids += i;
5807 spec->adc_nids += i;
5808 spec->num_adc_nids = 1;
8ed99d97
TI
5809 /* optional dock-mic */
5810 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5811 if (eidx < 0)
5812 spec->dock_mic.pin = 0;
5813 else
5814 spec->dock_mic.mux_idx = eidx;
b59bdf3b
TI
5815 return;
5816 }
5817 snd_printd(KERN_INFO "hda_codec: %s: "
5818 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5819 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5820 spec->auto_mic = 0; /* disable auto-mic to be sure */
5821}
5822
748cce43
TI
5823/* select or unmute the given capsrc route */
5824static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5825 int idx)
5826{
5827 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5828 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5829 HDA_AMP_MUTE, 0);
5830 } else {
5831 snd_hda_codec_write_cache(codec, cap, 0,
5832 AC_VERB_SET_CONNECT_SEL, idx);
5833 }
5834}
5835
840b64c0
TI
5836/* set the default connection to that pin */
5837static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5838{
5839 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5840 int i;
5841
8ed99d97
TI
5842 if (!pin)
5843 return 0;
eaa9b3a7
TI
5844 for (i = 0; i < spec->num_adc_nids; i++) {
5845 hda_nid_t cap = spec->capsrc_nids ?
5846 spec->capsrc_nids[i] : spec->adc_nids[i];
5847 int idx;
5848
5849 idx = get_connection_index(codec, cap, pin);
5850 if (idx < 0)
5851 continue;
748cce43 5852 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5853 return i; /* return the found index */
5854 }
5855 return -1; /* not found */
5856}
5857
5858/* choose the ADC/MUX containing the input pin and initialize the setup */
5859static void fixup_single_adc(struct hda_codec *codec)
5860{
5861 struct alc_spec *spec = codec->spec;
66ceeb6b 5862 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5863 int i;
5864
5865 /* search for the input pin; there must be only one */
66ceeb6b 5866 if (cfg->num_inputs != 1)
eaa9b3a7 5867 return;
66ceeb6b 5868 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5869 if (i >= 0) {
5870 /* use only this ADC */
5871 if (spec->capsrc_nids)
5872 spec->capsrc_nids += i;
5873 spec->adc_nids += i;
5874 spec->num_adc_nids = 1;
584c0c4c 5875 spec->single_input_src = 1;
eaa9b3a7
TI
5876 }
5877}
5878
840b64c0
TI
5879/* initialize dual adcs */
5880static void fixup_dual_adc_switch(struct hda_codec *codec)
5881{
5882 struct alc_spec *spec = codec->spec;
5883 init_capsrc_for_pin(codec, spec->ext_mic.pin);
8ed99d97 5884 init_capsrc_for_pin(codec, spec->dock_mic.pin);
840b64c0
TI
5885 init_capsrc_for_pin(codec, spec->int_mic.pin);
5886}
5887
584c0c4c
TI
5888/* initialize some special cases for input sources */
5889static void alc_init_special_input_src(struct hda_codec *codec)
5890{
5891 struct alc_spec *spec = codec->spec;
5892 if (spec->dual_adc_switch)
5893 fixup_dual_adc_switch(codec);
5894 else if (spec->single_input_src)
5895 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5896}
5897
b59bdf3b 5898static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5899{
b59bdf3b 5900 struct alc_spec *spec = codec->spec;
a9111321 5901 static const struct snd_kcontrol_new *caps[2][3] = {
a23b688f
TI
5902 { alc_capture_mixer_nosrc1,
5903 alc_capture_mixer_nosrc2,
5904 alc_capture_mixer_nosrc3 },
5905 { alc_capture_mixer1,
5906 alc_capture_mixer2,
5907 alc_capture_mixer3 },
f9e336f6 5908 };
a23b688f 5909 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5910 int mux = 0;
840b64c0
TI
5911 int num_adcs = spec->num_adc_nids;
5912 if (spec->dual_adc_switch)
584c0c4c 5913 num_adcs = 1;
840b64c0 5914 else if (spec->auto_mic)
b59bdf3b 5915 fixup_automic_adc(codec);
eaa9b3a7
TI
5916 else if (spec->input_mux) {
5917 if (spec->input_mux->num_items > 1)
5918 mux = 1;
5919 else if (spec->input_mux->num_items == 1)
5920 fixup_single_adc(codec);
5921 }
840b64c0 5922 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5923 }
f9e336f6
TI
5924}
5925
6694635d 5926/* fill adc_nids (and capsrc_nids) containing all active input pins */
4c6d72d1 5927static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
6694635d
TI
5928 int num_nids)
5929{
5930 struct alc_spec *spec = codec->spec;
66ceeb6b 5931 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5932 int n;
5933 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5934
5935 for (n = 0; n < num_nids; n++) {
5936 hda_nid_t adc, cap;
5937 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5938 int nconns, i, j;
5939
5940 adc = nids[n];
5941 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5942 continue;
5943 cap = adc;
5944 nconns = snd_hda_get_connections(codec, cap, conn,
5945 ARRAY_SIZE(conn));
5946 if (nconns == 1) {
5947 cap = conn[0];
5948 nconns = snd_hda_get_connections(codec, cap, conn,
5949 ARRAY_SIZE(conn));
5950 }
5951 if (nconns <= 0)
5952 continue;
5953 if (!fallback_adc) {
5954 fallback_adc = adc;
5955 fallback_cap = cap;
5956 }
66ceeb6b
TI
5957 for (i = 0; i < cfg->num_inputs; i++) {
5958 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5959 for (j = 0; j < nconns; j++) {
5960 if (conn[j] == nid)
5961 break;
5962 }
5963 if (j >= nconns)
5964 break;
5965 }
66ceeb6b 5966 if (i >= cfg->num_inputs) {
6694635d
TI
5967 int num_adcs = spec->num_adc_nids;
5968 spec->private_adc_nids[num_adcs] = adc;
5969 spec->private_capsrc_nids[num_adcs] = cap;
5970 spec->num_adc_nids++;
5971 spec->adc_nids = spec->private_adc_nids;
5972 if (adc != cap)
5973 spec->capsrc_nids = spec->private_capsrc_nids;
5974 }
5975 }
5976 if (!spec->num_adc_nids) {
5977 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5978 " using fallback 0x%x\n",
5979 codec->chip_name, fallback_adc);
6694635d
TI
5980 spec->private_adc_nids[0] = fallback_adc;
5981 spec->adc_nids = spec->private_adc_nids;
5982 if (fallback_adc != fallback_cap) {
5983 spec->private_capsrc_nids[0] = fallback_cap;
5984 spec->capsrc_nids = spec->private_adc_nids;
5985 }
5986 }
5987}
5988
67d634c0 5989#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5990#define set_beep_amp(spec, nid, idx, dir) \
5991 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25 5992
a9111321 5993static const struct snd_pci_quirk beep_white_list[] = {
dc1eae25 5994 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5995 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
a7e985e1 5996 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
39dfe138 5997 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
e096c8e6 5998 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5999 {}
6000};
6001
6002static inline int has_cdefine_beep(struct hda_codec *codec)
6003{
6004 struct alc_spec *spec = codec->spec;
6005 const struct snd_pci_quirk *q;
6006 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
6007 if (q)
6008 return q->value;
6009 return spec->cdefine.enable_pcbeep;
6010}
67d634c0
TI
6011#else
6012#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 6013#define has_cdefine_beep(codec) 0
67d634c0 6014#endif
45bdd1c1
TI
6015
6016/*
6017 * OK, here we have finally the patch for ALC880
6018 */
6019
1da177e4
LT
6020static int patch_alc880(struct hda_codec *codec)
6021{
6022 struct alc_spec *spec;
6023 int board_config;
df694daa 6024 int err;
1da177e4 6025
e560d8d8 6026 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6027 if (spec == NULL)
6028 return -ENOMEM;
6029
6030 codec->spec = spec;
6031
1f0f4b80
TI
6032 spec->mixer_nid = 0x0b;
6033
f5fcc13c
TI
6034 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
6035 alc880_models,
6036 alc880_cfg_tbl);
6037 if (board_config < 0) {
9a11f1aa
TI
6038 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6039 codec->chip_name);
e9edcee0 6040 board_config = ALC880_AUTO;
1da177e4 6041 }
1da177e4 6042
e9edcee0
TI
6043 if (board_config == ALC880_AUTO) {
6044 /* automatic parse from the BIOS config */
6045 err = alc880_parse_auto_config(codec);
6046 if (err < 0) {
6047 alc_free(codec);
6048 return err;
f12ab1e0 6049 } else if (!err) {
9c7f852e
TI
6050 printk(KERN_INFO
6051 "hda_codec: Cannot set up configuration "
6052 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
6053 board_config = ALC880_3ST;
6054 }
1da177e4
LT
6055 }
6056
680cd536
KK
6057 err = snd_hda_attach_beep_device(codec, 0x1);
6058 if (err < 0) {
6059 alc_free(codec);
6060 return err;
6061 }
6062
df694daa 6063 if (board_config != ALC880_AUTO)
e9c364c0 6064 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 6065
1da177e4
LT
6066 spec->stream_analog_playback = &alc880_pcm_analog_playback;
6067 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 6068 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 6069
1da177e4
LT
6070 spec->stream_digital_playback = &alc880_pcm_digital_playback;
6071 spec->stream_digital_capture = &alc880_pcm_digital_capture;
6072
f12ab1e0 6073 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 6074 /* check whether NID 0x07 is valid */
54d17403 6075 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 6076 /* get type */
a22d543a 6077 wcap = get_wcaps_type(wcap);
e9edcee0
TI
6078 if (wcap != AC_WID_AUD_IN) {
6079 spec->adc_nids = alc880_adc_nids_alt;
6080 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
6081 } else {
6082 spec->adc_nids = alc880_adc_nids;
6083 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
6084 }
6085 }
b59bdf3b 6086 set_capture_mixer(codec);
45bdd1c1 6087 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 6088
2134ea4f
TI
6089 spec->vmaster_nid = 0x0c;
6090
1da177e4 6091 codec->patch_ops = alc_patch_ops;
e9edcee0 6092 if (board_config == ALC880_AUTO)
ae6b813a 6093 spec->init_hook = alc880_auto_init;
cb53c626
TI
6094#ifdef CONFIG_SND_HDA_POWER_SAVE
6095 if (!spec->loopback.amplist)
6096 spec->loopback.amplist = alc880_loopbacks;
6097#endif
1da177e4
LT
6098
6099 return 0;
6100}
6101
e9edcee0 6102
1da177e4
LT
6103/*
6104 * ALC260 support
6105 */
6106
4c6d72d1 6107static const hda_nid_t alc260_dac_nids[1] = {
e9edcee0
TI
6108 /* front */
6109 0x02,
6110};
6111
4c6d72d1 6112static const hda_nid_t alc260_adc_nids[1] = {
e9edcee0
TI
6113 /* ADC0 */
6114 0x04,
6115};
6116
4c6d72d1 6117static const hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
6118 /* ADC1 */
6119 0x05,
6120};
6121
d57fdac0
JW
6122/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6123 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6124 */
4c6d72d1 6125static const hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
6126 /* ADC0, ADC1 */
6127 0x04, 0x05
6128};
6129
e9edcee0
TI
6130#define ALC260_DIGOUT_NID 0x03
6131#define ALC260_DIGIN_NID 0x06
6132
a9111321 6133static const struct hda_input_mux alc260_capture_source = {
e9edcee0
TI
6134 .num_items = 4,
6135 .items = {
6136 { "Mic", 0x0 },
6137 { "Front Mic", 0x1 },
6138 { "Line", 0x2 },
6139 { "CD", 0x4 },
6140 },
6141};
6142
17e7aec6 6143/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
6144 * headphone jack and the internal CD lines since these are the only pins at
6145 * which audio can appear. For flexibility, also allow the option of
6146 * recording the mixer output on the second ADC (ADC0 doesn't have a
6147 * connection to the mixer output).
a9430dd8 6148 */
a9111321 6149static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
a1e8d2da
JW
6150 {
6151 .num_items = 3,
6152 .items = {
6153 { "Mic/Line", 0x0 },
6154 { "CD", 0x4 },
6155 { "Headphone", 0x2 },
6156 },
a9430dd8 6157 },
a1e8d2da
JW
6158 {
6159 .num_items = 4,
6160 .items = {
6161 { "Mic/Line", 0x0 },
6162 { "CD", 0x4 },
6163 { "Headphone", 0x2 },
6164 { "Mixer", 0x5 },
6165 },
6166 },
6167
a9430dd8
JW
6168};
6169
a1e8d2da
JW
6170/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6171 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 6172 */
a9111321 6173static const struct hda_input_mux alc260_acer_capture_sources[2] = {
a1e8d2da
JW
6174 {
6175 .num_items = 4,
6176 .items = {
6177 { "Mic", 0x0 },
6178 { "Line", 0x2 },
6179 { "CD", 0x4 },
6180 { "Headphone", 0x5 },
6181 },
6182 },
6183 {
6184 .num_items = 5,
6185 .items = {
6186 { "Mic", 0x0 },
6187 { "Line", 0x2 },
6188 { "CD", 0x4 },
6189 { "Headphone", 0x6 },
6190 { "Mixer", 0x5 },
6191 },
0bfc90e9
JW
6192 },
6193};
cc959489
MS
6194
6195/* Maxdata Favorit 100XS */
a9111321 6196static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
cc959489
MS
6197 {
6198 .num_items = 2,
6199 .items = {
6200 { "Line/Mic", 0x0 },
6201 { "CD", 0x4 },
6202 },
6203 },
6204 {
6205 .num_items = 3,
6206 .items = {
6207 { "Line/Mic", 0x0 },
6208 { "CD", 0x4 },
6209 { "Mixer", 0x5 },
6210 },
6211 },
6212};
6213
1da177e4
LT
6214/*
6215 * This is just place-holder, so there's something for alc_build_pcms to look
6216 * at when it calculates the maximum number of channels. ALC260 has no mixer
6217 * element which allows changing the channel mode, so the verb list is
6218 * never used.
6219 */
a9111321 6220static const struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
6221 { 2, NULL },
6222};
6223
df694daa
KY
6224
6225/* Mixer combinations
6226 *
6227 * basic: base_output + input + pc_beep + capture
6228 * HP: base_output + input + capture_alt
6229 * HP_3013: hp_3013 + input + capture
6230 * fujitsu: fujitsu + capture
0bfc90e9 6231 * acer: acer + capture
df694daa
KY
6232 */
6233
a9111321 6234static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 6235 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6236 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 6237 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 6238 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 6239 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 6240 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 6241 { } /* end */
f12ab1e0 6242};
1da177e4 6243
a9111321 6244static const struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
6245 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6246 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6247 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6248 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6250 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6251 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6252 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
6253 { } /* end */
6254};
6255
bec15c3a 6256/* update HP, line and mono out pins according to the master switch */
e9427969 6257static void alc260_hp_master_update(struct hda_codec *codec)
bec15c3a 6258{
e9427969 6259 update_speakers(codec);
bec15c3a
TI
6260}
6261
6262static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6263 struct snd_ctl_elem_value *ucontrol)
6264{
6265 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6266 struct alc_spec *spec = codec->spec;
e9427969 6267 *ucontrol->value.integer.value = !spec->master_mute;
bec15c3a
TI
6268 return 0;
6269}
6270
6271static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6272 struct snd_ctl_elem_value *ucontrol)
6273{
6274 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6275 struct alc_spec *spec = codec->spec;
e9427969 6276 int val = !*ucontrol->value.integer.value;
bec15c3a 6277
e9427969 6278 if (val == spec->master_mute)
bec15c3a 6279 return 0;
e9427969
TI
6280 spec->master_mute = val;
6281 alc260_hp_master_update(codec);
bec15c3a
TI
6282 return 1;
6283}
6284
a9111321 6285static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
bec15c3a
TI
6286 {
6287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6288 .name = "Master Playback Switch",
5b0cb1d8 6289 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6290 .info = snd_ctl_boolean_mono_info,
6291 .get = alc260_hp_master_sw_get,
6292 .put = alc260_hp_master_sw_put,
bec15c3a
TI
6293 },
6294 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6295 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6296 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6297 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6298 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6299 HDA_OUTPUT),
6300 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6301 { } /* end */
6302};
6303
a9111321 6304static const struct hda_verb alc260_hp_unsol_verbs[] = {
bec15c3a
TI
6305 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6306 {},
6307};
6308
e9427969 6309static void alc260_hp_setup(struct hda_codec *codec)
bec15c3a
TI
6310{
6311 struct alc_spec *spec = codec->spec;
bec15c3a 6312
e9427969
TI
6313 spec->autocfg.hp_pins[0] = 0x0f;
6314 spec->autocfg.speaker_pins[0] = 0x10;
6315 spec->autocfg.speaker_pins[1] = 0x11;
6316 spec->automute = 1;
6317 spec->automute_mode = ALC_AUTOMUTE_PIN;
bec15c3a
TI
6318}
6319
a9111321 6320static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6321 {
6322 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6323 .name = "Master Playback Switch",
5b0cb1d8 6324 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6325 .info = snd_ctl_boolean_mono_info,
6326 .get = alc260_hp_master_sw_get,
6327 .put = alc260_hp_master_sw_put,
bec15c3a 6328 },
df694daa
KY
6329 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6330 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6331 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6332 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6333 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6334 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6335 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6336 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6337 { } /* end */
6338};
6339
e9427969
TI
6340static void alc260_hp_3013_setup(struct hda_codec *codec)
6341{
6342 struct alc_spec *spec = codec->spec;
6343
6344 spec->autocfg.hp_pins[0] = 0x15;
6345 spec->autocfg.speaker_pins[0] = 0x10;
6346 spec->autocfg.speaker_pins[1] = 0x11;
6347 spec->automute = 1;
6348 spec->automute_mode = ALC_AUTOMUTE_PIN;
6349}
6350
a9111321 6351static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
3f878308
KY
6352 .ops = &snd_hda_bind_vol,
6353 .values = {
6354 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6355 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6356 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6357 0
6358 },
6359};
6360
a9111321 6361static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
3f878308
KY
6362 .ops = &snd_hda_bind_sw,
6363 .values = {
6364 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6365 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6366 0
6367 },
6368};
6369
a9111321 6370static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
3f878308
KY
6371 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6372 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6373 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6374 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6375 { } /* end */
6376};
6377
a9111321 6378static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
bec15c3a
TI
6379 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6380 {},
6381};
6382
e9427969 6383static void alc260_hp_3012_setup(struct hda_codec *codec)
bec15c3a
TI
6384{
6385 struct alc_spec *spec = codec->spec;
bec15c3a 6386
e9427969
TI
6387 spec->autocfg.hp_pins[0] = 0x10;
6388 spec->autocfg.speaker_pins[0] = 0x0f;
6389 spec->autocfg.speaker_pins[1] = 0x11;
6390 spec->autocfg.speaker_pins[2] = 0x15;
6391 spec->automute = 1;
6392 spec->automute_mode = ALC_AUTOMUTE_PIN;
3f878308
KY
6393}
6394
6395/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6396 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6397 */
a9111321 6398static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6399 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6400 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6401 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6402 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6403 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6404 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6405 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6406 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6407 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6408 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6409 { } /* end */
6410};
6411
a1e8d2da
JW
6412/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6413 * versions of the ALC260 don't act on requests to enable mic bias from NID
6414 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6415 * datasheet doesn't mention this restriction. At this stage it's not clear
6416 * whether this behaviour is intentional or is a hardware bug in chip
6417 * revisions available in early 2006. Therefore for now allow the
6418 * "Headphone Jack Mode" control to span all choices, but if it turns out
6419 * that the lack of mic bias for this NID is intentional we could change the
6420 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6421 *
6422 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6423 * don't appear to make the mic bias available from the "line" jack, even
6424 * though the NID used for this jack (0x14) can supply it. The theory is
6425 * that perhaps Acer have included blocking capacitors between the ALC260
6426 * and the output jack. If this turns out to be the case for all such
6427 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6428 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6429 *
6430 * The C20x Tablet series have a mono internal speaker which is controlled
6431 * via the chip's Mono sum widget and pin complex, so include the necessary
6432 * controls for such models. On models without a "mono speaker" the control
6433 * won't do anything.
a1e8d2da 6434 */
a9111321 6435static const struct snd_kcontrol_new alc260_acer_mixer[] = {
0bfc90e9
JW
6436 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6437 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6438 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6439 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6440 HDA_OUTPUT),
31bffaa9 6441 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6442 HDA_INPUT),
0bfc90e9
JW
6443 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6444 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6446 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6447 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6448 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6449 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6450 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6451 { } /* end */
6452};
6453
cc959489
MS
6454/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6455 */
a9111321 6456static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
cc959489
MS
6457 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6458 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6459 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6460 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6461 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6462 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6463 { } /* end */
6464};
6465
bc9f98a9
KY
6466/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6467 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6468 */
a9111321 6469static const struct snd_kcontrol_new alc260_will_mixer[] = {
bc9f98a9
KY
6470 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6471 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6473 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6474 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6475 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6476 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6477 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6478 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6479 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6480 { } /* end */
6481};
6482
6483/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6484 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6485 */
a9111321 6486static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
bc9f98a9
KY
6487 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6488 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6489 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6490 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6491 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6492 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6493 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6494 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6495 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6496 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6497 { } /* end */
6498};
6499
df694daa
KY
6500/*
6501 * initialization verbs
6502 */
a9111321 6503static const struct hda_verb alc260_init_verbs[] = {
1da177e4 6504 /* Line In pin widget for input */
05acb863 6505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6506 /* CD pin widget for input */
05acb863 6507 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6508 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6509 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6510 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6511 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6512 /* LINE-2 is used for line-out in rear */
05acb863 6513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6514 /* select line-out */
fd56f2db 6515 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6516 /* LINE-OUT pin */
05acb863 6517 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6518 /* enable HP */
05acb863 6519 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6520 /* enable Mono */
05acb863
TI
6521 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6522 /* mute capture amp left and right */
16ded525 6523 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6524 /* set connection select to line in (default select for this ADC) */
6525 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6526 /* mute capture amp left and right */
6527 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6528 /* set connection select to line in (default select for this ADC) */
6529 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6530 /* set vol=0 Line-Out mixer amp left and right */
6531 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6532 /* unmute pin widget amp left and right (no gain on this amp) */
6533 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6534 /* set vol=0 HP mixer amp left and right */
6535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6536 /* unmute pin widget amp left and right (no gain on this amp) */
6537 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6538 /* set vol=0 Mono mixer amp left and right */
6539 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6540 /* unmute pin widget amp left and right (no gain on this amp) */
6541 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6542 /* unmute LINE-2 out pin */
6543 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6544 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6545 * Line In 2 = 0x03
6546 */
cb53c626
TI
6547 /* mute analog inputs */
6548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6553 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6554 /* mute Front out path */
6555 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6557 /* mute Headphone out path */
6558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6560 /* mute Mono out path */
6561 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6562 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6563 { }
6564};
6565
474167d6 6566#if 0 /* should be identical with alc260_init_verbs? */
a9111321 6567static const struct hda_verb alc260_hp_init_verbs[] = {
df694daa
KY
6568 /* Headphone and output */
6569 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6570 /* mono output */
6571 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6572 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6573 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6574 /* Mic2 (front panel) pin widget for input and vref at 80% */
6575 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6576 /* Line In pin widget for input */
6577 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6578 /* Line-2 pin widget for output */
6579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6580 /* CD pin widget for input */
6581 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6582 /* unmute amp left and right */
6583 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6584 /* set connection select to line in (default select for this ADC) */
6585 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6586 /* unmute Line-Out mixer amp left and right (volume = 0) */
6587 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6588 /* mute pin widget amp left and right (no gain on this amp) */
6589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6590 /* unmute HP mixer amp left and right (volume = 0) */
6591 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6592 /* mute pin widget amp left and right (no gain on this amp) */
6593 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6594 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6595 * Line In 2 = 0x03
6596 */
cb53c626
TI
6597 /* mute analog inputs */
6598 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6603 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6604 /* Unmute Front out path */
6605 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6607 /* Unmute Headphone out path */
6608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6610 /* Unmute Mono out path */
6611 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6612 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6613 { }
6614};
474167d6 6615#endif
df694daa 6616
a9111321 6617static const struct hda_verb alc260_hp_3013_init_verbs[] = {
df694daa
KY
6618 /* Line out and output */
6619 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6620 /* mono output */
6621 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6622 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6623 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6624 /* Mic2 (front panel) pin widget for input and vref at 80% */
6625 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6626 /* Line In pin widget for input */
6627 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6628 /* Headphone pin widget for output */
6629 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6630 /* CD pin widget for input */
6631 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6632 /* unmute amp left and right */
6633 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6634 /* set connection select to line in (default select for this ADC) */
6635 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6636 /* unmute Line-Out mixer amp left and right (volume = 0) */
6637 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6638 /* mute pin widget amp left and right (no gain on this amp) */
6639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6640 /* unmute HP mixer amp left and right (volume = 0) */
6641 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6642 /* mute pin widget amp left and right (no gain on this amp) */
6643 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6644 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6645 * Line In 2 = 0x03
6646 */
cb53c626
TI
6647 /* mute analog inputs */
6648 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6649 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6650 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6651 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6652 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6653 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6654 /* Unmute Front out path */
6655 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6657 /* Unmute Headphone out path */
6658 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6659 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6660 /* Unmute Mono out path */
6661 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6662 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6663 { }
6664};
6665
a9430dd8 6666/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6667 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6668 * audio = 0x16, internal speaker = 0x10.
a9430dd8 6669 */
a9111321 6670static const struct hda_verb alc260_fujitsu_init_verbs[] = {
a9430dd8
JW
6671 /* Disable all GPIOs */
6672 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6673 /* Internal speaker is connected to headphone pin */
6674 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6675 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6677 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6678 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6679 /* Ensure all other unused pins are disabled and muted. */
6680 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6681 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6682 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6683 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6684 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6685 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6686 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6688
6689 /* Disable digital (SPDIF) pins */
6690 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6691 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6692
ea1fb29a 6693 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6694 * when acting as an output.
6695 */
6696 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6697
f7ace40d 6698 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6699 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6700 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6701 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6703 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6704 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6705 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6706 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6707 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6708
f7ace40d
JW
6709 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6710 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6711 /* Unmute Line1 pin widget output buffer since it starts as an output.
6712 * If the pin mode is changed by the user the pin mode control will
6713 * take care of enabling the pin's input/output buffers as needed.
6714 * Therefore there's no need to enable the input buffer at this
6715 * stage.
cdcd9268 6716 */
f7ace40d 6717 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6718 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6719 * mixer ctrl)
6720 */
f7ace40d
JW
6721 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6722
6723 /* Mute capture amp left and right */
6724 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6725 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6726 * in (on mic1 pin)
6727 */
6728 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6729
6730 /* Do the same for the second ADC: mute capture input amp and
6731 * set ADC connection to line in (on mic1 pin)
6732 */
6733 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6734 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6735
6736 /* Mute all inputs to mixer widget (even unconnected ones) */
6737 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6739 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6740 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6741 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6745
6746 { }
a9430dd8
JW
6747};
6748
0bfc90e9
JW
6749/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6750 * similar laptops (adapted from Fujitsu init verbs).
6751 */
a9111321 6752static const struct hda_verb alc260_acer_init_verbs[] = {
0bfc90e9
JW
6753 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6754 * the headphone jack. Turn this on and rely on the standard mute
6755 * methods whenever the user wants to turn these outputs off.
6756 */
6757 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6758 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6759 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6760 /* Internal speaker/Headphone jack is connected to Line-out pin */
6761 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6762 /* Internal microphone/Mic jack is connected to Mic1 pin */
6763 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6764 /* Line In jack is connected to Line1 pin */
6765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6766 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6767 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6768 /* Ensure all other unused pins are disabled and muted. */
6769 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6770 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6771 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6772 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6773 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6774 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6775 /* Disable digital (SPDIF) pins */
6776 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6777 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6778
ea1fb29a 6779 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6780 * bus when acting as outputs.
6781 */
6782 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6783 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6784
6785 /* Start with output sum widgets muted and their output gains at min */
6786 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6789 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6792 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6793 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6794 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6795
f12ab1e0
TI
6796 /* Unmute Line-out pin widget amp left and right
6797 * (no equiv mixer ctrl)
6798 */
0bfc90e9 6799 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6800 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6801 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6802 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6803 * inputs. If the pin mode is changed by the user the pin mode control
6804 * will take care of enabling the pin's input/output buffers as needed.
6805 * Therefore there's no need to enable the input buffer at this
6806 * stage.
6807 */
6808 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6809 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6810
6811 /* Mute capture amp left and right */
6812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6813 /* Set ADC connection select to match default mixer setting - mic
6814 * (on mic1 pin)
6815 */
6816 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6817
6818 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6819 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6820 */
6821 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6822 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6823
6824 /* Mute all inputs to mixer widget (even unconnected ones) */
6825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6833
6834 { }
6835};
6836
cc959489
MS
6837/* Initialisation sequence for Maxdata Favorit 100XS
6838 * (adapted from Acer init verbs).
6839 */
a9111321 6840static const struct hda_verb alc260_favorit100_init_verbs[] = {
cc959489
MS
6841 /* GPIO 0 enables the output jack.
6842 * Turn this on and rely on the standard mute
6843 * methods whenever the user wants to turn these outputs off.
6844 */
6845 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6846 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6847 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6848 /* Line/Mic input jack is connected to Mic1 pin */
6849 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6850 /* Ensure all other unused pins are disabled and muted. */
6851 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6852 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6853 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6854 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6855 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6856 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6857 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6858 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6859 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6861 /* Disable digital (SPDIF) pins */
6862 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6863 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6864
6865 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6866 * bus when acting as outputs.
6867 */
6868 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6869 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6870
6871 /* Start with output sum widgets muted and their output gains at min */
6872 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6873 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6874 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6875 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6876 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6877 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6878 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6879 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6880 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6881
6882 /* Unmute Line-out pin widget amp left and right
6883 * (no equiv mixer ctrl)
6884 */
6885 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6886 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6887 * inputs. If the pin mode is changed by the user the pin mode control
6888 * will take care of enabling the pin's input/output buffers as needed.
6889 * Therefore there's no need to enable the input buffer at this
6890 * stage.
6891 */
6892 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6893
6894 /* Mute capture amp left and right */
6895 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6896 /* Set ADC connection select to match default mixer setting - mic
6897 * (on mic1 pin)
6898 */
6899 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6900
6901 /* Do similar with the second ADC: mute capture input amp and
6902 * set ADC connection to mic to match ALSA's default state.
6903 */
6904 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6905 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6906
6907 /* Mute all inputs to mixer widget (even unconnected ones) */
6908 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6914 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6915 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6916
6917 { }
6918};
6919
a9111321 6920static const struct hda_verb alc260_will_verbs[] = {
bc9f98a9
KY
6921 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6922 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6923 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6924 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6925 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6926 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6927 {}
6928};
6929
a9111321 6930static const struct hda_verb alc260_replacer_672v_verbs[] = {
bc9f98a9
KY
6931 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6932 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6933 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6934
6935 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6936 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6937 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6938
6939 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6940 {}
6941};
6942
6943/* toggle speaker-output according to the hp-jack state */
6944static void alc260_replacer_672v_automute(struct hda_codec *codec)
6945{
6946 unsigned int present;
6947
6948 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6949 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6950 if (present) {
82beb8fd
TI
6951 snd_hda_codec_write_cache(codec, 0x01, 0,
6952 AC_VERB_SET_GPIO_DATA, 1);
6953 snd_hda_codec_write_cache(codec, 0x0f, 0,
6954 AC_VERB_SET_PIN_WIDGET_CONTROL,
6955 PIN_HP);
bc9f98a9 6956 } else {
82beb8fd
TI
6957 snd_hda_codec_write_cache(codec, 0x01, 0,
6958 AC_VERB_SET_GPIO_DATA, 0);
6959 snd_hda_codec_write_cache(codec, 0x0f, 0,
6960 AC_VERB_SET_PIN_WIDGET_CONTROL,
6961 PIN_OUT);
bc9f98a9
KY
6962 }
6963}
6964
6965static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6966 unsigned int res)
6967{
6968 if ((res >> 26) == ALC880_HP_EVENT)
6969 alc260_replacer_672v_automute(codec);
6970}
6971
a9111321 6972static const struct hda_verb alc260_hp_dc7600_verbs[] = {
3f878308
KY
6973 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6974 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6975 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6976 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6977 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6979 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6980 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6981 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6982 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6983 {}
6984};
6985
7cf51e48
JW
6986/* Test configuration for debugging, modelled after the ALC880 test
6987 * configuration.
6988 */
6989#ifdef CONFIG_SND_DEBUG
4c6d72d1 6990static const hda_nid_t alc260_test_dac_nids[1] = {
7cf51e48
JW
6991 0x02,
6992};
4c6d72d1 6993static const hda_nid_t alc260_test_adc_nids[2] = {
7cf51e48
JW
6994 0x04, 0x05,
6995};
a1e8d2da 6996/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6997 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6998 * is NID 0x04.
17e7aec6 6999 */
a9111321 7000static const struct hda_input_mux alc260_test_capture_sources[2] = {
a1e8d2da
JW
7001 {
7002 .num_items = 7,
7003 .items = {
7004 { "MIC1 pin", 0x0 },
7005 { "MIC2 pin", 0x1 },
7006 { "LINE1 pin", 0x2 },
7007 { "LINE2 pin", 0x3 },
7008 { "CD pin", 0x4 },
7009 { "LINE-OUT pin", 0x5 },
7010 { "HP-OUT pin", 0x6 },
7011 },
7012 },
7013 {
7014 .num_items = 8,
7015 .items = {
7016 { "MIC1 pin", 0x0 },
7017 { "MIC2 pin", 0x1 },
7018 { "LINE1 pin", 0x2 },
7019 { "LINE2 pin", 0x3 },
7020 { "CD pin", 0x4 },
7021 { "Mixer", 0x5 },
7022 { "LINE-OUT pin", 0x6 },
7023 { "HP-OUT pin", 0x7 },
7024 },
7cf51e48
JW
7025 },
7026};
a9111321 7027static const struct snd_kcontrol_new alc260_test_mixer[] = {
7cf51e48
JW
7028 /* Output driver widgets */
7029 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
7030 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
7031 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
7032 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
7033 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
7034 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
7035
a1e8d2da
JW
7036 /* Modes for retasking pin widgets
7037 * Note: the ALC260 doesn't seem to act on requests to enable mic
7038 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
7039 * mention this restriction. At this stage it's not clear whether
7040 * this behaviour is intentional or is a hardware bug in chip
7041 * revisions available at least up until early 2006. Therefore for
7042 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
7043 * choices, but if it turns out that the lack of mic bias for these
7044 * NIDs is intentional we could change their modes from
7045 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
7046 */
7cf51e48
JW
7047 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
7048 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
7049 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7050 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7051 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7052 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7053
7054 /* Loopback mixer controls */
7055 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7056 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7057 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7058 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7059 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7060 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7061 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7062 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7063 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7064 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
7065 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7066 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7067 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7068 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
7069
7070 /* Controls for GPIO pins, assuming they are configured as outputs */
7071 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7072 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7073 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7074 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7075
92621f13
JW
7076 /* Switches to allow the digital IO pins to be enabled. The datasheet
7077 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 7078 * make this output available should provide clarification.
92621f13
JW
7079 */
7080 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7081 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7082
f8225f6d
JW
7083 /* A switch allowing EAPD to be enabled. Some laptops seem to use
7084 * this output to turn on an external amplifier.
7085 */
7086 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7087 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7088
7cf51e48
JW
7089 { } /* end */
7090};
a9111321 7091static const struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
7092 /* Enable all GPIOs as outputs with an initial value of 0 */
7093 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7094 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7095 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7096
7cf51e48
JW
7097 /* Enable retasking pins as output, initially without power amp */
7098 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7099 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7101 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7102 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7103 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7104
92621f13
JW
7105 /* Disable digital (SPDIF) pins initially, but users can enable
7106 * them via a mixer switch. In the case of SPDIF-out, this initverb
7107 * payload also sets the generation to 0, output to be in "consumer"
7108 * PCM format, copyright asserted, no pre-emphasis and no validity
7109 * control.
7110 */
7cf51e48
JW
7111 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7112 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7113
ea1fb29a 7114 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
7115 * OUT1 sum bus when acting as an output.
7116 */
7117 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7118 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7119 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7120 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7121
7122 /* Start with output sum widgets muted and their output gains at min */
7123 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7124 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7125 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7128 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7129 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7130 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7131 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7132
cdcd9268
JW
7133 /* Unmute retasking pin widget output buffers since the default
7134 * state appears to be output. As the pin mode is changed by the
7135 * user the pin mode control will take care of enabling the pin's
7136 * input/output buffers as needed.
7137 */
7cf51e48
JW
7138 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7139 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7140 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7142 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7143 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7144 /* Also unmute the mono-out pin widget */
7145 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7146
7cf51e48
JW
7147 /* Mute capture amp left and right */
7148 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
7149 /* Set ADC connection select to match default mixer setting (mic1
7150 * pin)
7cf51e48
JW
7151 */
7152 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7153
7154 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 7155 * set ADC connection to mic1 pin
7cf51e48
JW
7156 */
7157 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7158 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7159
7160 /* Mute all inputs to mixer widget (even unconnected ones) */
7161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7162 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7163 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7164 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7168 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7169
7170 { }
7171};
7172#endif
7173
6330079f
TI
7174#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7175#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 7176
a3bcba38
TI
7177#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7178#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7179
df694daa
KY
7180/*
7181 * for BIOS auto-configuration
7182 */
16ded525 7183
6d86b4fb
TI
7184/* convert from pin to volume-mixer widget */
7185static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid)
7186{
7187 if (nid >= 0x0f && nid <= 0x11)
7188 return nid - 0x7;
7189 else if (nid >= 0x12 && nid <= 0x15)
7190 return 0x08;
7191 else
7192 return 0;
7193}
7194
df694daa 7195static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 7196 const char *pfx, int *vol_bits)
df694daa
KY
7197{
7198 hda_nid_t nid_vol;
7199 unsigned long vol_val, sw_val;
6d86b4fb 7200 int chs, err;
df694daa 7201
6d86b4fb
TI
7202 nid_vol = alc260_pin_to_vol_mix(nid);
7203 if (!nid_vol)
df694daa 7204 return 0; /* N/A */
6d86b4fb
TI
7205 if (nid == 0x11)
7206 chs = 2;
7207 else
7208 chs = 3;
7209 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, chs, 0, HDA_OUTPUT);
7210 sw_val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
ea1fb29a 7211
863b4518
TI
7212 if (!(*vol_bits & (1 << nid_vol))) {
7213 /* first control for the volume widget */
0afe5f89 7214 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
7215 if (err < 0)
7216 return err;
7217 *vol_bits |= (1 << nid_vol);
7218 }
0afe5f89 7219 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 7220 if (err < 0)
df694daa
KY
7221 return err;
7222 return 1;
7223}
7224
7225/* add playback controls from the parsed DAC table */
7226static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7227 const struct auto_pin_cfg *cfg)
7228{
7229 hda_nid_t nid;
7230 int err;
863b4518 7231 int vols = 0;
df694daa
KY
7232
7233 spec->multiout.num_dacs = 1;
7234 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 7235 spec->private_dac_nids[0] = 0x02;
df694daa
KY
7236
7237 nid = cfg->line_out_pins[0];
7238 if (nid) {
23112d6d 7239 const char *pfx;
2e925dde
TI
7240 int index;
7241 pfx = alc_get_line_out_pfx(spec, 0, true, &index);
23112d6d 7242 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
7243 if (err < 0)
7244 return err;
7245 }
7246
82bc955f 7247 nid = cfg->speaker_pins[0];
df694daa 7248 if (nid) {
863b4518 7249 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
7250 if (err < 0)
7251 return err;
7252 }
7253
eb06ed8f 7254 nid = cfg->hp_pins[0];
df694daa 7255 if (nid) {
863b4518
TI
7256 err = alc260_add_playback_controls(spec, nid, "Headphone",
7257 &vols);
df694daa
KY
7258 if (err < 0)
7259 return err;
7260 }
f12ab1e0 7261 return 0;
df694daa
KY
7262}
7263
7264/* create playback/capture controls for input pins */
05f5f477 7265static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
7266 const struct auto_pin_cfg *cfg)
7267{
05f5f477 7268 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
7269}
7270
7271static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7272 hda_nid_t nid, int pin_type,
7273 int sel_idx)
7274{
6d86b4fb
TI
7275 hda_nid_t mix;
7276
f6c7e546 7277 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7278 /* need the manual connection? */
7279 if (nid >= 0x12) {
7280 int idx = nid - 0x12;
7281 snd_hda_codec_write(codec, idx + 0x0b, 0,
7282 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa 7283 }
df694daa 7284
6d86b4fb
TI
7285 mix = alc260_pin_to_vol_mix(nid);
7286 if (!mix)
1f0f4b80 7287 return;
6d86b4fb 7288 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1f0f4b80 7289 AMP_OUT_ZERO);
6d86b4fb
TI
7290 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7291 AMP_IN_UNMUTE(0));
7292 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7293 AMP_IN_UNMUTE(1));
1f0f4b80
TI
7294}
7295
df694daa
KY
7296static void alc260_auto_init_multi_out(struct hda_codec *codec)
7297{
7298 struct alc_spec *spec = codec->spec;
7299 hda_nid_t nid;
7300
f12ab1e0 7301 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7302 if (nid) {
7303 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7304 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7305 }
ea1fb29a 7306
82bc955f 7307 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7308 if (nid)
7309 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7310
eb06ed8f 7311 nid = spec->autocfg.hp_pins[0];
df694daa 7312 if (nid)
baba8ee9 7313 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
df694daa
KY
7314}
7315
1f0f4b80 7316#define alc260_auto_init_analog_input alc880_auto_init_analog_input
7f311a46
TI
7317#define alc260_auto_init_input_src alc880_auto_init_input_src
7318
df694daa
KY
7319static int alc260_parse_auto_config(struct hda_codec *codec)
7320{
7321 struct alc_spec *spec = codec->spec;
df694daa 7322 int err;
4c6d72d1 7323 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
df694daa 7324
f12ab1e0
TI
7325 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7326 alc260_ignore);
7327 if (err < 0)
df694daa 7328 return err;
f12ab1e0
TI
7329 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7330 if (err < 0)
4a471b7d 7331 return err;
603c4019 7332 if (!spec->kctls.list)
df694daa 7333 return 0; /* can't find valid BIOS pin config */
05f5f477 7334 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7335 if (err < 0)
df694daa
KY
7336 return err;
7337
7338 spec->multiout.max_channels = 2;
7339
0852d7a6 7340 if (spec->autocfg.dig_outs)
df694daa 7341 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7342 if (spec->kctls.list)
d88897ea 7343 add_mixer(spec, spec->kctls.list);
df694daa 7344
a1e8d2da 7345 spec->num_mux_defs = 1;
61b9b9b1 7346 spec->input_mux = &spec->private_imux[0];
df694daa 7347
6227cdce 7348 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7349
df694daa
KY
7350 return 1;
7351}
7352
ae6b813a
TI
7353/* additional initialization for auto-configuration model */
7354static void alc260_auto_init(struct hda_codec *codec)
df694daa 7355{
f6c7e546 7356 struct alc_spec *spec = codec->spec;
df694daa
KY
7357 alc260_auto_init_multi_out(codec);
7358 alc260_auto_init_analog_input(codec);
7f311a46 7359 alc260_auto_init_input_src(codec);
757899ac 7360 alc_auto_init_digital(codec);
f6c7e546 7361 if (spec->unsol_event)
7fb0d78f 7362 alc_inithook(codec);
df694daa
KY
7363}
7364
cb53c626 7365#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 7366static const struct hda_amp_list alc260_loopbacks[] = {
cb53c626
TI
7367 { 0x07, HDA_INPUT, 0 },
7368 { 0x07, HDA_INPUT, 1 },
7369 { 0x07, HDA_INPUT, 2 },
7370 { 0x07, HDA_INPUT, 3 },
7371 { 0x07, HDA_INPUT, 4 },
7372 { } /* end */
7373};
7374#endif
7375
fc091769
TI
7376/*
7377 * Pin config fixes
7378 */
7379enum {
7380 PINFIX_HP_DC5750,
7381};
7382
fc091769
TI
7383static const struct alc_fixup alc260_fixups[] = {
7384 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7385 .type = ALC_FIXUP_PINS,
7386 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7387 { 0x11, 0x90130110 }, /* speaker */
7388 { }
7389 }
fc091769
TI
7390 },
7391};
7392
a9111321 7393static const struct snd_pci_quirk alc260_fixup_tbl[] = {
fc091769
TI
7394 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7395 {}
7396};
7397
df694daa
KY
7398/*
7399 * ALC260 configurations
7400 */
ea734963 7401static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7402 [ALC260_BASIC] = "basic",
7403 [ALC260_HP] = "hp",
7404 [ALC260_HP_3013] = "hp-3013",
2922c9af 7405 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7406 [ALC260_FUJITSU_S702X] = "fujitsu",
7407 [ALC260_ACER] = "acer",
bc9f98a9
KY
7408 [ALC260_WILL] = "will",
7409 [ALC260_REPLACER_672V] = "replacer",
cc959489 7410 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7411#ifdef CONFIG_SND_DEBUG
f5fcc13c 7412 [ALC260_TEST] = "test",
7cf51e48 7413#endif
f5fcc13c
TI
7414 [ALC260_AUTO] = "auto",
7415};
7416
a9111321 7417static const struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7418 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7419 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7420 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7421 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7422 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7423 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7424 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7425 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7426 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7427 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7428 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7429 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7430 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7431 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7432 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7433 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7434 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7435 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7436 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7437 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7438 {}
7439};
7440
a9111321 7441static const struct alc_config_preset alc260_presets[] = {
df694daa
KY
7442 [ALC260_BASIC] = {
7443 .mixers = { alc260_base_output_mixer,
45bdd1c1 7444 alc260_input_mixer },
df694daa
KY
7445 .init_verbs = { alc260_init_verbs },
7446 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7447 .dac_nids = alc260_dac_nids,
f9e336f6 7448 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7449 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7450 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7451 .channel_mode = alc260_modes,
7452 .input_mux = &alc260_capture_source,
7453 },
7454 [ALC260_HP] = {
bec15c3a 7455 .mixers = { alc260_hp_output_mixer,
f9e336f6 7456 alc260_input_mixer },
bec15c3a
TI
7457 .init_verbs = { alc260_init_verbs,
7458 alc260_hp_unsol_verbs },
df694daa
KY
7459 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7460 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7461 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7462 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7463 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7464 .channel_mode = alc260_modes,
7465 .input_mux = &alc260_capture_source,
e9427969
TI
7466 .unsol_event = alc_sku_unsol_event,
7467 .setup = alc260_hp_setup,
7468 .init_hook = alc_inithook,
df694daa 7469 },
3f878308
KY
7470 [ALC260_HP_DC7600] = {
7471 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7472 alc260_input_mixer },
3f878308
KY
7473 .init_verbs = { alc260_init_verbs,
7474 alc260_hp_dc7600_verbs },
7475 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7476 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7477 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7478 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7479 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7480 .channel_mode = alc260_modes,
7481 .input_mux = &alc260_capture_source,
e9427969
TI
7482 .unsol_event = alc_sku_unsol_event,
7483 .setup = alc260_hp_3012_setup,
7484 .init_hook = alc_inithook,
3f878308 7485 },
df694daa
KY
7486 [ALC260_HP_3013] = {
7487 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7488 alc260_input_mixer },
bec15c3a
TI
7489 .init_verbs = { alc260_hp_3013_init_verbs,
7490 alc260_hp_3013_unsol_verbs },
df694daa
KY
7491 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7492 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7493 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7494 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7495 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7496 .channel_mode = alc260_modes,
7497 .input_mux = &alc260_capture_source,
e9427969
TI
7498 .unsol_event = alc_sku_unsol_event,
7499 .setup = alc260_hp_3013_setup,
7500 .init_hook = alc_inithook,
df694daa
KY
7501 },
7502 [ALC260_FUJITSU_S702X] = {
f9e336f6 7503 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7504 .init_verbs = { alc260_fujitsu_init_verbs },
7505 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7506 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7507 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7508 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7509 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7510 .channel_mode = alc260_modes,
a1e8d2da
JW
7511 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7512 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7513 },
0bfc90e9 7514 [ALC260_ACER] = {
f9e336f6 7515 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7516 .init_verbs = { alc260_acer_init_verbs },
7517 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7518 .dac_nids = alc260_dac_nids,
7519 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7520 .adc_nids = alc260_dual_adc_nids,
7521 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7522 .channel_mode = alc260_modes,
a1e8d2da
JW
7523 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7524 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7525 },
cc959489
MS
7526 [ALC260_FAVORIT100] = {
7527 .mixers = { alc260_favorit100_mixer },
7528 .init_verbs = { alc260_favorit100_init_verbs },
7529 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7530 .dac_nids = alc260_dac_nids,
7531 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7532 .adc_nids = alc260_dual_adc_nids,
7533 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7534 .channel_mode = alc260_modes,
7535 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7536 .input_mux = alc260_favorit100_capture_sources,
7537 },
bc9f98a9 7538 [ALC260_WILL] = {
f9e336f6 7539 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7540 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7541 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7542 .dac_nids = alc260_dac_nids,
7543 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7544 .adc_nids = alc260_adc_nids,
7545 .dig_out_nid = ALC260_DIGOUT_NID,
7546 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7547 .channel_mode = alc260_modes,
7548 .input_mux = &alc260_capture_source,
7549 },
7550 [ALC260_REPLACER_672V] = {
f9e336f6 7551 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7552 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7553 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7554 .dac_nids = alc260_dac_nids,
7555 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7556 .adc_nids = alc260_adc_nids,
7557 .dig_out_nid = ALC260_DIGOUT_NID,
7558 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7559 .channel_mode = alc260_modes,
7560 .input_mux = &alc260_capture_source,
7561 .unsol_event = alc260_replacer_672v_unsol_event,
7562 .init_hook = alc260_replacer_672v_automute,
7563 },
7cf51e48
JW
7564#ifdef CONFIG_SND_DEBUG
7565 [ALC260_TEST] = {
f9e336f6 7566 .mixers = { alc260_test_mixer },
7cf51e48
JW
7567 .init_verbs = { alc260_test_init_verbs },
7568 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7569 .dac_nids = alc260_test_dac_nids,
7570 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7571 .adc_nids = alc260_test_adc_nids,
7572 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7573 .channel_mode = alc260_modes,
a1e8d2da
JW
7574 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7575 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7576 },
7577#endif
df694daa
KY
7578};
7579
7580static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7581{
7582 struct alc_spec *spec;
df694daa 7583 int err, board_config;
1da177e4 7584
e560d8d8 7585 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7586 if (spec == NULL)
7587 return -ENOMEM;
7588
7589 codec->spec = spec;
7590
1f0f4b80
TI
7591 spec->mixer_nid = 0x07;
7592
f5fcc13c
TI
7593 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7594 alc260_models,
7595 alc260_cfg_tbl);
7596 if (board_config < 0) {
9a11f1aa 7597 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7598 codec->chip_name);
df694daa 7599 board_config = ALC260_AUTO;
16ded525 7600 }
1da177e4 7601
b5bfbc67
TI
7602 if (board_config == ALC260_AUTO) {
7603 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7604 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7605 }
fc091769 7606
df694daa
KY
7607 if (board_config == ALC260_AUTO) {
7608 /* automatic parse from the BIOS config */
7609 err = alc260_parse_auto_config(codec);
7610 if (err < 0) {
7611 alc_free(codec);
7612 return err;
f12ab1e0 7613 } else if (!err) {
9c7f852e
TI
7614 printk(KERN_INFO
7615 "hda_codec: Cannot set up configuration "
7616 "from BIOS. Using base mode...\n");
df694daa
KY
7617 board_config = ALC260_BASIC;
7618 }
a9430dd8 7619 }
e9edcee0 7620
680cd536
KK
7621 err = snd_hda_attach_beep_device(codec, 0x1);
7622 if (err < 0) {
7623 alc_free(codec);
7624 return err;
7625 }
7626
df694daa 7627 if (board_config != ALC260_AUTO)
e9c364c0 7628 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7629
1da177e4
LT
7630 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7631 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7632 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7633
a3bcba38
TI
7634 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7635 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7636
4ef0ef19
TI
7637 if (!spec->adc_nids && spec->input_mux) {
7638 /* check whether NID 0x04 is valid */
7639 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7640 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7641 /* get type */
7642 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7643 spec->adc_nids = alc260_adc_nids_alt;
7644 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7645 } else {
7646 spec->adc_nids = alc260_adc_nids;
7647 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7648 }
7649 }
b59bdf3b 7650 set_capture_mixer(codec);
45bdd1c1 7651 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7652
b5bfbc67 7653 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7654
2134ea4f
TI
7655 spec->vmaster_nid = 0x08;
7656
1da177e4 7657 codec->patch_ops = alc_patch_ops;
df694daa 7658 if (board_config == ALC260_AUTO)
ae6b813a 7659 spec->init_hook = alc260_auto_init;
1c716153 7660 spec->shutup = alc_eapd_shutup;
cb53c626
TI
7661#ifdef CONFIG_SND_HDA_POWER_SAVE
7662 if (!spec->loopback.amplist)
7663 spec->loopback.amplist = alc260_loopbacks;
7664#endif
1da177e4
LT
7665
7666 return 0;
7667}
7668
e9edcee0 7669
1da177e4 7670/*
4953550a 7671 * ALC882/883/885/888/889 support
1da177e4
LT
7672 *
7673 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7674 * configuration. Each pin widget can choose any input DACs and a mixer.
7675 * Each ADC is connected from a mixer of all inputs. This makes possible
7676 * 6-channel independent captures.
7677 *
7678 * In addition, an independent DAC for the multi-playback (not used in this
7679 * driver yet).
7680 */
df694daa
KY
7681#define ALC882_DIGOUT_NID 0x06
7682#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7683#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7684#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7685#define ALC1200_DIGOUT_NID 0x10
7686
1da177e4 7687
a9111321 7688static const struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7689 { 8, NULL }
7690};
7691
4953550a 7692/* DACs */
4c6d72d1 7693static const hda_nid_t alc882_dac_nids[4] = {
1da177e4
LT
7694 /* front, rear, clfe, rear_surr */
7695 0x02, 0x03, 0x04, 0x05
7696};
4953550a 7697#define alc883_dac_nids alc882_dac_nids
1da177e4 7698
4953550a 7699/* ADCs */
df694daa
KY
7700#define alc882_adc_nids alc880_adc_nids
7701#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a 7702#define alc883_adc_nids alc882_adc_nids_alt
4c6d72d1
TI
7703static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7704static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
4953550a 7705#define alc889_adc_nids alc880_adc_nids
1da177e4 7706
4c6d72d1
TI
7707static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7708static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a 7709#define alc883_capsrc_nids alc882_capsrc_nids_alt
4c6d72d1 7710static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
4953550a 7711#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7712
1da177e4
LT
7713/* input MUX */
7714/* FIXME: should be a matrix-type input source selection */
7715
a9111321 7716static const struct hda_input_mux alc882_capture_source = {
1da177e4
LT
7717 .num_items = 4,
7718 .items = {
7719 { "Mic", 0x0 },
7720 { "Front Mic", 0x1 },
7721 { "Line", 0x2 },
7722 { "CD", 0x4 },
7723 },
7724};
41d5545d 7725
4953550a
TI
7726#define alc883_capture_source alc882_capture_source
7727
a9111321 7728static const struct hda_input_mux alc889_capture_source = {
87a8c370
JK
7729 .num_items = 3,
7730 .items = {
7731 { "Front Mic", 0x0 },
7732 { "Mic", 0x3 },
7733 { "Line", 0x2 },
7734 },
7735};
7736
a9111321 7737static const struct hda_input_mux mb5_capture_source = {
41d5545d
KS
7738 .num_items = 3,
7739 .items = {
7740 { "Mic", 0x1 },
b8f171e7 7741 { "Line", 0x7 },
41d5545d
KS
7742 { "CD", 0x4 },
7743 },
7744};
7745
a9111321 7746static const struct hda_input_mux macmini3_capture_source = {
e458b1fa
LY
7747 .num_items = 2,
7748 .items = {
7749 { "Line", 0x2 },
7750 { "CD", 0x4 },
7751 },
7752};
7753
a9111321 7754static const struct hda_input_mux alc883_3stack_6ch_intel = {
4953550a
TI
7755 .num_items = 4,
7756 .items = {
7757 { "Mic", 0x1 },
7758 { "Front Mic", 0x0 },
7759 { "Line", 0x2 },
7760 { "CD", 0x4 },
7761 },
7762};
7763
a9111321 7764static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
4953550a
TI
7765 .num_items = 2,
7766 .items = {
7767 { "Mic", 0x1 },
7768 { "Line", 0x2 },
7769 },
7770};
7771
a9111321 7772static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
4953550a
TI
7773 .num_items = 4,
7774 .items = {
7775 { "Mic", 0x0 },
28c4edb7 7776 { "Internal Mic", 0x1 },
4953550a
TI
7777 { "Line", 0x2 },
7778 { "CD", 0x4 },
7779 },
7780};
7781
a9111321 7782static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
4953550a
TI
7783 .num_items = 2,
7784 .items = {
7785 { "Mic", 0x0 },
28c4edb7 7786 { "Internal Mic", 0x1 },
4953550a
TI
7787 },
7788};
7789
a9111321 7790static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
4953550a
TI
7791 .num_items = 3,
7792 .items = {
7793 { "Mic", 0x0 },
7794 { "Front Mic", 0x1 },
7795 { "Line", 0x4 },
7796 },
7797};
7798
a9111321 7799static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
4953550a
TI
7800 .num_items = 2,
7801 .items = {
7802 { "Mic", 0x0 },
7803 { "Line", 0x2 },
7804 },
7805};
7806
a9111321 7807static const struct hda_input_mux alc889A_mb31_capture_source = {
4953550a
TI
7808 .num_items = 2,
7809 .items = {
7810 { "Mic", 0x0 },
7811 /* Front Mic (0x01) unused */
7812 { "Line", 0x2 },
7813 /* Line 2 (0x03) unused */
af901ca1 7814 /* CD (0x04) unused? */
4953550a
TI
7815 },
7816};
7817
a9111321 7818static const struct hda_input_mux alc889A_imac91_capture_source = {
b7cccc52
JM
7819 .num_items = 2,
7820 .items = {
7821 { "Mic", 0x01 },
7822 { "Line", 0x2 }, /* Not sure! */
7823 },
7824};
7825
4953550a
TI
7826/*
7827 * 2ch mode
7828 */
a9111321 7829static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4953550a
TI
7830 { 2, NULL }
7831};
7832
272a527c
KY
7833/*
7834 * 2ch mode
7835 */
a9111321 7836static const struct hda_verb alc882_3ST_ch2_init[] = {
272a527c
KY
7837 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7838 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7839 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7840 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7841 { } /* end */
7842};
7843
4953550a
TI
7844/*
7845 * 4ch mode
7846 */
a9111321 7847static const struct hda_verb alc882_3ST_ch4_init[] = {
4953550a
TI
7848 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7849 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7850 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7851 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7852 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7853 { } /* end */
7854};
7855
272a527c
KY
7856/*
7857 * 6ch mode
7858 */
a9111321 7859static const struct hda_verb alc882_3ST_ch6_init[] = {
272a527c
KY
7860 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7861 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7862 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7865 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7866 { } /* end */
7867};
7868
a9111321 7869static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7870 { 2, alc882_3ST_ch2_init },
4953550a 7871 { 4, alc882_3ST_ch4_init },
272a527c
KY
7872 { 6, alc882_3ST_ch6_init },
7873};
7874
4953550a
TI
7875#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7876
a65cc60f 7877/*
7878 * 2ch mode
7879 */
a9111321 7880static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
a65cc60f 7881 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7882 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7883 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7884 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7885 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7886 { } /* end */
7887};
7888
7889/*
7890 * 4ch mode
7891 */
a9111321 7892static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
a65cc60f 7893 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7894 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7895 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7896 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7897 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7898 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7899 { } /* end */
7900};
7901
7902/*
7903 * 6ch mode
7904 */
a9111321 7905static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
a65cc60f 7906 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7908 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7909 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7910 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7911 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7912 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7913 { } /* end */
7914};
7915
a9111321 7916static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
a65cc60f 7917 { 2, alc883_3ST_ch2_clevo_init },
7918 { 4, alc883_3ST_ch4_clevo_init },
7919 { 6, alc883_3ST_ch6_clevo_init },
7920};
7921
7922
df694daa
KY
7923/*
7924 * 6ch mode
7925 */
a9111321 7926static const struct hda_verb alc882_sixstack_ch6_init[] = {
df694daa
KY
7927 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7928 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7929 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7931 { } /* end */
7932};
7933
7934/*
7935 * 8ch mode
7936 */
a9111321 7937static const struct hda_verb alc882_sixstack_ch8_init[] = {
df694daa
KY
7938 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7940 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7941 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7942 { } /* end */
7943};
7944
a9111321 7945static const struct hda_channel_mode alc882_sixstack_modes[2] = {
df694daa
KY
7946 { 6, alc882_sixstack_ch6_init },
7947 { 8, alc882_sixstack_ch8_init },
7948};
7949
76e6f5a9
RH
7950
7951/* Macbook Air 2,1 */
7952
a9111321 7953static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
76e6f5a9
RH
7954 { 2, NULL },
7955};
7956
87350ad0 7957/*
def319f9 7958 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7959 */
7960
7961/*
7962 * 2ch mode
7963 */
a9111321 7964static const struct hda_verb alc885_mbp_ch2_init[] = {
87350ad0
TI
7965 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7966 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7967 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7968 { } /* end */
7969};
7970
7971/*
a3f730af 7972 * 4ch mode
87350ad0 7973 */
a9111321 7974static const struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7975 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7976 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7977 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7978 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7979 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7980 { } /* end */
7981};
7982
a9111321 7983static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7984 { 2, alc885_mbp_ch2_init },
a3f730af 7985 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7986};
7987
92b9de83
KS
7988/*
7989 * 2ch
7990 * Speakers/Woofer/HP = Front
7991 * LineIn = Input
7992 */
a9111321 7993static const struct hda_verb alc885_mb5_ch2_init[] = {
92b9de83
KS
7994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7995 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7996 { } /* end */
7997};
7998
7999/*
8000 * 6ch mode
8001 * Speakers/HP = Front
8002 * Woofer = LFE
8003 * LineIn = Surround
8004 */
a9111321 8005static const struct hda_verb alc885_mb5_ch6_init[] = {
92b9de83
KS
8006 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8009 { } /* end */
8010};
8011
a9111321 8012static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
92b9de83
KS
8013 { 2, alc885_mb5_ch2_init },
8014 { 6, alc885_mb5_ch6_init },
8015};
87350ad0 8016
d01aecdf 8017#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
8018
8019/*
8020 * 2ch mode
8021 */
a9111321 8022static const struct hda_verb alc883_4ST_ch2_init[] = {
4953550a
TI
8023 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8024 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8025 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8026 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8027 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8028 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8029 { } /* end */
8030};
8031
8032/*
8033 * 4ch mode
8034 */
a9111321 8035static const struct hda_verb alc883_4ST_ch4_init[] = {
4953550a
TI
8036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8038 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8039 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8040 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8041 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8042 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8043 { } /* end */
8044};
8045
8046/*
8047 * 6ch mode
8048 */
a9111321 8049static const struct hda_verb alc883_4ST_ch6_init[] = {
4953550a
TI
8050 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8051 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8052 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8053 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8054 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8055 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8056 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8057 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8058 { } /* end */
8059};
8060
8061/*
8062 * 8ch mode
8063 */
a9111321 8064static const struct hda_verb alc883_4ST_ch8_init[] = {
4953550a
TI
8065 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8066 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8067 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8068 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8069 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8070 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8071 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8072 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8073 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8074 { } /* end */
8075};
8076
a9111321 8077static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
4953550a
TI
8078 { 2, alc883_4ST_ch2_init },
8079 { 4, alc883_4ST_ch4_init },
8080 { 6, alc883_4ST_ch6_init },
8081 { 8, alc883_4ST_ch8_init },
8082};
8083
8084
8085/*
8086 * 2ch mode
8087 */
a9111321 8088static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
4953550a
TI
8089 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8090 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8091 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8092 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8093 { } /* end */
8094};
8095
8096/*
8097 * 4ch mode
8098 */
a9111321 8099static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
4953550a
TI
8100 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8101 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8102 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8103 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8104 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8105 { } /* end */
8106};
8107
8108/*
8109 * 6ch mode
8110 */
a9111321 8111static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
4953550a
TI
8112 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8113 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8114 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8117 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8118 { } /* end */
8119};
8120
a9111321 8121static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
4953550a
TI
8122 { 2, alc883_3ST_ch2_intel_init },
8123 { 4, alc883_3ST_ch4_intel_init },
8124 { 6, alc883_3ST_ch6_intel_init },
8125};
8126
dd7714c9
WF
8127/*
8128 * 2ch mode
8129 */
a9111321 8130static const struct hda_verb alc889_ch2_intel_init[] = {
dd7714c9
WF
8131 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8132 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8133 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8134 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8135 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8136 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8137 { } /* end */
8138};
8139
87a8c370
JK
8140/*
8141 * 6ch mode
8142 */
a9111321 8143static const struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
8144 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8145 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8146 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8147 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8148 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
8149 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8150 { } /* end */
8151};
8152
8153/*
8154 * 8ch mode
8155 */
a9111321 8156static const struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
8157 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8158 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8159 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8160 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8161 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
8162 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8163 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
8164 { } /* end */
8165};
8166
a9111321 8167static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
dd7714c9 8168 { 2, alc889_ch2_intel_init },
87a8c370
JK
8169 { 6, alc889_ch6_intel_init },
8170 { 8, alc889_ch8_intel_init },
8171};
8172
4953550a
TI
8173/*
8174 * 6ch mode
8175 */
a9111321 8176static const struct hda_verb alc883_sixstack_ch6_init[] = {
4953550a
TI
8177 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8178 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8179 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8180 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8181 { } /* end */
8182};
8183
8184/*
8185 * 8ch mode
8186 */
a9111321 8187static const struct hda_verb alc883_sixstack_ch8_init[] = {
4953550a
TI
8188 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8189 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8190 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8191 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8192 { } /* end */
8193};
8194
a9111321 8195static const struct hda_channel_mode alc883_sixstack_modes[2] = {
4953550a
TI
8196 { 6, alc883_sixstack_ch6_init },
8197 { 8, alc883_sixstack_ch8_init },
8198};
8199
8200
1da177e4
LT
8201/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8202 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8203 */
a9111321 8204static const struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 8205 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 8206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 8207 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 8208 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
8209 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8210 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
8211 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8212 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 8213 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 8214 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
8215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8216 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8217 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8218 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8219 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8221 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
8222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8223 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8224 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8225 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8226 { } /* end */
8227};
8228
76e6f5a9
RH
8229/* Macbook Air 2,1 same control for HP and internal Speaker */
8230
a9111321 8231static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
76e6f5a9
RH
8232 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8233 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8234 { }
8235};
8236
8237
a9111321 8238static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8239 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8240 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8241 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8242 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8243 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8244 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8245 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8247 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8248 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8249 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8250 { } /* end */
8251};
41d5545d 8252
a9111321 8253static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8254 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8255 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8256 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8257 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8258 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8259 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8260 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8261 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8262 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8263 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8264 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8265 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8266 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8267 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8268 { } /* end */
8269};
92b9de83 8270
a9111321 8271static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
e458b1fa
LY
8272 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8273 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8274 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8275 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8276 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8277 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8278 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8279 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8280 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8281 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8282 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8283 { } /* end */
8284};
8285
a9111321 8286static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8287 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8288 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8289 { } /* end */
8290};
8291
8292
a9111321 8293static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
bdd148a3
KY
8294 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8295 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8296 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8297 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8298 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8299 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8301 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8303 { } /* end */
8304};
8305
a9111321 8306static const struct snd_kcontrol_new alc882_targa_mixer[] = {
272a527c
KY
8307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8308 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8312 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8313 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8316 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8317 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8318 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8319 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8320 { } /* end */
8321};
8322
8323/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8324 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8325 */
a9111321 8326static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
272a527c
KY
8327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8328 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8329 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8335 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8336 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8337 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8338 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8339 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8340 { } /* end */
8341};
8342
a9111321 8343static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
914759b7
TI
8344 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8345 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8346 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8347 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8348 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8352 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8354 { } /* end */
8355};
8356
a9111321 8357static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
df694daa
KY
8358 {
8359 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8360 .name = "Channel Mode",
8361 .info = alc_ch_mode_info,
8362 .get = alc_ch_mode_get,
8363 .put = alc_ch_mode_put,
8364 },
8365 { } /* end */
8366};
8367
a9111321 8368static const struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8369 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8372 /* Rear mixer */
05acb863
TI
8373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8375 /* CLFE mixer */
05acb863
TI
8376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8378 /* Side mixer */
05acb863
TI
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8381
e9edcee0 8382 /* Front Pin: output 0 (0x0c) */
05acb863 8383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8384 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8385 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8386 /* Rear Pin: output 1 (0x0d) */
05acb863 8387 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8389 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8390 /* CLFE Pin: output 2 (0x0e) */
05acb863 8391 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8392 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8393 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8394 /* Side Pin: output 3 (0x0f) */
05acb863 8395 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8396 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8397 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8398 /* Mic (rear) pin: input vref at 80% */
16ded525 8399 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8400 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8401 /* Front Mic pin: input vref at 80% */
16ded525 8402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8403 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8404 /* Line In pin: input */
05acb863 8405 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8406 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8407 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8408 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8410 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8411 /* CD pin widget for input */
05acb863 8412 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8413
8414 /* FIXME: use matrix-type input source selection */
8415 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8416 /* Input mixer2 */
05acb863 8417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8418 /* Input mixer3 */
05acb863 8419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8420 /* ADC2: mute amp left and right */
8421 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8422 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8423 /* ADC3: mute amp left and right */
8424 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8425 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8426
8427 { }
8428};
8429
a9111321 8430static const struct hda_verb alc882_adc1_init_verbs[] = {
4953550a
TI
8431 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8435 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8436 /* ADC1: mute amp left and right */
8437 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8439 { }
8440};
8441
a9111321 8442static const struct hda_verb alc882_eapd_verbs[] = {
4b146cb0
TI
8443 /* change to EAPD mode */
8444 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8445 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8446 { }
4b146cb0
TI
8447};
8448
a9111321 8449static const struct hda_verb alc889_eapd_verbs[] = {
87a8c370
JK
8450 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8451 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8452 { }
8453};
8454
a9111321 8455static const struct hda_verb alc_hp15_unsol_verbs[] = {
6732bd0d
WF
8456 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8458 {}
8459};
87a8c370 8460
a9111321 8461static const struct hda_verb alc885_init_verbs[] = {
87a8c370 8462 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8465 /* Rear mixer */
88102f3f
KY
8466 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8467 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8468 /* CLFE mixer */
88102f3f
KY
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8471 /* Side mixer */
88102f3f
KY
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8473 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8474
8475 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8477 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8478 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8479 /* Front Pin: output 0 (0x0c) */
8480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8482 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 /* Rear Pin: output 1 (0x0d) */
8484 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8485 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8486 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8487 /* CLFE Pin: output 2 (0x0e) */
8488 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8489 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8490 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8491 /* Side Pin: output 3 (0x0f) */
8492 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8493 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8494 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8495 /* Mic (rear) pin: input vref at 80% */
8496 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8497 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8498 /* Front Mic pin: input vref at 80% */
8499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8501 /* Line In pin: input */
8502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8504
8505 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8506 /* Input mixer1 */
88102f3f 8507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8508 /* Input mixer2 */
8509 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8510 /* Input mixer3 */
88102f3f 8511 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8512 /* ADC2: mute amp left and right */
8513 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8514 /* ADC3: mute amp left and right */
8515 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8516
8517 { }
8518};
8519
a9111321 8520static const struct hda_verb alc885_init_input_verbs[] = {
87a8c370
JK
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8524 { }
8525};
8526
8527
8528/* Unmute Selector 24h and set the default input to front mic */
a9111321 8529static const struct hda_verb alc889_init_input_verbs[] = {
87a8c370
JK
8530 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8532 { }
8533};
8534
8535
4953550a
TI
8536#define alc883_init_verbs alc882_base_init_verbs
8537
9102cd1c 8538/* Mac Pro test */
a9111321 8539static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
9102cd1c
TD
8540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8541 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8543 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8544 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8545 /* FIXME: this looks suspicious...
d355c82a
JK
8546 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8547 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8548 */
9102cd1c
TD
8549 { } /* end */
8550};
8551
a9111321 8552static const struct hda_verb alc882_macpro_init_verbs[] = {
9102cd1c
TD
8553 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8557 /* Front Pin: output 0 (0x0c) */
8558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8561 /* Front Mic pin: input vref at 80% */
8562 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8563 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8564 /* Speaker: output */
8565 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8566 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8567 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8568 /* Headphone output (output 0 - 0x0c) */
8569 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8571 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8572
8573 /* FIXME: use matrix-type input source selection */
8574 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8575 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8579 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8580 /* Input mixer2 */
8581 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8584 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8585 /* Input mixer3 */
8586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8589 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8590 /* ADC1: mute amp left and right */
8591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8592 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8593 /* ADC2: mute amp left and right */
8594 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8595 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8596 /* ADC3: mute amp left and right */
8597 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8598 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8599
8600 { }
8601};
f12ab1e0 8602
41d5545d 8603/* Macbook 5,1 */
a9111321 8604static const struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8605 /* DACs */
8606 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8607 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8609 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8610 /* Front mixer */
41d5545d
KS
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8614 /* Surround mixer */
8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8617 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8618 /* LFE mixer */
8619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8620 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8621 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8622 /* HP mixer */
8623 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8624 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8625 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8626 /* Front Pin (0x0c) */
41d5545d
KS
8627 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8628 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8629 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8630 /* LFE Pin (0x0e) */
8631 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8632 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8633 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8634 /* HP Pin (0x0f) */
41d5545d
KS
8635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8637 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8638 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8639 /* Front Mic pin: input vref at 80% */
8640 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8641 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8642 /* Line In pin */
8643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8644 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8645
b8f171e7
AM
8646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8649 { }
8650};
8651
e458b1fa 8652/* Macmini 3,1 */
a9111321 8653static const struct hda_verb alc885_macmini3_init_verbs[] = {
e458b1fa
LY
8654 /* DACs */
8655 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8657 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8658 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8659 /* Front mixer */
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8663 /* Surround mixer */
8664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8666 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8667 /* LFE mixer */
8668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8670 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8671 /* HP mixer */
8672 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8673 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8674 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8675 /* Front Pin (0x0c) */
8676 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8677 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8678 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8679 /* LFE Pin (0x0e) */
8680 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8681 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8682 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8683 /* HP Pin (0x0f) */
8684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8686 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8687 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8688 /* Line In pin */
8689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8691
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8696 { }
8697};
8698
76e6f5a9 8699
a9111321 8700static const struct hda_verb alc885_mba21_init_verbs[] = {
76e6f5a9
RH
8701 /*Internal and HP Speaker Mixer*/
8702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8705 /*Internal Speaker Pin (0x0c)*/
8706 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8707 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8708 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8709 /* HP Pin: output 0 (0x0e) */
8710 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8711 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8712 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8713 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8714 /* Line in (is hp when jack connected)*/
8715 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8716 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8717
8718 { }
8719 };
8720
8721
87350ad0 8722/* Macbook Pro rev3 */
a9111321 8723static const struct hda_verb alc885_mbp3_init_verbs[] = {
87350ad0
TI
8724 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8727 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8728 /* Rear mixer */
8729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8732 /* HP mixer */
8733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8735 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8736 /* Front Pin: output 0 (0x0c) */
8737 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8738 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8739 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8740 /* HP Pin: output 0 (0x0e) */
87350ad0 8741 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8743 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8744 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8745 /* Mic (rear) pin: input vref at 80% */
8746 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8747 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8748 /* Front Mic pin: input vref at 80% */
8749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8751 /* Line In pin: use output 1 when in LineOut mode */
8752 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8754 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8755
8756 /* FIXME: use matrix-type input source selection */
8757 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8758 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8763 /* Input mixer2 */
8764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8768 /* Input mixer3 */
8769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8773 /* ADC1: mute amp left and right */
8774 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8775 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8776 /* ADC2: mute amp left and right */
8777 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8778 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8779 /* ADC3: mute amp left and right */
8780 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8781 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8782
8783 { }
8784};
8785
4b7e1803 8786/* iMac 9,1 */
a9111321 8787static const struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8788 /* Internal Speaker Pin (0x0c) */
8789 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8790 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8791 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8792 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8793 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8794 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8795 /* HP Pin: Rear */
4b7e1803
JM
8796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8798 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8799 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8800 /* Line in Rear */
8801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8803 /* Front Mic pin: input vref at 80% */
8804 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8805 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8806 /* Rear mixer */
8807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8810 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8814 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8818 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8819 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8820 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8821 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8822 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8823 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8824 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8826 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8828 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8829 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8831 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8832 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8834 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8835 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8836 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8837 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8838 { }
8839};
8840
c54728d8 8841/* iMac 24 mixer. */
a9111321 8842static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
c54728d8
NF
8843 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8844 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8845 { } /* end */
8846};
8847
8848/* iMac 24 init verbs. */
a9111321 8849static const struct hda_verb alc885_imac24_init_verbs[] = {
c54728d8
NF
8850 /* Internal speakers: output 0 (0x0c) */
8851 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8852 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8853 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8854 /* Internal speakers: output 0 (0x0c) */
8855 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8856 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8857 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8858 /* Headphone: output 0 (0x0c) */
8859 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8860 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8861 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8862 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8863 /* Front Mic: input vref at 80% */
8864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8865 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8866 { }
8867};
8868
8869/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8870static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8871{
a9fd4f3f 8872 struct alc_spec *spec = codec->spec;
c54728d8 8873
a9fd4f3f
TI
8874 spec->autocfg.hp_pins[0] = 0x14;
8875 spec->autocfg.speaker_pins[0] = 0x18;
8876 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8877 spec->automute = 1;
8878 spec->automute_mode = ALC_AUTOMUTE_AMP;
c54728d8
NF
8879}
8880
9d54f08b
TI
8881#define alc885_mb5_setup alc885_imac24_setup
8882#define alc885_macmini3_setup alc885_imac24_setup
8883
76e6f5a9
RH
8884/* Macbook Air 2,1 */
8885static void alc885_mba21_setup(struct hda_codec *codec)
8886{
8887 struct alc_spec *spec = codec->spec;
8888
8889 spec->autocfg.hp_pins[0] = 0x14;
8890 spec->autocfg.speaker_pins[0] = 0x18;
d922b51d
TI
8891 spec->automute = 1;
8892 spec->automute_mode = ALC_AUTOMUTE_AMP;
76e6f5a9
RH
8893}
8894
8895
8896
4f5d1706 8897static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8898{
a9fd4f3f 8899 struct alc_spec *spec = codec->spec;
87350ad0 8900
a9fd4f3f
TI
8901 spec->autocfg.hp_pins[0] = 0x15;
8902 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
8903 spec->automute = 1;
8904 spec->automute_mode = ALC_AUTOMUTE_AMP;
87350ad0
TI
8905}
8906
9d54f08b 8907static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8908{
9d54f08b 8909 struct alc_spec *spec = codec->spec;
4b7e1803 8910
9d54f08b 8911 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8912 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8913 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8914 spec->automute = 1;
8915 spec->automute_mode = ALC_AUTOMUTE_AMP;
4b7e1803 8916}
87350ad0 8917
a9111321 8918static const struct hda_verb alc882_targa_verbs[] = {
272a527c
KY
8919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8920 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8921
8922 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8923 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8924
272a527c
KY
8925 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8926 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8927 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8928
8929 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8930 { } /* end */
8931};
8932
8933/* toggle speaker-output according to the hp-jack state */
8934static void alc882_targa_automute(struct hda_codec *codec)
8935{
a9fd4f3f 8936 struct alc_spec *spec = codec->spec;
d922b51d 8937 alc_hp_automute(codec);
82beb8fd 8938 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8939 spec->jack_present ? 1 : 3);
8940}
8941
4f5d1706 8942static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8943{
8944 struct alc_spec *spec = codec->spec;
8945
8946 spec->autocfg.hp_pins[0] = 0x14;
8947 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
8948 spec->automute = 1;
8949 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
8950}
8951
8952static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8953{
a9fd4f3f 8954 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8955 alc882_targa_automute(codec);
272a527c
KY
8956}
8957
a9111321 8958static const struct hda_verb alc882_asus_a7j_verbs[] = {
272a527c
KY
8959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8961
8962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8963 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8964 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8965
272a527c
KY
8966 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8967 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8968 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8969
8970 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8971 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8972 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8973 { } /* end */
8974};
8975
a9111321 8976static const struct hda_verb alc882_asus_a7m_verbs[] = {
914759b7
TI
8977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8978 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8979
8980 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8981 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8982 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8983
914759b7
TI
8984 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8985 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8986 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8987
8988 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8989 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8990 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8991 { } /* end */
8992};
8993
9102cd1c
TD
8994static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8995{
8996 unsigned int gpiostate, gpiomask, gpiodir;
8997
8998 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8999 AC_VERB_GET_GPIO_DATA, 0);
9000
9001 if (!muted)
9002 gpiostate |= (1 << pin);
9003 else
9004 gpiostate &= ~(1 << pin);
9005
9006 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9007 AC_VERB_GET_GPIO_MASK, 0);
9008 gpiomask |= (1 << pin);
9009
9010 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9011 AC_VERB_GET_GPIO_DIRECTION, 0);
9012 gpiodir |= (1 << pin);
9013
9014
9015 snd_hda_codec_write(codec, codec->afg, 0,
9016 AC_VERB_SET_GPIO_MASK, gpiomask);
9017 snd_hda_codec_write(codec, codec->afg, 0,
9018 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9019
9020 msleep(1);
9021
9022 snd_hda_codec_write(codec, codec->afg, 0,
9023 AC_VERB_SET_GPIO_DATA, gpiostate);
9024}
9025
7debbe51
TI
9026/* set up GPIO at initialization */
9027static void alc885_macpro_init_hook(struct hda_codec *codec)
9028{
9029 alc882_gpio_mute(codec, 0, 0);
9030 alc882_gpio_mute(codec, 1, 0);
9031}
9032
9033/* set up GPIO and update auto-muting at initialization */
9034static void alc885_imac24_init_hook(struct hda_codec *codec)
9035{
9036 alc885_macpro_init_hook(codec);
d922b51d 9037 alc_hp_automute(codec);
7debbe51
TI
9038}
9039
eb4c41d3 9040/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
a9111321 9041static const struct hda_verb alc889A_mb31_ch2_init[] = {
eb4c41d3
TS
9042 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9043 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9044 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9045 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9046 { } /* end */
9047};
9048
9049/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
a9111321 9050static const struct hda_verb alc889A_mb31_ch4_init[] = {
eb4c41d3
TS
9051 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9052 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9053 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9054 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9055 { } /* end */
9056};
9057
9058/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
a9111321 9059static const struct hda_verb alc889A_mb31_ch5_init[] = {
eb4c41d3
TS
9060 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9061 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9063 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9064 { } /* end */
9065};
9066
9067/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
a9111321 9068static const struct hda_verb alc889A_mb31_ch6_init[] = {
eb4c41d3
TS
9069 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9070 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9071 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9072 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9073 { } /* end */
9074};
9075
a9111321 9076static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
eb4c41d3
TS
9077 { 2, alc889A_mb31_ch2_init },
9078 { 4, alc889A_mb31_ch4_init },
9079 { 5, alc889A_mb31_ch5_init },
9080 { 6, alc889A_mb31_ch6_init },
9081};
9082
a9111321 9083static const struct hda_verb alc883_medion_eapd_verbs[] = {
b373bdeb
AN
9084 /* eanable EAPD on medion laptop */
9085 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9086 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9087 { }
9088};
9089
4953550a 9090#define alc883_base_mixer alc882_base_mixer
834be88d 9091
a9111321 9092static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
a8848bd6
AS
9093 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9094 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9095 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9096 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9097 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9098 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9101 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
9102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9103 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9104 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 9105 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
9106 { } /* end */
9107};
9108
a9111321 9109static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
9110 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9111 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9112 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9113 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9114 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 9116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9117 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9118 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9119 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
9120 { } /* end */
9121};
9122
a9111321 9123static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
fb97dc67
J
9124 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9125 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9126 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9127 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9129 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 9130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9131 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9132 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9133 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
9134 { } /* end */
9135};
9136
a9111321 9137static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9c7f852e
TI
9138 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9139 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9141 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9142 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9143 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9144 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9146 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9148 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9149 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9150 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9151 { } /* end */
9152};
df694daa 9153
a9111321 9154static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9c7f852e
TI
9155 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9156 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9157 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9158 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9159 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9160 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9161 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9162 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9164 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9165 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9166 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9167 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9168 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9169 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9171 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9172 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9173 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9174 { } /* end */
9175};
9176
a9111321 9177static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
17bba1b7
J
9178 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9179 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9180 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9181 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9182 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9183 HDA_OUTPUT),
9184 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9185 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9186 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9187 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9188 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9189 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9190 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9191 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9192 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9194 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9195 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9196 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9198 { } /* end */
9199};
9200
a9111321 9201static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
87a8c370
JK
9202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9203 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9204 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9205 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9206 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9207 HDA_OUTPUT),
9208 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9209 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9210 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9212 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9215 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9217 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9220 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9221 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9222 { } /* end */
9223};
9224
a9111321 9225static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9226 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9227 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9228 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9229 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9230 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9231 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9232 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9233 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9234 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9235 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9236 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9237 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9238 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9240 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9241 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9242 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9243 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9244 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9245 { } /* end */
9246};
9247
a9111321 9248static const struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9249 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9250 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9251 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9252 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9253 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9254 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9255 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9256 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9257 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9258 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9259 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9260 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9261 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9262 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9264 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9265 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9266 { } /* end */
f12ab1e0 9267};
ccc656ce 9268
a9111321 9269static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9270 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9271 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9272 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9273 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9274 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9275 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9276 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9277 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9278 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9279 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9280 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9281 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9282 { } /* end */
f12ab1e0 9283};
ccc656ce 9284
a9111321 9285static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
b99dba34
TI
9286 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9287 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9288 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9289 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9290 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9291 { } /* end */
9292};
9293
a9111321 9294static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
bc9f98a9
KY
9295 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9296 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9297 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9298 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9299 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9301 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9303 { } /* end */
f12ab1e0 9304};
bc9f98a9 9305
a9111321 9306static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
272a527c
KY
9307 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9308 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9312 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9313 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9314 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9315 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9316 { } /* end */
ea1fb29a 9317};
272a527c 9318
a9111321 9319static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
7ad7b218
MC
9320 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9321 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9322 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9323 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9324 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9325 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9326 { } /* end */
9327};
9328
a9111321 9329static const struct hda_verb alc883_medion_wim2160_verbs[] = {
7ad7b218
MC
9330 /* Unmute front mixer */
9331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9333
9334 /* Set speaker pin to front mixer */
9335 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9336
9337 /* Init headphone pin */
9338 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9339 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9340 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9341 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9342
9343 { } /* end */
9344};
9345
9346/* toggle speaker-output according to the hp-jack state */
9347static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9348{
9349 struct alc_spec *spec = codec->spec;
9350
9351 spec->autocfg.hp_pins[0] = 0x1a;
9352 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9353 spec->automute = 1;
9354 spec->automute_mode = ALC_AUTOMUTE_AMP;
7ad7b218
MC
9355}
9356
a9111321 9357static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9358 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9359 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9360 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9361 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9362 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9363 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9364 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9366 { } /* end */
d1a991a6 9367};
2880a867 9368
a9111321 9369static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
d2fd4b09 9370 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9371 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9372 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9373 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9374 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9375 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9376 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9377 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9378 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9379 { } /* end */
9380};
9381
a9111321 9382static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
e2757d5e
KY
9383 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9384 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9385 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9386 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9387 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9388 0x0d, 1, 0x0, HDA_OUTPUT),
9389 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9390 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9391 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9392 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9393 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9394 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9395 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9396 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9397 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9398 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9399 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9400 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9401 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9402 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9403 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9404 { } /* end */
9405};
9406
a9111321 9407static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
eb4c41d3
TS
9408 /* Output mixers */
9409 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9410 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9411 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9412 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9413 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9414 HDA_OUTPUT),
9415 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9416 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9417 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9418 /* Output switches */
9419 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9420 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9421 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9422 /* Boost mixers */
5f99f86a
DH
9423 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9424 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9425 /* Input mixers */
9426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9427 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9430 { } /* end */
9431};
9432
a9111321 9433static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
3e1647c5
GG
9434 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9435 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9436 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9438 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9440 { } /* end */
9441};
9442
a9111321 9443static const struct hda_bind_ctls alc883_bind_cap_vol = {
e2757d5e
KY
9444 .ops = &snd_hda_bind_vol,
9445 .values = {
9446 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9447 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9448 0
9449 },
9450};
9451
a9111321 9452static const struct hda_bind_ctls alc883_bind_cap_switch = {
e2757d5e
KY
9453 .ops = &snd_hda_bind_sw,
9454 .values = {
9455 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9456 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9457 0
9458 },
9459};
9460
a9111321 9461static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
e2757d5e
KY
9462 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9463 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9464 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9465 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9466 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9468 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9470 { } /* end */
9471};
df694daa 9472
a9111321 9473static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
4953550a
TI
9474 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9475 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9476 {
9477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9478 /* .name = "Capture Source", */
9479 .name = "Input Source",
9480 .count = 1,
9481 .info = alc_mux_enum_info,
9482 .get = alc_mux_enum_get,
9483 .put = alc_mux_enum_put,
9484 },
9485 { } /* end */
9486};
9c7f852e 9487
a9111321 9488static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
4953550a
TI
9489 {
9490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9491 .name = "Channel Mode",
9492 .info = alc_ch_mode_info,
9493 .get = alc_ch_mode_get,
9494 .put = alc_ch_mode_put,
9495 },
9496 { } /* end */
9c7f852e
TI
9497};
9498
a8848bd6 9499/* toggle speaker-output according to the hp-jack state */
4f5d1706 9500static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9501{
a9fd4f3f 9502 struct alc_spec *spec = codec->spec;
a8848bd6 9503
a9fd4f3f
TI
9504 spec->autocfg.hp_pins[0] = 0x15;
9505 spec->autocfg.speaker_pins[0] = 0x14;
9506 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9507 spec->automute = 1;
9508 spec->automute_mode = ALC_AUTOMUTE_AMP;
a8848bd6
AS
9509}
9510
a9111321 9511static const struct hda_verb alc883_mitac_verbs[] = {
a8848bd6
AS
9512 /* HP */
9513 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9515 /* Subwoofer */
9516 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9517 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9518
9519 /* enable unsolicited event */
9520 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9521 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9522
9523 { } /* end */
9524};
9525
a9111321 9526static const struct hda_verb alc883_clevo_m540r_verbs[] = {
a65cc60f 9527 /* HP */
9528 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9530 /* Int speaker */
9531 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9532
9533 /* enable unsolicited event */
9534 /*
9535 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9536 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9537 */
9538
9539 { } /* end */
9540};
9541
a9111321 9542static const struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9543 /* HP */
9544 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9545 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9546 /* Int speaker */
9547 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9548 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9549
9550 /* enable unsolicited event */
9551 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9552 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9553
9554 { } /* end */
9555};
9556
a9111321 9557static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
fb97dc67
J
9558 /* HP */
9559 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9561 /* Subwoofer */
9562 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9563 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9564
9565 /* enable unsolicited event */
9566 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9567
9568 { } /* end */
9569};
9570
a9111321 9571static const struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9574
9575 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9576 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9577
64a8be74
DH
9578/* Connect Line-Out side jack (SPDIF) to Side */
9579 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9580 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9581 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9582/* Connect Mic jack to CLFE */
9583 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9585 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9586/* Connect Line-in jack to Surround */
9587 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9588 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9589 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9590/* Connect HP out jack to Front */
9591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9592 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9593 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9594
9595 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9596
9597 { } /* end */
9598};
9599
a9111321 9600static const struct hda_verb alc883_lenovo_101e_verbs[] = {
bc9f98a9
KY
9601 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9602 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9603 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9604 { } /* end */
9605};
9606
a9111321 9607static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
272a527c
KY
9608 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9610 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9612 { } /* end */
9613};
9614
a9111321 9615static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
272a527c
KY
9616 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9617 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9618 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9619 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9620 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9621 { } /* end */
9622};
9623
a9111321 9624static const struct hda_verb alc883_haier_w66_verbs[] = {
189609ae
KY
9625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9626 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9627
9628 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9629
9630 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9631 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9632 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9633 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9634 { } /* end */
9635};
9636
a9111321 9637static const struct hda_verb alc888_lenovo_sky_verbs[] = {
e2757d5e
KY
9638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9640 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9641 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9642 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9643 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9644 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9645 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9646 { } /* end */
9647};
9648
a9111321 9649static const struct hda_verb alc888_6st_dell_verbs[] = {
8718b700
HRK
9650 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9651 { }
9652};
9653
a9111321 9654static const struct hda_verb alc883_vaiott_verbs[] = {
3e1647c5
GG
9655 /* HP */
9656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9657 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9658
9659 /* enable unsolicited event */
9660 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9661
9662 { } /* end */
9663};
9664
4f5d1706 9665static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9666{
a9fd4f3f 9667 struct alc_spec *spec = codec->spec;
8718b700 9668
a9fd4f3f
TI
9669 spec->autocfg.hp_pins[0] = 0x1b;
9670 spec->autocfg.speaker_pins[0] = 0x14;
9671 spec->autocfg.speaker_pins[1] = 0x16;
9672 spec->autocfg.speaker_pins[2] = 0x18;
d922b51d
TI
9673 spec->automute = 1;
9674 spec->automute_mode = ALC_AUTOMUTE_AMP;
8718b700
HRK
9675}
9676
a9111321 9677static const struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9678 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9679 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9680 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9681 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9682 { } /* end */
5795b9e6
CM
9683};
9684
3ea0d7cf
HRK
9685/*
9686 * 2ch mode
9687 */
a9111321 9688static const struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9689 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9690 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9691 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9692 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9693 { } /* end */
8341de60
CM
9694};
9695
3ea0d7cf
HRK
9696/*
9697 * 4ch mode
9698 */
a9111321 9699static const struct hda_verb alc888_3st_hp_4ch_init[] = {
3ea0d7cf
HRK
9700 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9701 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9702 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9703 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9704 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9705 { } /* end */
9706};
9707
9708/*
9709 * 6ch mode
9710 */
a9111321 9711static const struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9712 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9713 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9714 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9715 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9716 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9717 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9718 { } /* end */
8341de60
CM
9719};
9720
a9111321 9721static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9722 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9723 { 4, alc888_3st_hp_4ch_init },
4723c022 9724 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9725};
9726
e6a5e1b7 9727static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
272a527c 9728{
e6a5e1b7 9729 struct alc_spec *spec = codec->spec;
47fd830a 9730
e6a5e1b7
TI
9731 spec->autocfg.hp_pins[0] = 0x1b;
9732 spec->autocfg.line_out_pins[0] = 0x14;
9733 spec->autocfg.speaker_pins[0] = 0x15;
9734 spec->automute = 1;
9735 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9736}
9737
272a527c 9738/* toggle speaker-output according to the hp-jack state */
dc427170 9739static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9740{
a9fd4f3f 9741 struct alc_spec *spec = codec->spec;
272a527c 9742
a9fd4f3f
TI
9743 spec->autocfg.hp_pins[0] = 0x14;
9744 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9745 spec->automute = 1;
9746 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9747}
9748
ccc656ce 9749/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9750#define alc883_targa_init_hook alc882_targa_init_hook
9751#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9752
4f5d1706 9753static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9754{
a9fd4f3f
TI
9755 struct alc_spec *spec = codec->spec;
9756
9757 spec->autocfg.hp_pins[0] = 0x15;
9758 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9759 spec->automute = 1;
9760 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
9761}
9762
9763static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9764{
d922b51d 9765 alc_hp_automute(codec);
eeb43387 9766 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9767}
9768
9769static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9770 unsigned int res)
9771{
0c4cc443 9772 switch (res >> 26) {
0c4cc443 9773 case ALC880_MIC_EVENT:
eeb43387 9774 alc88x_simple_mic_automute(codec);
0c4cc443 9775 break;
a9fd4f3f 9776 default:
d922b51d 9777 alc_sku_unsol_event(codec, res);
a9fd4f3f 9778 break;
0c4cc443 9779 }
368c7a95
J
9780}
9781
fb97dc67 9782/* toggle speaker-output according to the hp-jack state */
4f5d1706 9783static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9784{
a9fd4f3f 9785 struct alc_spec *spec = codec->spec;
fb97dc67 9786
a9fd4f3f
TI
9787 spec->autocfg.hp_pins[0] = 0x14;
9788 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9789 spec->automute = 1;
9790 spec->automute_mode = ALC_AUTOMUTE_AMP;
fb97dc67
J
9791}
9792
4f5d1706 9793static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9794{
a9fd4f3f 9795 struct alc_spec *spec = codec->spec;
189609ae 9796
a9fd4f3f
TI
9797 spec->autocfg.hp_pins[0] = 0x1b;
9798 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9799 spec->automute = 1;
9800 spec->automute_mode = ALC_AUTOMUTE_AMP;
189609ae
KY
9801}
9802
e6a5e1b7 9803static void alc883_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 9804{
e6a5e1b7 9805 struct alc_spec *spec = codec->spec;
bc9f98a9 9806
e6a5e1b7
TI
9807 spec->autocfg.hp_pins[0] = 0x1b;
9808 spec->autocfg.line_out_pins[0] = 0x14;
9809 spec->autocfg.speaker_pins[0] = 0x15;
9810 spec->automute = 1;
9811 spec->detect_line = 1;
9812 spec->automute_lines = 1;
9813 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
9814}
9815
676a9b53 9816/* toggle speaker-output according to the hp-jack state */
4f5d1706 9817static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9818{
a9fd4f3f 9819 struct alc_spec *spec = codec->spec;
676a9b53 9820
a9fd4f3f
TI
9821 spec->autocfg.hp_pins[0] = 0x14;
9822 spec->autocfg.speaker_pins[0] = 0x15;
9823 spec->autocfg.speaker_pins[1] = 0x16;
d922b51d
TI
9824 spec->automute = 1;
9825 spec->automute_mode = ALC_AUTOMUTE_AMP;
676a9b53
TI
9826}
9827
a9111321 9828static const struct hda_verb alc883_acer_eapd_verbs[] = {
d1a991a6
KY
9829 /* HP Pin: output 0 (0x0c) */
9830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9831 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9832 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9833 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9834 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9835 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9836 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9837 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9838 /* eanable EAPD on medion laptop */
9839 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9840 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9841 /* enable unsolicited event */
9842 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9843 { }
9844};
9845
4f5d1706 9846static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9847{
a9fd4f3f 9848 struct alc_spec *spec = codec->spec;
5795b9e6 9849
a9fd4f3f
TI
9850 spec->autocfg.hp_pins[0] = 0x1b;
9851 spec->autocfg.speaker_pins[0] = 0x14;
9852 spec->autocfg.speaker_pins[1] = 0x15;
9853 spec->autocfg.speaker_pins[2] = 0x16;
9854 spec->autocfg.speaker_pins[3] = 0x17;
d922b51d
TI
9855 spec->automute = 1;
9856 spec->automute_mode = ALC_AUTOMUTE_AMP;
5795b9e6
CM
9857}
9858
4f5d1706 9859static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9860{
a9fd4f3f 9861 struct alc_spec *spec = codec->spec;
e2757d5e 9862
a9fd4f3f
TI
9863 spec->autocfg.hp_pins[0] = 0x1b;
9864 spec->autocfg.speaker_pins[0] = 0x14;
9865 spec->autocfg.speaker_pins[1] = 0x15;
9866 spec->autocfg.speaker_pins[2] = 0x16;
9867 spec->autocfg.speaker_pins[3] = 0x17;
9868 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
9869 spec->automute = 1;
9870 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9871}
9872
4f5d1706 9873static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9874{
9875 struct alc_spec *spec = codec->spec;
9876
9877 spec->autocfg.hp_pins[0] = 0x15;
9878 spec->autocfg.speaker_pins[0] = 0x14;
9879 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9880 spec->automute = 1;
9881 spec->automute_mode = ALC_AUTOMUTE_AMP;
3e1647c5
GG
9882}
9883
a9111321 9884static const struct hda_verb alc888_asus_m90v_verbs[] = {
e2757d5e
KY
9885 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9886 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9888 /* enable unsolicited event */
9889 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9890 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9891 { } /* end */
9892};
9893
4f5d1706 9894static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9895{
a9fd4f3f 9896 struct alc_spec *spec = codec->spec;
e2757d5e 9897
a9fd4f3f
TI
9898 spec->autocfg.hp_pins[0] = 0x1b;
9899 spec->autocfg.speaker_pins[0] = 0x14;
9900 spec->autocfg.speaker_pins[1] = 0x15;
9901 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9902 spec->ext_mic.pin = 0x18;
9903 spec->int_mic.pin = 0x19;
9904 spec->ext_mic.mux_idx = 0;
9905 spec->int_mic.mux_idx = 1;
9906 spec->auto_mic = 1;
d922b51d
TI
9907 spec->automute = 1;
9908 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9909}
9910
a9111321 9911static const struct hda_verb alc888_asus_eee1601_verbs[] = {
e2757d5e
KY
9912 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9915 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9916 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9917 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9918 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9919 /* enable unsolicited event */
9920 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9921 { } /* end */
9922};
9923
e2757d5e
KY
9924static void alc883_eee1601_inithook(struct hda_codec *codec)
9925{
a9fd4f3f
TI
9926 struct alc_spec *spec = codec->spec;
9927
9928 spec->autocfg.hp_pins[0] = 0x14;
9929 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d 9930 alc_hp_automute(codec);
e2757d5e
KY
9931}
9932
a9111321 9933static const struct hda_verb alc889A_mb31_verbs[] = {
eb4c41d3
TS
9934 /* Init rear pin (used as headphone output) */
9935 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9936 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9937 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9938 /* Init line pin (used as output in 4ch and 6ch mode) */
9939 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9940 /* Init line 2 pin (used as headphone out by default) */
9941 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9942 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9943 { } /* end */
9944};
9945
9946/* Mute speakers according to the headphone jack state */
9947static void alc889A_mb31_automute(struct hda_codec *codec)
9948{
9949 unsigned int present;
9950
9951 /* Mute only in 2ch or 4ch mode */
9952 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9953 == 0x00) {
864f92be 9954 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9955 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9956 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9957 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9958 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9959 }
9960}
9961
9962static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9963{
9964 if ((res >> 26) == ALC880_HP_EVENT)
9965 alc889A_mb31_automute(codec);
9966}
9967
4953550a 9968
cb53c626 9969#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9970#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9971#endif
9972
def319f9 9973/* pcm configuration: identical with ALC880 */
4953550a
TI
9974#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9975#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9976#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9977#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9978
4c6d72d1 9979static const hda_nid_t alc883_slave_dig_outs[] = {
4953550a
TI
9980 ALC1200_DIGOUT_NID, 0,
9981};
9982
4c6d72d1 9983static const hda_nid_t alc1200_slave_dig_outs[] = {
4953550a
TI
9984 ALC883_DIGOUT_NID, 0,
9985};
9c7f852e
TI
9986
9987/*
9988 * configuration and preset
9989 */
ea734963 9990static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9991 [ALC882_3ST_DIG] = "3stack-dig",
9992 [ALC882_6ST_DIG] = "6stack-dig",
9993 [ALC882_ARIMA] = "arima",
9994 [ALC882_W2JC] = "w2jc",
9995 [ALC882_TARGA] = "targa",
9996 [ALC882_ASUS_A7J] = "asus-a7j",
9997 [ALC882_ASUS_A7M] = "asus-a7m",
9998 [ALC885_MACPRO] = "macpro",
9999 [ALC885_MB5] = "mb5",
e458b1fa 10000 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 10001 [ALC885_MBA21] = "mba21",
4953550a
TI
10002 [ALC885_MBP3] = "mbp3",
10003 [ALC885_IMAC24] = "imac24",
4b7e1803 10004 [ALC885_IMAC91] = "imac91",
4953550a 10005 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
10006 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10007 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 10008 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
10009 [ALC883_TARGA_DIG] = "targa-dig",
10010 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 10011 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 10012 [ALC883_ACER] = "acer",
2880a867 10013 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 10014 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 10015 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 10016 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 10017 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 10018 [ALC883_MEDION] = "medion",
7ad7b218 10019 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 10020 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 10021 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
10022 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10023 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 10024 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 10025 [ALC883_HAIER_W66] = "haier-w66",
4723c022 10026 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 10027 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 10028 [ALC883_MITAC] = "mitac",
a65cc60f 10029 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 10030 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 10031 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 10032 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 10033 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
10034 [ALC889A_INTEL] = "intel-alc889a",
10035 [ALC889_INTEL] = "intel-x58",
3ab90935 10036 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 10037 [ALC889A_MB31] = "mb31",
3e1647c5 10038 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 10039 [ALC882_AUTO] = "auto",
f5fcc13c
TI
10040};
10041
a9111321 10042static const struct snd_pci_quirk alc882_cfg_tbl[] = {
4953550a
TI
10043 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10044
ac3e3741 10045 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 10046 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 10047 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
10048 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10049 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 10050 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
10051 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10052 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 10053 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 10054 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
10055 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10056 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
10057 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10058 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
10059 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10060 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 10061 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 10062 ALC888_ACER_ASPIRE_6530G),
cc374c47 10063 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 10064 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
10065 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10066 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
10067 /* default Acer -- disabled as it causes more problems.
10068 * model=auto should work fine now
10069 */
10070 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 10071
5795b9e6 10072 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 10073
25985edc 10074 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
ac3e3741
TI
10075 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10076 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 10077 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 10078 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 10079 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
10080
10081 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10082 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10083 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 10084 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
10085 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10086 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10087 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 10088 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 10089 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 10090 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 10091 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
10092
10093 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 10094 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 10095 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 10096 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
10097 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10098 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 10099 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 10100 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
ebb47241 10101 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
4953550a 10102
6f3bf657 10103 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 10104 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10105 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10106 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 10107 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 10108 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 10109 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 10110 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 10111 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10112 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10113 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10114 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 10115 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 10116 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 10117 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10118 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10119 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10120 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 10121 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 10122 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
10123 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10124 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10125 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 10126 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 10127 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
10128 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10129 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 10130 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 10131 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 10132 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 10133 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10134
ac3e3741 10135 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 10136 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
10137 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10138 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 10139 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 10140 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 10141 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 10142 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 10143 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 10144 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 10145 ALC883_FUJITSU_PI2515),
bfb53037 10146 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 10147 ALC888_FUJITSU_XA3530),
272a527c 10148 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 10149 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
10150 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10151 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 10152 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 10153 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 10154 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 10155 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 10156
17bba1b7
J
10157 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10158 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 10159 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
10160 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10161 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10162 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 10163 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 10164
4953550a 10165 {}
f3cd3f5d
WF
10166};
10167
4953550a 10168/* codec SSID table for Intel Mac */
a9111321 10169static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
4953550a
TI
10170 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10171 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10172 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10173 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10174 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10175 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10176 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 10177 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 10178 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 10179 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 10180 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
10181 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10182 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10183 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 10184 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 10185 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 10186 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10187 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10188 * so apparently no perfect solution yet
4953550a
TI
10189 */
10190 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10191 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10192 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10193 {} /* terminator */
b25c9da1
WF
10194};
10195
a9111321 10196static const struct alc_config_preset alc882_presets[] = {
4953550a
TI
10197 [ALC882_3ST_DIG] = {
10198 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10199 .init_verbs = { alc882_base_init_verbs,
10200 alc882_adc1_init_verbs },
4953550a
TI
10201 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10202 .dac_nids = alc882_dac_nids,
10203 .dig_out_nid = ALC882_DIGOUT_NID,
10204 .dig_in_nid = ALC882_DIGIN_NID,
10205 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10206 .channel_mode = alc882_ch_modes,
10207 .need_dac_fix = 1,
10208 .input_mux = &alc882_capture_source,
10209 },
10210 [ALC882_6ST_DIG] = {
10211 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10212 .init_verbs = { alc882_base_init_verbs,
10213 alc882_adc1_init_verbs },
4953550a
TI
10214 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10215 .dac_nids = alc882_dac_nids,
10216 .dig_out_nid = ALC882_DIGOUT_NID,
10217 .dig_in_nid = ALC882_DIGIN_NID,
10218 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10219 .channel_mode = alc882_sixstack_modes,
10220 .input_mux = &alc882_capture_source,
10221 },
10222 [ALC882_ARIMA] = {
10223 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10224 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10225 alc882_eapd_verbs },
4953550a
TI
10226 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10227 .dac_nids = alc882_dac_nids,
10228 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10229 .channel_mode = alc882_sixstack_modes,
10230 .input_mux = &alc882_capture_source,
10231 },
10232 [ALC882_W2JC] = {
10233 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10234 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10235 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10236 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10237 .dac_nids = alc882_dac_nids,
10238 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10239 .channel_mode = alc880_threestack_modes,
10240 .need_dac_fix = 1,
10241 .input_mux = &alc882_capture_source,
10242 .dig_out_nid = ALC882_DIGOUT_NID,
10243 },
76e6f5a9
RH
10244 [ALC885_MBA21] = {
10245 .mixers = { alc885_mba21_mixer },
10246 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10247 .num_dacs = 2,
10248 .dac_nids = alc882_dac_nids,
10249 .channel_mode = alc885_mba21_ch_modes,
10250 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10251 .input_mux = &alc882_capture_source,
d922b51d 10252 .unsol_event = alc_sku_unsol_event,
76e6f5a9 10253 .setup = alc885_mba21_setup,
d922b51d 10254 .init_hook = alc_hp_automute,
76e6f5a9 10255 },
4953550a
TI
10256 [ALC885_MBP3] = {
10257 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10258 .init_verbs = { alc885_mbp3_init_verbs,
10259 alc880_gpio1_init_verbs },
be0ae923 10260 .num_dacs = 2,
4953550a 10261 .dac_nids = alc882_dac_nids,
be0ae923
TI
10262 .hp_nid = 0x04,
10263 .channel_mode = alc885_mbp_4ch_modes,
10264 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10265 .input_mux = &alc882_capture_source,
10266 .dig_out_nid = ALC882_DIGOUT_NID,
10267 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10268 .unsol_event = alc_sku_unsol_event,
4f5d1706 10269 .setup = alc885_mbp3_setup,
d922b51d 10270 .init_hook = alc_hp_automute,
4953550a
TI
10271 },
10272 [ALC885_MB5] = {
10273 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10274 .init_verbs = { alc885_mb5_init_verbs,
10275 alc880_gpio1_init_verbs },
10276 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10277 .dac_nids = alc882_dac_nids,
10278 .channel_mode = alc885_mb5_6ch_modes,
10279 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10280 .input_mux = &mb5_capture_source,
10281 .dig_out_nid = ALC882_DIGOUT_NID,
10282 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10283 .unsol_event = alc_sku_unsol_event,
9d54f08b 10284 .setup = alc885_mb5_setup,
d922b51d 10285 .init_hook = alc_hp_automute,
4953550a 10286 },
e458b1fa
LY
10287 [ALC885_MACMINI3] = {
10288 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10289 .init_verbs = { alc885_macmini3_init_verbs,
10290 alc880_gpio1_init_verbs },
10291 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10292 .dac_nids = alc882_dac_nids,
10293 .channel_mode = alc885_macmini3_6ch_modes,
10294 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10295 .input_mux = &macmini3_capture_source,
10296 .dig_out_nid = ALC882_DIGOUT_NID,
10297 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10298 .unsol_event = alc_sku_unsol_event,
9d54f08b 10299 .setup = alc885_macmini3_setup,
d922b51d 10300 .init_hook = alc_hp_automute,
e458b1fa 10301 },
4953550a
TI
10302 [ALC885_MACPRO] = {
10303 .mixers = { alc882_macpro_mixer },
10304 .init_verbs = { alc882_macpro_init_verbs },
10305 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10306 .dac_nids = alc882_dac_nids,
10307 .dig_out_nid = ALC882_DIGOUT_NID,
10308 .dig_in_nid = ALC882_DIGIN_NID,
10309 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10310 .channel_mode = alc882_ch_modes,
10311 .input_mux = &alc882_capture_source,
10312 .init_hook = alc885_macpro_init_hook,
10313 },
10314 [ALC885_IMAC24] = {
10315 .mixers = { alc885_imac24_mixer },
10316 .init_verbs = { alc885_imac24_init_verbs },
10317 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10318 .dac_nids = alc882_dac_nids,
10319 .dig_out_nid = ALC882_DIGOUT_NID,
10320 .dig_in_nid = ALC882_DIGIN_NID,
10321 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10322 .channel_mode = alc882_ch_modes,
10323 .input_mux = &alc882_capture_source,
d922b51d 10324 .unsol_event = alc_sku_unsol_event,
4f5d1706 10325 .setup = alc885_imac24_setup,
4953550a
TI
10326 .init_hook = alc885_imac24_init_hook,
10327 },
4b7e1803 10328 [ALC885_IMAC91] = {
b7cccc52 10329 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10330 .init_verbs = { alc885_imac91_init_verbs,
10331 alc880_gpio1_init_verbs },
10332 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10333 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10334 .channel_mode = alc885_mba21_ch_modes,
10335 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10336 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10337 .dig_out_nid = ALC882_DIGOUT_NID,
10338 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10339 .unsol_event = alc_sku_unsol_event,
9d54f08b 10340 .setup = alc885_imac91_setup,
d922b51d 10341 .init_hook = alc_hp_automute,
4b7e1803 10342 },
4953550a
TI
10343 [ALC882_TARGA] = {
10344 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10345 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10346 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10347 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10348 .dac_nids = alc882_dac_nids,
10349 .dig_out_nid = ALC882_DIGOUT_NID,
10350 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10351 .adc_nids = alc882_adc_nids,
10352 .capsrc_nids = alc882_capsrc_nids,
10353 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10354 .channel_mode = alc882_3ST_6ch_modes,
10355 .need_dac_fix = 1,
10356 .input_mux = &alc882_capture_source,
d922b51d 10357 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
10358 .setup = alc882_targa_setup,
10359 .init_hook = alc882_targa_automute,
4953550a
TI
10360 },
10361 [ALC882_ASUS_A7J] = {
10362 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10363 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10364 alc882_asus_a7j_verbs},
4953550a
TI
10365 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10366 .dac_nids = alc882_dac_nids,
10367 .dig_out_nid = ALC882_DIGOUT_NID,
10368 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10369 .adc_nids = alc882_adc_nids,
10370 .capsrc_nids = alc882_capsrc_nids,
10371 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10372 .channel_mode = alc882_3ST_6ch_modes,
10373 .need_dac_fix = 1,
10374 .input_mux = &alc882_capture_source,
10375 },
10376 [ALC882_ASUS_A7M] = {
10377 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10378 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10379 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10380 alc882_asus_a7m_verbs },
10381 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10382 .dac_nids = alc882_dac_nids,
10383 .dig_out_nid = ALC882_DIGOUT_NID,
10384 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10385 .channel_mode = alc880_threestack_modes,
10386 .need_dac_fix = 1,
10387 .input_mux = &alc882_capture_source,
10388 },
9c7f852e
TI
10389 [ALC883_3ST_2ch_DIG] = {
10390 .mixers = { alc883_3ST_2ch_mixer },
10391 .init_verbs = { alc883_init_verbs },
10392 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10393 .dac_nids = alc883_dac_nids,
10394 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10395 .dig_in_nid = ALC883_DIGIN_NID,
10396 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10397 .channel_mode = alc883_3ST_2ch_modes,
10398 .input_mux = &alc883_capture_source,
10399 },
10400 [ALC883_3ST_6ch_DIG] = {
10401 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10402 .init_verbs = { alc883_init_verbs },
10403 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10404 .dac_nids = alc883_dac_nids,
10405 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10406 .dig_in_nid = ALC883_DIGIN_NID,
10407 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10408 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10409 .need_dac_fix = 1,
9c7f852e 10410 .input_mux = &alc883_capture_source,
f12ab1e0 10411 },
9c7f852e
TI
10412 [ALC883_3ST_6ch] = {
10413 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10414 .init_verbs = { alc883_init_verbs },
10415 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10416 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10417 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10418 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10419 .need_dac_fix = 1,
9c7f852e 10420 .input_mux = &alc883_capture_source,
f12ab1e0 10421 },
17bba1b7
J
10422 [ALC883_3ST_6ch_INTEL] = {
10423 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10424 .init_verbs = { alc883_init_verbs },
10425 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10426 .dac_nids = alc883_dac_nids,
10427 .dig_out_nid = ALC883_DIGOUT_NID,
10428 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10429 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10430 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10431 .channel_mode = alc883_3ST_6ch_intel_modes,
10432 .need_dac_fix = 1,
10433 .input_mux = &alc883_3stack_6ch_intel,
10434 },
87a8c370
JK
10435 [ALC889A_INTEL] = {
10436 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10437 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10438 alc_hp15_unsol_verbs },
87a8c370
JK
10439 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10440 .dac_nids = alc883_dac_nids,
10441 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10442 .adc_nids = alc889_adc_nids,
10443 .dig_out_nid = ALC883_DIGOUT_NID,
10444 .dig_in_nid = ALC883_DIGIN_NID,
10445 .slave_dig_outs = alc883_slave_dig_outs,
10446 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10447 .channel_mode = alc889_8ch_intel_modes,
10448 .capsrc_nids = alc889_capsrc_nids,
10449 .input_mux = &alc889_capture_source,
4f5d1706 10450 .setup = alc889_automute_setup,
d922b51d
TI
10451 .init_hook = alc_hp_automute,
10452 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10453 .need_dac_fix = 1,
10454 },
10455 [ALC889_INTEL] = {
10456 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10457 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10458 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10459 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10460 .dac_nids = alc883_dac_nids,
10461 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10462 .adc_nids = alc889_adc_nids,
10463 .dig_out_nid = ALC883_DIGOUT_NID,
10464 .dig_in_nid = ALC883_DIGIN_NID,
10465 .slave_dig_outs = alc883_slave_dig_outs,
10466 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10467 .channel_mode = alc889_8ch_intel_modes,
10468 .capsrc_nids = alc889_capsrc_nids,
10469 .input_mux = &alc889_capture_source,
4f5d1706 10470 .setup = alc889_automute_setup,
6732bd0d 10471 .init_hook = alc889_intel_init_hook,
d922b51d 10472 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10473 .need_dac_fix = 1,
10474 },
9c7f852e
TI
10475 [ALC883_6ST_DIG] = {
10476 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10477 .init_verbs = { alc883_init_verbs },
10478 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10479 .dac_nids = alc883_dac_nids,
10480 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10481 .dig_in_nid = ALC883_DIGIN_NID,
10482 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10483 .channel_mode = alc883_sixstack_modes,
10484 .input_mux = &alc883_capture_source,
10485 },
ccc656ce 10486 [ALC883_TARGA_DIG] = {
c259249f 10487 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10488 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10489 alc883_targa_verbs},
ccc656ce
KY
10490 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10491 .dac_nids = alc883_dac_nids,
10492 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10494 .channel_mode = alc883_3ST_6ch_modes,
10495 .need_dac_fix = 1,
10496 .input_mux = &alc883_capture_source,
c259249f 10497 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10498 .setup = alc882_targa_setup,
10499 .init_hook = alc882_targa_automute,
ccc656ce
KY
10500 },
10501 [ALC883_TARGA_2ch_DIG] = {
c259249f 10502 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10503 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10504 alc883_targa_verbs},
ccc656ce
KY
10505 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10506 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10507 .adc_nids = alc883_adc_nids_alt,
10508 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10509 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10510 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10511 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10512 .channel_mode = alc883_3ST_2ch_modes,
10513 .input_mux = &alc883_capture_source,
c259249f 10514 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10515 .setup = alc882_targa_setup,
10516 .init_hook = alc882_targa_automute,
ccc656ce 10517 },
64a8be74 10518 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10519 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10520 alc883_chmode_mixer },
64a8be74 10521 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10522 alc883_targa_verbs },
64a8be74
DH
10523 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10524 .dac_nids = alc883_dac_nids,
10525 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10526 .adc_nids = alc883_adc_nids_rev,
10527 .capsrc_nids = alc883_capsrc_nids_rev,
10528 .dig_out_nid = ALC883_DIGOUT_NID,
10529 .dig_in_nid = ALC883_DIGIN_NID,
10530 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10531 .channel_mode = alc883_4ST_8ch_modes,
10532 .need_dac_fix = 1,
10533 .input_mux = &alc883_capture_source,
c259249f 10534 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10535 .setup = alc882_targa_setup,
10536 .init_hook = alc882_targa_automute,
64a8be74 10537 },
bab282b9 10538 [ALC883_ACER] = {
676a9b53 10539 .mixers = { alc883_base_mixer },
bab282b9
VA
10540 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10541 * and the headphone jack. Turn this on and rely on the
10542 * standard mute methods whenever the user wants to turn
10543 * these outputs off.
10544 */
10545 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10547 .dac_nids = alc883_dac_nids,
bab282b9
VA
10548 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10549 .channel_mode = alc883_3ST_2ch_modes,
10550 .input_mux = &alc883_capture_source,
10551 },
2880a867 10552 [ALC883_ACER_ASPIRE] = {
676a9b53 10553 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10554 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10555 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10556 .dac_nids = alc883_dac_nids,
10557 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10558 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10559 .channel_mode = alc883_3ST_2ch_modes,
10560 .input_mux = &alc883_capture_source,
d922b51d 10561 .unsol_event = alc_sku_unsol_event,
4f5d1706 10562 .setup = alc883_acer_aspire_setup,
d922b51d 10563 .init_hook = alc_hp_automute,
d1a991a6 10564 },
5b2d1eca 10565 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10566 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10567 alc883_chmode_mixer },
10568 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10569 alc888_acer_aspire_4930g_verbs },
10570 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10571 .dac_nids = alc883_dac_nids,
10572 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10573 .adc_nids = alc883_adc_nids_rev,
10574 .capsrc_nids = alc883_capsrc_nids_rev,
10575 .dig_out_nid = ALC883_DIGOUT_NID,
10576 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10577 .channel_mode = alc883_3ST_6ch_modes,
10578 .need_dac_fix = 1,
973b8cb0 10579 .const_channel_count = 6,
5b2d1eca 10580 .num_mux_defs =
ef8ef5fb
VP
10581 ARRAY_SIZE(alc888_2_capture_sources),
10582 .input_mux = alc888_2_capture_sources,
d922b51d 10583 .unsol_event = alc_sku_unsol_event,
4f5d1706 10584 .setup = alc888_acer_aspire_4930g_setup,
d922b51d 10585 .init_hook = alc_hp_automute,
d2fd4b09
TV
10586 },
10587 [ALC888_ACER_ASPIRE_6530G] = {
10588 .mixers = { alc888_acer_aspire_6530_mixer },
10589 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10590 alc888_acer_aspire_6530g_verbs },
10591 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10592 .dac_nids = alc883_dac_nids,
10593 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10594 .adc_nids = alc883_adc_nids_rev,
10595 .capsrc_nids = alc883_capsrc_nids_rev,
10596 .dig_out_nid = ALC883_DIGOUT_NID,
10597 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10598 .channel_mode = alc883_3ST_2ch_modes,
10599 .num_mux_defs =
10600 ARRAY_SIZE(alc888_2_capture_sources),
10601 .input_mux = alc888_acer_aspire_6530_sources,
d922b51d 10602 .unsol_event = alc_sku_unsol_event,
4f5d1706 10603 .setup = alc888_acer_aspire_6530g_setup,
d922b51d 10604 .init_hook = alc_hp_automute,
5b2d1eca 10605 },
3b315d70 10606 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10607 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10608 alc883_chmode_mixer },
10609 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10610 alc889_acer_aspire_8930g_verbs,
10611 alc889_eapd_verbs},
3b315d70
HM
10612 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10613 .dac_nids = alc883_dac_nids,
018df418
HM
10614 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10615 .adc_nids = alc889_adc_nids,
10616 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10617 .dig_out_nid = ALC883_DIGOUT_NID,
10618 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10619 .channel_mode = alc883_3ST_6ch_modes,
10620 .need_dac_fix = 1,
10621 .const_channel_count = 6,
10622 .num_mux_defs =
018df418
HM
10623 ARRAY_SIZE(alc889_capture_sources),
10624 .input_mux = alc889_capture_sources,
d922b51d 10625 .unsol_event = alc_sku_unsol_event,
4f5d1706 10626 .setup = alc889_acer_aspire_8930g_setup,
d922b51d 10627 .init_hook = alc_hp_automute,
f5de24b0 10628#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10629 .power_hook = alc_power_eapd,
f5de24b0 10630#endif
3b315d70 10631 },
fc86f954
DK
10632 [ALC888_ACER_ASPIRE_7730G] = {
10633 .mixers = { alc883_3ST_6ch_mixer,
10634 alc883_chmode_mixer },
10635 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10636 alc888_acer_aspire_7730G_verbs },
10637 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10638 .dac_nids = alc883_dac_nids,
10639 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10640 .adc_nids = alc883_adc_nids_rev,
10641 .capsrc_nids = alc883_capsrc_nids_rev,
10642 .dig_out_nid = ALC883_DIGOUT_NID,
10643 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10644 .channel_mode = alc883_3ST_6ch_modes,
10645 .need_dac_fix = 1,
10646 .const_channel_count = 6,
10647 .input_mux = &alc883_capture_source,
d922b51d 10648 .unsol_event = alc_sku_unsol_event,
d9477207 10649 .setup = alc888_acer_aspire_7730g_setup,
d922b51d 10650 .init_hook = alc_hp_automute,
fc86f954 10651 },
c07584c8
TD
10652 [ALC883_MEDION] = {
10653 .mixers = { alc883_fivestack_mixer,
10654 alc883_chmode_mixer },
10655 .init_verbs = { alc883_init_verbs,
b373bdeb 10656 alc883_medion_eapd_verbs },
c07584c8
TD
10657 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10658 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10659 .adc_nids = alc883_adc_nids_alt,
10660 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10661 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10662 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10663 .channel_mode = alc883_sixstack_modes,
10664 .input_mux = &alc883_capture_source,
b373bdeb 10665 },
7ad7b218
MC
10666 [ALC883_MEDION_WIM2160] = {
10667 .mixers = { alc883_medion_wim2160_mixer },
10668 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10669 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10670 .dac_nids = alc883_dac_nids,
10671 .dig_out_nid = ALC883_DIGOUT_NID,
10672 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10673 .adc_nids = alc883_adc_nids,
10674 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10675 .channel_mode = alc883_3ST_2ch_modes,
10676 .input_mux = &alc883_capture_source,
d922b51d 10677 .unsol_event = alc_sku_unsol_event,
7ad7b218 10678 .setup = alc883_medion_wim2160_setup,
d922b51d 10679 .init_hook = alc_hp_automute,
7ad7b218 10680 },
b373bdeb 10681 [ALC883_LAPTOP_EAPD] = {
676a9b53 10682 .mixers = { alc883_base_mixer },
b373bdeb
AN
10683 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10684 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10685 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10686 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10687 .channel_mode = alc883_3ST_2ch_modes,
10688 .input_mux = &alc883_capture_source,
10689 },
a65cc60f 10690 [ALC883_CLEVO_M540R] = {
10691 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10692 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10693 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10694 .dac_nids = alc883_dac_nids,
10695 .dig_out_nid = ALC883_DIGOUT_NID,
10696 .dig_in_nid = ALC883_DIGIN_NID,
10697 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10698 .channel_mode = alc883_3ST_6ch_clevo_modes,
10699 .need_dac_fix = 1,
10700 .input_mux = &alc883_capture_source,
10701 /* This machine has the hardware HP auto-muting, thus
10702 * we need no software mute via unsol event
10703 */
10704 },
0c4cc443
HRK
10705 [ALC883_CLEVO_M720] = {
10706 .mixers = { alc883_clevo_m720_mixer },
10707 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10708 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10709 .dac_nids = alc883_dac_nids,
10710 .dig_out_nid = ALC883_DIGOUT_NID,
10711 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10712 .channel_mode = alc883_3ST_2ch_modes,
10713 .input_mux = &alc883_capture_source,
0c4cc443 10714 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10715 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10716 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10717 },
bc9f98a9
KY
10718 [ALC883_LENOVO_101E_2ch] = {
10719 .mixers = { alc883_lenovo_101e_2ch_mixer},
10720 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10721 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10722 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10723 .adc_nids = alc883_adc_nids_alt,
10724 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10725 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10726 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10727 .channel_mode = alc883_3ST_2ch_modes,
10728 .input_mux = &alc883_lenovo_101e_capture_source,
e6a5e1b7
TI
10729 .setup = alc883_lenovo_101e_setup,
10730 .unsol_event = alc_sku_unsol_event,
10731 .init_hook = alc_inithook,
bc9f98a9 10732 },
272a527c
KY
10733 [ALC883_LENOVO_NB0763] = {
10734 .mixers = { alc883_lenovo_nb0763_mixer },
10735 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10736 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10737 .dac_nids = alc883_dac_nids,
272a527c
KY
10738 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10739 .channel_mode = alc883_3ST_2ch_modes,
10740 .need_dac_fix = 1,
10741 .input_mux = &alc883_lenovo_nb0763_capture_source,
d922b51d 10742 .unsol_event = alc_sku_unsol_event,
dc427170 10743 .setup = alc883_lenovo_nb0763_setup,
d922b51d 10744 .init_hook = alc_hp_automute,
272a527c
KY
10745 },
10746 [ALC888_LENOVO_MS7195_DIG] = {
10747 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10748 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10749 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10750 .dac_nids = alc883_dac_nids,
10751 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10752 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10753 .channel_mode = alc883_3ST_6ch_modes,
10754 .need_dac_fix = 1,
10755 .input_mux = &alc883_capture_source,
e6a5e1b7
TI
10756 .unsol_event = alc_sku_unsol_event,
10757 .setup = alc888_lenovo_ms7195_setup,
10758 .init_hook = alc_inithook,
189609ae
KY
10759 },
10760 [ALC883_HAIER_W66] = {
c259249f 10761 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10762 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10763 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10764 .dac_nids = alc883_dac_nids,
10765 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10766 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10767 .channel_mode = alc883_3ST_2ch_modes,
10768 .input_mux = &alc883_capture_source,
d922b51d 10769 .unsol_event = alc_sku_unsol_event,
4f5d1706 10770 .setup = alc883_haier_w66_setup,
d922b51d 10771 .init_hook = alc_hp_automute,
eea6419e 10772 },
4723c022 10773 [ALC888_3ST_HP] = {
eea6419e 10774 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10775 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10776 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10777 .dac_nids = alc883_dac_nids,
4723c022
CM
10778 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10779 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10780 .need_dac_fix = 1,
10781 .input_mux = &alc883_capture_source,
d922b51d 10782 .unsol_event = alc_sku_unsol_event,
4f5d1706 10783 .setup = alc888_3st_hp_setup,
d922b51d 10784 .init_hook = alc_hp_automute,
8341de60 10785 },
5795b9e6 10786 [ALC888_6ST_DELL] = {
f24dbdc6 10787 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10788 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10789 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10790 .dac_nids = alc883_dac_nids,
10791 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10792 .dig_in_nid = ALC883_DIGIN_NID,
10793 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10794 .channel_mode = alc883_sixstack_modes,
10795 .input_mux = &alc883_capture_source,
d922b51d 10796 .unsol_event = alc_sku_unsol_event,
4f5d1706 10797 .setup = alc888_6st_dell_setup,
d922b51d 10798 .init_hook = alc_hp_automute,
5795b9e6 10799 },
a8848bd6
AS
10800 [ALC883_MITAC] = {
10801 .mixers = { alc883_mitac_mixer },
10802 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10803 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10804 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10805 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10806 .channel_mode = alc883_3ST_2ch_modes,
10807 .input_mux = &alc883_capture_source,
d922b51d 10808 .unsol_event = alc_sku_unsol_event,
4f5d1706 10809 .setup = alc883_mitac_setup,
d922b51d 10810 .init_hook = alc_hp_automute,
a8848bd6 10811 },
fb97dc67
J
10812 [ALC883_FUJITSU_PI2515] = {
10813 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10814 .init_verbs = { alc883_init_verbs,
10815 alc883_2ch_fujitsu_pi2515_verbs},
10816 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10817 .dac_nids = alc883_dac_nids,
10818 .dig_out_nid = ALC883_DIGOUT_NID,
10819 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10820 .channel_mode = alc883_3ST_2ch_modes,
10821 .input_mux = &alc883_fujitsu_pi2515_capture_source,
d922b51d 10822 .unsol_event = alc_sku_unsol_event,
4f5d1706 10823 .setup = alc883_2ch_fujitsu_pi2515_setup,
d922b51d 10824 .init_hook = alc_hp_automute,
fb97dc67 10825 },
ef8ef5fb
VP
10826 [ALC888_FUJITSU_XA3530] = {
10827 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10828 .init_verbs = { alc883_init_verbs,
10829 alc888_fujitsu_xa3530_verbs },
10830 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10831 .dac_nids = alc883_dac_nids,
10832 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10833 .adc_nids = alc883_adc_nids_rev,
10834 .capsrc_nids = alc883_capsrc_nids_rev,
10835 .dig_out_nid = ALC883_DIGOUT_NID,
10836 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10837 .channel_mode = alc888_4ST_8ch_intel_modes,
10838 .num_mux_defs =
10839 ARRAY_SIZE(alc888_2_capture_sources),
10840 .input_mux = alc888_2_capture_sources,
d922b51d 10841 .unsol_event = alc_sku_unsol_event,
4f5d1706 10842 .setup = alc888_fujitsu_xa3530_setup,
d922b51d 10843 .init_hook = alc_hp_automute,
ef8ef5fb 10844 },
e2757d5e
KY
10845 [ALC888_LENOVO_SKY] = {
10846 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10847 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10848 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10849 .dac_nids = alc883_dac_nids,
10850 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10851 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10852 .channel_mode = alc883_sixstack_modes,
10853 .need_dac_fix = 1,
10854 .input_mux = &alc883_lenovo_sky_capture_source,
d922b51d 10855 .unsol_event = alc_sku_unsol_event,
4f5d1706 10856 .setup = alc888_lenovo_sky_setup,
d922b51d 10857 .init_hook = alc_hp_automute,
e2757d5e
KY
10858 },
10859 [ALC888_ASUS_M90V] = {
10860 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10861 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10862 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10863 .dac_nids = alc883_dac_nids,
10864 .dig_out_nid = ALC883_DIGOUT_NID,
10865 .dig_in_nid = ALC883_DIGIN_NID,
10866 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10867 .channel_mode = alc883_3ST_6ch_modes,
10868 .need_dac_fix = 1,
10869 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10870 .unsol_event = alc_sku_unsol_event,
10871 .setup = alc883_mode2_setup,
10872 .init_hook = alc_inithook,
e2757d5e
KY
10873 },
10874 [ALC888_ASUS_EEE1601] = {
10875 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10876 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10877 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10878 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10879 .dac_nids = alc883_dac_nids,
10880 .dig_out_nid = ALC883_DIGOUT_NID,
10881 .dig_in_nid = ALC883_DIGIN_NID,
10882 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10883 .channel_mode = alc883_3ST_2ch_modes,
10884 .need_dac_fix = 1,
10885 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10886 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10887 .init_hook = alc883_eee1601_inithook,
10888 },
3ab90935
WF
10889 [ALC1200_ASUS_P5Q] = {
10890 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10891 .init_verbs = { alc883_init_verbs },
10892 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10893 .dac_nids = alc883_dac_nids,
10894 .dig_out_nid = ALC1200_DIGOUT_NID,
10895 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10896 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10897 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10898 .channel_mode = alc883_sixstack_modes,
10899 .input_mux = &alc883_capture_source,
10900 },
eb4c41d3
TS
10901 [ALC889A_MB31] = {
10902 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10903 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10904 alc880_gpio1_init_verbs },
10905 .adc_nids = alc883_adc_nids,
10906 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10907 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10908 .dac_nids = alc883_dac_nids,
10909 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10910 .channel_mode = alc889A_mb31_6ch_modes,
10911 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10912 .input_mux = &alc889A_mb31_capture_source,
10913 .dig_out_nid = ALC883_DIGOUT_NID,
10914 .unsol_event = alc889A_mb31_unsol_event,
10915 .init_hook = alc889A_mb31_automute,
10916 },
3e1647c5
GG
10917 [ALC883_SONY_VAIO_TT] = {
10918 .mixers = { alc883_vaiott_mixer },
10919 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10920 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10921 .dac_nids = alc883_dac_nids,
10922 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10923 .channel_mode = alc883_3ST_2ch_modes,
10924 .input_mux = &alc883_capture_source,
d922b51d 10925 .unsol_event = alc_sku_unsol_event,
4f5d1706 10926 .setup = alc883_vaiott_setup,
d922b51d 10927 .init_hook = alc_hp_automute,
3e1647c5 10928 },
9c7f852e
TI
10929};
10930
10931
4953550a
TI
10932/*
10933 * Pin config fixes
10934 */
10935enum {
954a29c8 10936 PINFIX_ABIT_AW9D_MAX,
32eea388 10937 PINFIX_LENOVO_Y530,
954a29c8 10938 PINFIX_PB_M5210,
c3d226ab 10939 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10940};
10941
f8f25ba3
TI
10942static const struct alc_fixup alc882_fixups[] = {
10943 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10944 .type = ALC_FIXUP_PINS,
10945 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10946 { 0x15, 0x01080104 }, /* side */
10947 { 0x16, 0x01011012 }, /* rear */
10948 { 0x17, 0x01016011 }, /* clfe */
10949 { }
10950 }
f8f25ba3 10951 },
32eea388
DH
10952 [PINFIX_LENOVO_Y530] = {
10953 .type = ALC_FIXUP_PINS,
10954 .v.pins = (const struct alc_pincfg[]) {
10955 { 0x15, 0x99130112 }, /* rear int speakers */
10956 { 0x16, 0x99130111 }, /* subwoofer */
10957 { }
10958 }
10959 },
954a29c8 10960 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10961 .type = ALC_FIXUP_VERBS,
10962 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10963 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10964 {}
10965 }
954a29c8 10966 },
c3d226ab 10967 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10968 .type = ALC_FIXUP_SKU,
10969 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10970 },
4953550a
TI
10971};
10972
a9111321 10973static const struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10974 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10975 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10976 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10977 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10978 {}
10979};
10980
9c7f852e
TI
10981/*
10982 * BIOS auto configuration
10983 */
05f5f477
TI
10984static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10985 const struct auto_pin_cfg *cfg)
10986{
10987 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10988}
10989
4953550a 10990static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10991 hda_nid_t nid, int pin_type,
489008cd 10992 hda_nid_t dac)
9c7f852e 10993{
f12ab1e0
TI
10994 int idx;
10995
489008cd 10996 /* set as output */
f6c7e546 10997 alc_set_pin_output(codec, nid, pin_type);
489008cd 10998
1f0f4b80
TI
10999 if (snd_hda_get_conn_list(codec, nid, NULL) < 2)
11000 return;
11001
489008cd 11002 if (dac == 0x25)
9c7f852e 11003 idx = 4;
489008cd
TI
11004 else if (dac >= 0x02 && dac <= 0x05)
11005 idx = dac - 2;
f9700d5a 11006 else
489008cd 11007 return;
9c7f852e 11008 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
11009}
11010
1f0f4b80
TI
11011#define alc882_auto_init_dac alc880_auto_init_dac
11012
4953550a 11013static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
11014{
11015 struct alc_spec *spec = codec->spec;
11016 int i;
11017
11018 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 11019 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11020 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 11021 if (nid)
4953550a 11022 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 11023 spec->multiout.dac_nids[i]);
9c7f852e 11024 }
1f0f4b80
TI
11025 /* mute DACs */
11026 for (i = 0; i < spec->multiout.num_dacs; i++)
11027 alc882_auto_init_dac(codec, spec->multiout.dac_nids[i]);
9c7f852e
TI
11028}
11029
4953550a 11030static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
11031{
11032 struct alc_spec *spec = codec->spec;
489008cd 11033 hda_nid_t pin, dac;
5855fb80 11034 int i;
9c7f852e 11035
0a3fabe3
DH
11036 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11037 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11038 pin = spec->autocfg.hp_pins[i];
11039 if (!pin)
11040 break;
11041 dac = spec->multiout.hp_nid;
11042 if (!dac)
11043 dac = spec->multiout.dac_nids[0]; /* to front */
11044 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11045 }
489008cd 11046 }
0a3fabe3
DH
11047
11048 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11049 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11050 pin = spec->autocfg.speaker_pins[i];
11051 if (!pin)
11052 break;
11053 dac = spec->multiout.extra_out_nid[0];
11054 if (!dac)
11055 dac = spec->multiout.dac_nids[0]; /* to front */
11056 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11057 }
489008cd 11058 }
9c7f852e 11059
1f0f4b80
TI
11060 /* mute DACs */
11061 alc882_auto_init_dac(codec, spec->multiout.hp_nid);
11062 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
11063 alc882_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
4953550a
TI
11064}
11065
1f0f4b80
TI
11066#define alc882_auto_init_analog_input alc880_auto_init_analog_input
11067
4953550a
TI
11068static void alc882_auto_init_input_src(struct hda_codec *codec)
11069{
11070 struct alc_spec *spec = codec->spec;
11071 int c;
11072
11073 for (c = 0; c < spec->num_adc_nids; c++) {
4953550a
TI
11074 hda_nid_t nid = spec->capsrc_nids[c];
11075 unsigned int mux_idx;
11076 const struct hda_input_mux *imux;
11077 int conns, mute, idx, item;
7ec9c6cc 11078 unsigned int wid_type;
4953550a 11079
10696aa0
TI
11080 /* mute ADC */
11081 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11082 AC_VERB_SET_AMP_GAIN_MUTE,
11083 AMP_IN_MUTE(0));
11084
1f0f4b80
TI
11085 conns = snd_hda_get_conn_list(codec, nid, NULL);
11086 if (conns <= 0)
4953550a
TI
11087 continue;
11088 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11089 imux = &spec->input_mux[mux_idx];
5311114d
TI
11090 if (!imux->num_items && mux_idx > 0)
11091 imux = &spec->input_mux[0];
7ec9c6cc 11092 wid_type = get_wcaps_type(get_wcaps(codec, nid));
4953550a
TI
11093 for (idx = 0; idx < conns; idx++) {
11094 /* if the current connection is the selected one,
11095 * unmute it as default - otherwise mute it
11096 */
11097 mute = AMP_IN_MUTE(idx);
11098 for (item = 0; item < imux->num_items; item++) {
11099 if (imux->items[item].index == idx) {
11100 if (spec->cur_mux[c] == item)
11101 mute = AMP_IN_UNMUTE(idx);
11102 break;
11103 }
11104 }
7ec9c6cc
TI
11105 /* initialize the mute status if mute-amp is present */
11106 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
9c7f852e
TI
11107 snd_hda_codec_write(codec, nid, 0,
11108 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a 11109 mute);
7ec9c6cc
TI
11110 if (wid_type == AC_WID_AUD_SEL &&
11111 mute != AMP_IN_MUTE(idx))
4953550a
TI
11112 snd_hda_codec_write(codec, nid, 0,
11113 AC_VERB_SET_CONNECT_SEL,
11114 idx);
9c7f852e
TI
11115 }
11116 }
11117}
11118
4953550a
TI
11119/* add mic boosts if needed */
11120static int alc_auto_add_mic_boost(struct hda_codec *codec)
11121{
11122 struct alc_spec *spec = codec->spec;
66ceeb6b 11123 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 11124 int i, err;
53e8c323 11125 int type_idx = 0;
4953550a 11126 hda_nid_t nid;
5322bf27 11127 const char *prev_label = NULL;
4953550a 11128
66ceeb6b 11129 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 11130 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
11131 break;
11132 nid = cfg->inputs[i].pin;
11133 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
11134 const char *label;
11135 char boost_label[32];
11136
11137 label = hda_get_autocfg_input_label(codec, cfg, i);
11138 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
11139 type_idx++;
11140 else
11141 type_idx = 0;
5322bf27
DH
11142 prev_label = label;
11143
11144 snprintf(boost_label, sizeof(boost_label),
11145 "%s Boost Volume", label);
11146 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11147 boost_label, type_idx,
4953550a 11148 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
11149 if (err < 0)
11150 return err;
11151 }
4953550a
TI
11152 }
11153 return 0;
11154}
f511b01c 11155
9c7f852e 11156/* almost identical with ALC880 parser... */
4953550a 11157static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
11158{
11159 struct alc_spec *spec = codec->spec;
4c6d72d1 11160 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 11161 int err;
9c7f852e 11162
05f5f477
TI
11163 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11164 alc882_ignore);
9c7f852e
TI
11165 if (err < 0)
11166 return err;
05f5f477
TI
11167 if (!spec->autocfg.line_outs)
11168 return 0; /* can't find valid BIOS pin config */
776e184e 11169
cb053a82 11170 err = alc880_auto_fill_dac_nids(codec);
ce764ab2
TI
11171 if (err < 0)
11172 return err;
cb053a82 11173 err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
05f5f477
TI
11174 if (err < 0)
11175 return err;
569ed348 11176 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
11177 if (err < 0)
11178 return err;
11179 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11180 "Headphone");
05f5f477
TI
11181 if (err < 0)
11182 return err;
11183 err = alc880_auto_create_extra_out(spec,
11184 spec->autocfg.speaker_pins[0],
11185 "Speaker");
11186 if (err < 0)
11187 return err;
05f5f477 11188 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
11189 if (err < 0)
11190 return err;
11191
05f5f477
TI
11192 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11193
757899ac 11194 alc_auto_parse_digital(codec);
05f5f477
TI
11195
11196 if (spec->kctls.list)
11197 add_mixer(spec, spec->kctls.list);
11198
4953550a 11199 /* if ADC 0x07 is available, initialize it, too */
05f5f477 11200 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 11201 add_verb(spec, alc882_adc1_init_verbs);
776e184e 11202
05f5f477
TI
11203 spec->num_mux_defs = 1;
11204 spec->input_mux = &spec->private_imux[0];
11205
6227cdce 11206 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
11207
11208 err = alc_auto_add_mic_boost(codec);
11209 if (err < 0)
11210 return err;
61b9b9b1 11211
776e184e 11212 return 1; /* config found */
9c7f852e
TI
11213}
11214
11215/* additional initialization for auto-configuration model */
4953550a 11216static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 11217{
f6c7e546 11218 struct alc_spec *spec = codec->spec;
4953550a
TI
11219 alc882_auto_init_multi_out(codec);
11220 alc882_auto_init_hp_out(codec);
11221 alc882_auto_init_analog_input(codec);
11222 alc882_auto_init_input_src(codec);
757899ac 11223 alc_auto_init_digital(codec);
f6c7e546 11224 if (spec->unsol_event)
7fb0d78f 11225 alc_inithook(codec);
9c7f852e
TI
11226}
11227
4953550a 11228static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
11229{
11230 struct alc_spec *spec;
11231 int err, board_config;
11232
11233 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11234 if (spec == NULL)
11235 return -ENOMEM;
11236
11237 codec->spec = spec;
11238
1f0f4b80
TI
11239 spec->mixer_nid = 0x0b;
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
TI
11311 hda_nid_t cap;
11312 hda_nid_t nid = alc882_adc_nids[i];
11313 unsigned int wcap = get_wcaps(codec, nid);
11314 /* get type */
a22d543a 11315 wcap = get_wcaps_type(wcap);
4953550a
TI
11316 if (wcap != AC_WID_AUD_IN)
11317 continue;
11318 spec->private_adc_nids[spec->num_adc_nids] = nid;
11319 err = snd_hda_get_connections(codec, nid, &cap, 1);
11320 if (err < 0)
11321 continue;
1f0f4b80 11322 err = snd_hda_get_conn_list(codec, cap, NULL);
d11f74c6
TI
11323 if (err < 0)
11324 continue;
11325 for (j = 0; j < imux->num_items; j++)
11326 if (imux->items[j].index >= err)
11327 break;
11328 if (j < imux->num_items)
11329 continue;
4953550a
TI
11330 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11331 spec->num_adc_nids++;
61b9b9b1 11332 }
4953550a
TI
11333 spec->adc_nids = spec->private_adc_nids;
11334 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11335 }
11336
b59bdf3b 11337 set_capture_mixer(codec);
da00c244 11338
dc1eae25 11339 if (has_cdefine_beep(codec))
da00c244 11340 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11341
b5bfbc67 11342 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11343
2134ea4f
TI
11344 spec->vmaster_nid = 0x0c;
11345
9c7f852e 11346 codec->patch_ops = alc_patch_ops;
4953550a
TI
11347 if (board_config == ALC882_AUTO)
11348 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11349
11350 alc_init_jacks(codec);
cb53c626
TI
11351#ifdef CONFIG_SND_HDA_POWER_SAVE
11352 if (!spec->loopback.amplist)
4953550a 11353 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11354#endif
9c7f852e
TI
11355
11356 return 0;
11357}
11358
4953550a 11359
9c7f852e
TI
11360/*
11361 * ALC262 support
11362 */
11363
11364#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11365#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11366
11367#define alc262_dac_nids alc260_dac_nids
11368#define alc262_adc_nids alc882_adc_nids
11369#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11370#define alc262_capsrc_nids alc882_capsrc_nids
11371#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11372
11373#define alc262_modes alc260_modes
11374#define alc262_capture_source alc882_capture_source
11375
4c6d72d1 11376static const hda_nid_t alc262_dmic_adc_nids[1] = {
4e555fe5
KY
11377 /* ADC0 */
11378 0x09
11379};
11380
4c6d72d1 11381static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
4e555fe5 11382
a9111321 11383static const struct snd_kcontrol_new alc262_base_mixer[] = {
9c7f852e
TI
11384 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11385 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11386 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11387 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11388 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11389 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11390 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11391 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11392 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11393 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11394 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11395 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11396 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11397 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11398 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11399 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11400 { } /* end */
11401};
11402
ce875f07 11403/* update HP, line and mono-out pins according to the master switch */
e9427969 11404#define alc262_hp_master_update alc260_hp_master_update
ce875f07 11405
e9427969 11406static void alc262_hp_bpc_setup(struct hda_codec *codec)
ce875f07
TI
11407{
11408 struct alc_spec *spec = codec->spec;
864f92be 11409
e9427969
TI
11410 spec->autocfg.hp_pins[0] = 0x1b;
11411 spec->autocfg.speaker_pins[0] = 0x16;
11412 spec->automute = 1;
11413 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11414}
11415
e9427969 11416static void alc262_hp_wildwest_setup(struct hda_codec *codec)
ce875f07
TI
11417{
11418 struct alc_spec *spec = codec->spec;
864f92be 11419
e9427969
TI
11420 spec->autocfg.hp_pins[0] = 0x15;
11421 spec->autocfg.speaker_pins[0] = 0x16;
11422 spec->automute = 1;
11423 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11424}
11425
b72519b5 11426#define alc262_hp_master_sw_get alc260_hp_master_sw_get
e9427969 11427#define alc262_hp_master_sw_put alc260_hp_master_sw_put
ce875f07 11428
b72519b5
TI
11429#define ALC262_HP_MASTER_SWITCH \
11430 { \
11431 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11432 .name = "Master Playback Switch", \
11433 .info = snd_ctl_boolean_mono_info, \
11434 .get = alc262_hp_master_sw_get, \
11435 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11436 }, \
11437 { \
11438 .iface = NID_MAPPING, \
11439 .name = "Master Playback Switch", \
11440 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11441 }
11442
5b0cb1d8 11443
a9111321 11444static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11445 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11446 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11447 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11448 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11449 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11450 HDA_OUTPUT),
11451 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11452 HDA_OUTPUT),
9c7f852e
TI
11453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11455 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11456 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11457 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11458 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11459 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11460 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11461 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11462 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11463 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11464 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11465 { } /* end */
11466};
11467
a9111321 11468static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11469 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11470 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11471 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11472 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11473 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11474 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11475 HDA_OUTPUT),
11476 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11477 HDA_OUTPUT),
cd7509a4
KY
11478 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11479 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11480 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11483 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11484 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11485 { } /* end */
11486};
11487
a9111321 11488static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
cd7509a4
KY
11489 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11490 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11491 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11492 { } /* end */
11493};
11494
66d2a9d6 11495/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11496static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11497{
11498 struct alc_spec *spec = codec->spec;
66d2a9d6 11499
a9fd4f3f 11500 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11501 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
11502 spec->automute = 1;
11503 spec->automute_mode = ALC_AUTOMUTE_PIN;
66d2a9d6
KY
11504}
11505
a9111321 11506static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11507 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11508 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11509 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11510 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11511 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11512 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11513 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11514 { } /* end */
11515};
11516
a9111321 11517static const struct hda_verb alc262_hp_t5735_verbs[] = {
66d2a9d6
KY
11518 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11519 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11520
11521 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11522 { }
11523};
11524
a9111321 11525static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11526 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11527 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11528 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11529 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11530 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11531 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11532 { } /* end */
11533};
11534
a9111321 11535static const struct hda_verb alc262_hp_rp5700_verbs[] = {
8c427226
KY
11536 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11537 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11538 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11539 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11540 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11541 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11542 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11545 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11546 {}
11547};
11548
a9111321 11549static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
8c427226
KY
11550 .num_items = 1,
11551 .items = {
11552 { "Line", 0x1 },
11553 },
11554};
11555
42171c17 11556/* bind hp and internal speaker mute (with plug check) as master switch */
e9427969 11557#define alc262_hippo_master_update alc262_hp_master_update
42171c17 11558#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
e9427969 11559#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
42171c17
TI
11560
11561#define ALC262_HIPPO_MASTER_SWITCH \
11562 { \
11563 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11564 .name = "Master Playback Switch", \
11565 .info = snd_ctl_boolean_mono_info, \
11566 .get = alc262_hippo_master_sw_get, \
11567 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11568 }, \
11569 { \
11570 .iface = NID_MAPPING, \
11571 .name = "Master Playback Switch", \
11572 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11573 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11574 }
42171c17 11575
a9111321 11576static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
42171c17
TI
11577 ALC262_HIPPO_MASTER_SWITCH,
11578 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11579 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11580 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11581 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11582 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11583 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11584 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11585 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11586 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11587 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11588 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11589 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11590 { } /* end */
11591};
11592
a9111321 11593static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
42171c17
TI
11594 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11595 ALC262_HIPPO_MASTER_SWITCH,
11596 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11597 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11598 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11599 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11602 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11603 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11605 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11606 { } /* end */
11607};
11608
11609/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11610static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11611{
11612 struct alc_spec *spec = codec->spec;
11613
11614 spec->autocfg.hp_pins[0] = 0x15;
11615 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11616 spec->automute = 1;
11617 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11618}
11619
4f5d1706 11620static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11621{
11622 struct alc_spec *spec = codec->spec;
11623
11624 spec->autocfg.hp_pins[0] = 0x1b;
11625 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11626 spec->automute = 1;
11627 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11628}
11629
11630
a9111321 11631static const struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11632 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11633 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11636 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11637 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11638 { } /* end */
11639};
11640
a9111321 11641static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11642 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11643 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11644 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11645 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11646 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11647 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11648 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11649 { } /* end */
11650};
272a527c 11651
a9111321 11652static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
ba340e82
TV
11653 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11654 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11655 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11656 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11657 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11658 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11659 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11660 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11661 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11662 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11663 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11664 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11665 { } /* end */
11666};
11667
a9111321 11668static const struct hda_verb alc262_tyan_verbs[] = {
ba340e82
TV
11669 /* Headphone automute */
11670 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11671 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11673
11674 /* P11 AUX_IN, white 4-pin connector */
11675 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11676 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11677 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11678 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11679
11680 {}
11681};
11682
11683/* unsolicited event for HP jack sensing */
4f5d1706 11684static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11685{
a9fd4f3f 11686 struct alc_spec *spec = codec->spec;
ba340e82 11687
a9fd4f3f
TI
11688 spec->autocfg.hp_pins[0] = 0x1b;
11689 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
11690 spec->automute = 1;
11691 spec->automute_mode = ALC_AUTOMUTE_AMP;
ba340e82
TV
11692}
11693
ba340e82 11694
9c7f852e
TI
11695#define alc262_capture_mixer alc882_capture_mixer
11696#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11697
11698/*
11699 * generic initialization of ADC, input mixers and output mixers
11700 */
a9111321 11701static const struct hda_verb alc262_init_verbs[] = {
9c7f852e
TI
11702 /*
11703 * Unmute ADC0-2 and set the default input to mic-in
11704 */
11705 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11707 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11708 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11709 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11710 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11711
cb53c626 11712 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11713 * mixer widget
f12ab1e0
TI
11714 * Note: PASD motherboards uses the Line In 2 as the input for
11715 * front panel mic (mic 2)
9c7f852e
TI
11716 */
11717 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11718 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11723
11724 /*
df694daa
KY
11725 * Set up output mixers (0x0c - 0x0e)
11726 */
11727 /* set vol=0 to output mixers */
11728 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11730 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11731 /* set up input amps for analog loopback */
11732 /* Amp Indices: DAC = 0, mixer = 1 */
11733 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11734 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11735 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11736 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11737 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11738 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11739
11740 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11741 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11742 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11743 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11744 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11745 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11746
11747 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11749 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11750 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11751 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11752
df694daa
KY
11753 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11754 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11755
df694daa
KY
11756 /* FIXME: use matrix-type input source selection */
11757 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11758 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11763 /* Input mixer2 */
11764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11768 /* Input mixer3 */
11769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11773
11774 { }
11775};
1da177e4 11776
a9111321 11777static const struct hda_verb alc262_eapd_verbs[] = {
4e555fe5
KY
11778 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11779 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11780 { }
11781};
11782
a9111321 11783static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
ccc656ce
KY
11784 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11785 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11786 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11787
11788 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11789 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11790 {}
11791};
11792
a9111321 11793static const struct hda_verb alc262_sony_unsol_verbs[] = {
272a527c
KY
11794 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11795 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11796 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11797
11798 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11800 {}
272a527c
KY
11801};
11802
a9111321 11803static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
4e555fe5
KY
11804 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11805 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11806 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11807 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11808 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11809 { } /* end */
11810};
11811
a9111321 11812static const struct hda_verb alc262_toshiba_s06_verbs[] = {
4e555fe5
KY
11813 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11814 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11815 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11816 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11817 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11818 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11819 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11820 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11821 {}
11822};
11823
4f5d1706 11824static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11825{
a9fd4f3f
TI
11826 struct alc_spec *spec = codec->spec;
11827
11828 spec->autocfg.hp_pins[0] = 0x15;
11829 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11830 spec->ext_mic.pin = 0x18;
11831 spec->ext_mic.mux_idx = 0;
11832 spec->int_mic.pin = 0x12;
11833 spec->int_mic.mux_idx = 9;
11834 spec->auto_mic = 1;
d922b51d
TI
11835 spec->automute = 1;
11836 spec->automute_mode = ALC_AUTOMUTE_PIN;
4e555fe5
KY
11837}
11838
e8f9ae2a
PT
11839/*
11840 * nec model
11841 * 0x15 = headphone
11842 * 0x16 = internal speaker
11843 * 0x18 = external mic
11844 */
11845
a9111321 11846static const struct snd_kcontrol_new alc262_nec_mixer[] = {
e8f9ae2a
PT
11847 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11848 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11849
11850 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11851 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11852 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11853
11854 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11855 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11856 { } /* end */
11857};
11858
a9111321 11859static const struct hda_verb alc262_nec_verbs[] = {
e8f9ae2a
PT
11860 /* Unmute Speaker */
11861 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11862
11863 /* Headphone */
11864 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11865 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11866
11867 /* External mic to headphone */
11868 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11869 /* External mic to speaker */
11870 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11871 {}
11872};
11873
834be88d
TI
11874/*
11875 * fujitsu model
5d9fab2d
TV
11876 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11877 * 0x1b = port replicator headphone out
834be88d
TI
11878 */
11879
20f5e0b3 11880#define ALC_HP_EVENT ALC880_HP_EVENT
834be88d 11881
a9111321 11882static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
834be88d
TI
11883 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11884 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11885 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11886 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11887 {}
11888};
11889
a9111321 11890static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
0e31daf7
J
11891 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11892 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11893 {}
11894};
11895
a9111321 11896static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
e2595322
DC
11897 /* Front Mic pin: input vref at 50% */
11898 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11899 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11900 {}
11901};
11902
a9111321 11903static const struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11904 .num_items = 3,
834be88d
TI
11905 .items = {
11906 { "Mic", 0x0 },
28c4edb7 11907 { "Internal Mic", 0x1 },
834be88d
TI
11908 { "CD", 0x4 },
11909 },
11910};
11911
a9111321 11912static const struct hda_input_mux alc262_HP_capture_source = {
9c7f852e
TI
11913 .num_items = 5,
11914 .items = {
11915 { "Mic", 0x0 },
accbe498 11916 { "Front Mic", 0x1 },
9c7f852e
TI
11917 { "Line", 0x2 },
11918 { "CD", 0x4 },
11919 { "AUX IN", 0x6 },
11920 },
11921};
11922
a9111321 11923static const struct hda_input_mux alc262_HP_D7000_capture_source = {
accbe498 11924 .num_items = 4,
11925 .items = {
11926 { "Mic", 0x0 },
11927 { "Front Mic", 0x2 },
11928 { "Line", 0x1 },
11929 { "CD", 0x4 },
11930 },
11931};
11932
0f0f391c 11933static void alc262_fujitsu_setup(struct hda_codec *codec)
834be88d
TI
11934{
11935 struct alc_spec *spec = codec->spec;
834be88d 11936
0f0f391c
TI
11937 spec->autocfg.hp_pins[0] = 0x14;
11938 spec->autocfg.hp_pins[1] = 0x1b;
11939 spec->autocfg.speaker_pins[0] = 0x15;
11940 spec->automute = 1;
11941 spec->automute_mode = ALC_AUTOMUTE_AMP;
ebc7a406
TI
11942}
11943
834be88d 11944/* bind volumes of both NID 0x0c and 0x0d */
a9111321 11945static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
cca3b371
TI
11946 .ops = &snd_hda_bind_vol,
11947 .values = {
11948 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11949 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11950 0
11951 },
11952};
834be88d 11953
a9111321 11954static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11955 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11956 {
11957 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11958 .name = "Master Playback Switch",
0f0f391c
TI
11959 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11960 .info = snd_ctl_boolean_mono_info,
11961 .get = alc262_hp_master_sw_get,
11962 .put = alc262_hp_master_sw_put,
834be88d 11963 },
5b0cb1d8
JK
11964 {
11965 .iface = NID_MAPPING,
11966 .name = "Master Playback Switch",
11967 .private_value = 0x1b,
11968 },
834be88d
TI
11969 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11970 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11971 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11974 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11975 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11976 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11977 { } /* end */
11978};
11979
0f0f391c 11980static void alc262_lenovo_3000_setup(struct hda_codec *codec)
0e31daf7 11981{
0f0f391c 11982 struct alc_spec *spec = codec->spec;
0e31daf7 11983
0f0f391c
TI
11984 spec->autocfg.hp_pins[0] = 0x1b;
11985 spec->autocfg.speaker_pins[0] = 0x14;
11986 spec->autocfg.speaker_pins[1] = 0x16;
11987 spec->automute = 1;
11988 spec->automute_mode = ALC_AUTOMUTE_AMP;
0e31daf7
J
11989}
11990
a9111321 11991static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
0e31daf7
J
11992 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11993 {
11994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11995 .name = "Master Playback Switch",
0f0f391c
TI
11996 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11997 .info = snd_ctl_boolean_mono_info,
11998 .get = alc262_hp_master_sw_get,
11999 .put = alc262_hp_master_sw_put,
0e31daf7
J
12000 },
12001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 12003 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
12004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12005 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12006 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
12007 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12008 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
12009 { } /* end */
12010};
12011
a9111321 12012static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9f99a638 12013 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 12014 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
12015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12016 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12017 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
12018 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12019 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 12020 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
12021 { } /* end */
12022};
12023
304dcaac 12024/* additional init verbs for Benq laptops */
a9111321 12025static const struct hda_verb alc262_EAPD_verbs[] = {
304dcaac
TI
12026 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12027 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12028 {}
12029};
12030
a9111321 12031static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
83c34218
KY
12032 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12033 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12034
12035 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12036 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12037 {}
12038};
12039
f651b50b 12040/* Samsung Q1 Ultra Vista model setup */
a9111321 12041static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
12042 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12043 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
12044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
12046 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12047 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
12048 { } /* end */
12049};
12050
a9111321 12051static const struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
12052 /* output mixer */
12053 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12054 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12056 /* speaker */
12057 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12059 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12060 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12061 /* HP */
f651b50b 12062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
12063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12065 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12066 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12067 /* internal mic */
12068 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12070 /* ADC, choose mic */
12071 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12072 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12073 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12079 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12080 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12081 {}
12082};
12083
f651b50b
TD
12084/* mute/unmute internal speaker according to the hp jack and mute state */
12085static void alc262_ultra_automute(struct hda_codec *codec)
12086{
12087 struct alc_spec *spec = codec->spec;
12088 unsigned int mute;
f651b50b 12089
bb9f76cd
TI
12090 mute = 0;
12091 /* auto-mute only when HP is used as HP */
12092 if (!spec->cur_mux[0]) {
864f92be 12093 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12094 if (spec->jack_present)
12095 mute = HDA_AMP_MUTE;
f651b50b 12096 }
bb9f76cd
TI
12097 /* mute/unmute internal speaker */
12098 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12099 HDA_AMP_MUTE, mute);
12100 /* mute/unmute HP */
12101 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12102 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12103}
12104
12105/* unsolicited event for HP jack sensing */
12106static void alc262_ultra_unsol_event(struct hda_codec *codec,
12107 unsigned int res)
12108{
12109 if ((res >> 26) != ALC880_HP_EVENT)
12110 return;
12111 alc262_ultra_automute(codec);
12112}
12113
a9111321 12114static const struct hda_input_mux alc262_ultra_capture_source = {
bb9f76cd
TI
12115 .num_items = 2,
12116 .items = {
12117 { "Mic", 0x1 },
12118 { "Headphone", 0x7 },
12119 },
12120};
12121
12122static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12123 struct snd_ctl_elem_value *ucontrol)
12124{
12125 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12126 struct alc_spec *spec = codec->spec;
12127 int ret;
12128
54cbc9ab 12129 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12130 if (!ret)
12131 return 0;
12132 /* reprogram the HP pin as mic or HP according to the input source */
12133 snd_hda_codec_write_cache(codec, 0x15, 0,
12134 AC_VERB_SET_PIN_WIDGET_CONTROL,
12135 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12136 alc262_ultra_automute(codec); /* mute/unmute HP */
12137 return ret;
12138}
12139
a9111321 12140static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
bb9f76cd
TI
12141 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12142 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12143 {
12144 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12145 .name = "Capture Source",
54cbc9ab
TI
12146 .info = alc_mux_enum_info,
12147 .get = alc_mux_enum_get,
bb9f76cd
TI
12148 .put = alc262_ultra_mux_enum_put,
12149 },
5b0cb1d8
JK
12150 {
12151 .iface = NID_MAPPING,
12152 .name = "Capture Source",
12153 .private_value = 0x15,
12154 },
bb9f76cd
TI
12155 { } /* end */
12156};
12157
c3fc1f50
TI
12158/* We use two mixers depending on the output pin; 0x16 is a mono output
12159 * and thus it's bound with a different mixer.
12160 * This function returns which mixer amp should be used.
12161 */
12162static int alc262_check_volbit(hda_nid_t nid)
12163{
12164 if (!nid)
12165 return 0;
12166 else if (nid == 0x16)
12167 return 2;
12168 else
12169 return 1;
12170}
12171
12172static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12173 const char *pfx, int *vbits, int idx)
c3fc1f50 12174{
c3fc1f50
TI
12175 unsigned long val;
12176 int vbit;
12177
12178 vbit = alc262_check_volbit(nid);
12179 if (!vbit)
12180 return 0;
12181 if (*vbits & vbit) /* a volume control for this mixer already there */
12182 return 0;
12183 *vbits |= vbit;
c3fc1f50
TI
12184 if (vbit == 2)
12185 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12186 else
12187 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12188 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12189}
12190
12191static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12192 const char *pfx, int idx)
c3fc1f50 12193{
c3fc1f50
TI
12194 unsigned long val;
12195
12196 if (!nid)
12197 return 0;
c3fc1f50
TI
12198 if (nid == 0x16)
12199 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12200 else
12201 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12202 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12203}
12204
df694daa 12205/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12206static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12207 const struct auto_pin_cfg *cfg)
df694daa 12208{
c3fc1f50
TI
12209 const char *pfx;
12210 int vbits;
6843ca16 12211 int i, index, err;
df694daa
KY
12212
12213 spec->multiout.num_dacs = 1; /* only use one dac */
12214 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 12215 spec->private_dac_nids[0] = 2;
df694daa 12216
033688a5 12217 for (i = 0; i < 2; i++) {
6843ca16
TI
12218 pfx = alc_get_line_out_pfx(spec, i, true, &index);
12219 if (!pfx)
12220 pfx = "PCM";
12221 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx,
12222 index);
033688a5
TI
12223 if (err < 0)
12224 return err;
12225 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12226 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12227 "Speaker", i);
12228 if (err < 0)
12229 return err;
12230 }
12231 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12232 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12233 "Headphone", i);
12234 if (err < 0)
12235 return err;
12236 }
12237 }
df694daa 12238
c3fc1f50
TI
12239 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12240 alc262_check_volbit(cfg->speaker_pins[0]) |
12241 alc262_check_volbit(cfg->hp_pins[0]);
c3fc1f50 12242 vbits = 0;
033688a5 12243 for (i = 0; i < 2; i++) {
6843ca16
TI
12244 pfx = alc_get_line_out_pfx(spec, i, true, &index);
12245 if (!pfx)
12246 pfx = "PCM";
033688a5
TI
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 12269
a9111321 12270static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
9c7f852e
TI
12271 /*
12272 * Unmute ADC0-2 and set the default input to mic-in
12273 */
12274 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12276 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12277 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12278 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12279 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12280
cb53c626 12281 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12282 * mixer widget
f12ab1e0
TI
12283 * Note: PASD motherboards uses the Line In 2 as the input for
12284 * front panel mic (mic 2)
9c7f852e
TI
12285 */
12286 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12291 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12292 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12293 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12294
9c7f852e
TI
12295 /*
12296 * Set up output mixers (0x0c - 0x0e)
12297 */
12298 /* set vol=0 to output mixers */
12299 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12300 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12301 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12302
12303 /* set up input amps for analog loopback */
12304 /* Amp Indices: DAC = 0, mixer = 1 */
12305 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12307 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12308 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12309 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12310 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12311
ce875f07 12312 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12313 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12314 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12315
12316 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12317 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12318
12319 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12320 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12321
12322 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12323 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12324 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12326 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12327
0e4835c1 12328 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12329 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12330 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12331 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12332 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12333 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12334
12335
12336 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12337 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12338 /* Input mixer1: only unmute Mic */
9c7f852e 12339 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12340 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12341 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12342 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12343 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12344 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12345 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12346 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12348 /* Input mixer2 */
12349 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12350 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12351 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12352 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12353 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12354 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12355 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12356 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12357 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12358 /* Input mixer3 */
12359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12360 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12361 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12362 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12363 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12364 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12365 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12366 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12367 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12368
ce875f07
TI
12369 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12370
9c7f852e
TI
12371 { }
12372};
12373
a9111321 12374static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
cd7509a4
KY
12375 /*
12376 * Unmute ADC0-2 and set the default input to mic-in
12377 */
12378 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12379 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12380 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12381 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12382 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12383 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12384
cb53c626 12385 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12386 * mixer widget
12387 * Note: PASD motherboards uses the Line In 2 as the input for front
12388 * panel mic (mic 2)
12389 */
12390 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12391 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12392 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12393 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12394 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12395 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12396 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12399 /*
12400 * Set up output mixers (0x0c - 0x0e)
12401 */
12402 /* set vol=0 to output mixers */
12403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12404 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12405 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12406
12407 /* set up input amps for analog loopback */
12408 /* Amp Indices: DAC = 0, mixer = 1 */
12409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12414 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12415
12416
12417 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12418 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12419 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12420 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12421 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12422 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12423 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12424
12425 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12426 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12427
12428 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12429 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12430
12431 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12434 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12435 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12436 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12437
12438 /* FIXME: use matrix-type input source selection */
12439 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12440 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12441 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12446 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12448 /* Input mixer2 */
12449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12451 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12454 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12455 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12456 /* Input mixer3 */
12457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12460 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12461 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12462 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12463 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12464
ce875f07
TI
12465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12466
cd7509a4
KY
12467 { }
12468};
12469
a9111321 12470static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
9f99a638
HM
12471
12472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12474 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12475
12476 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12477 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12478 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12479 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12480
12481 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12483 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12484 {}
12485};
12486
18675e42
TI
12487/*
12488 * Pin config fixes
12489 */
12490enum {
12491 PINFIX_FSC_H270,
d2a19da7 12492 PINFIX_HP_Z200,
18675e42
TI
12493};
12494
12495static const struct alc_fixup alc262_fixups[] = {
12496 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12497 .type = ALC_FIXUP_PINS,
12498 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12499 { 0x14, 0x99130110 }, /* speaker */
12500 { 0x15, 0x0221142f }, /* front HP */
12501 { 0x1b, 0x0121141f }, /* rear HP */
12502 { }
12503 }
12504 },
d2a19da7
DH
12505 [PINFIX_HP_Z200] = {
12506 .type = ALC_FIXUP_PINS,
12507 .v.pins = (const struct alc_pincfg[]) {
12508 { 0x16, 0x99130120 }, /* internal speaker */
12509 { }
12510 }
12511 },
18675e42
TI
12512};
12513
a9111321 12514static const struct snd_pci_quirk alc262_fixup_tbl[] = {
d2a19da7 12515 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
18675e42
TI
12516 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12517 {}
12518};
12519
9f99a638 12520
cb53c626
TI
12521#ifdef CONFIG_SND_HDA_POWER_SAVE
12522#define alc262_loopbacks alc880_loopbacks
12523#endif
12524
def319f9 12525/* pcm configuration: identical with ALC880 */
df694daa
KY
12526#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12527#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12528#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12529#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12530
12531/*
12532 * BIOS auto configuration
12533 */
12534static int alc262_parse_auto_config(struct hda_codec *codec)
12535{
12536 struct alc_spec *spec = codec->spec;
12537 int err;
4c6d72d1 12538 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
df694daa 12539
f12ab1e0
TI
12540 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12541 alc262_ignore);
12542 if (err < 0)
df694daa 12543 return err;
e64f14f4 12544 if (!spec->autocfg.line_outs) {
0852d7a6 12545 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12546 spec->multiout.max_channels = 2;
12547 spec->no_analog = 1;
12548 goto dig_only;
12549 }
df694daa 12550 return 0; /* can't find valid BIOS pin config */
e64f14f4 12551 }
f12ab1e0
TI
12552 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12553 if (err < 0)
12554 return err;
05f5f477 12555 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12556 if (err < 0)
df694daa
KY
12557 return err;
12558
12559 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12560
e64f14f4 12561 dig_only:
757899ac 12562 alc_auto_parse_digital(codec);
df694daa 12563
603c4019 12564 if (spec->kctls.list)
d88897ea 12565 add_mixer(spec, spec->kctls.list);
df694daa 12566
a1e8d2da 12567 spec->num_mux_defs = 1;
61b9b9b1 12568 spec->input_mux = &spec->private_imux[0];
df694daa 12569
776e184e
TI
12570 err = alc_auto_add_mic_boost(codec);
12571 if (err < 0)
12572 return err;
12573
6227cdce 12574 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12575
df694daa
KY
12576 return 1;
12577}
12578
12579#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12580#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12581#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12582#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12583
12584
12585/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12586static void alc262_auto_init(struct hda_codec *codec)
df694daa 12587{
f6c7e546 12588 struct alc_spec *spec = codec->spec;
df694daa
KY
12589 alc262_auto_init_multi_out(codec);
12590 alc262_auto_init_hp_out(codec);
12591 alc262_auto_init_analog_input(codec);
f511b01c 12592 alc262_auto_init_input_src(codec);
757899ac 12593 alc_auto_init_digital(codec);
f6c7e546 12594 if (spec->unsol_event)
7fb0d78f 12595 alc_inithook(codec);
df694daa
KY
12596}
12597
12598/*
12599 * configuration and preset
12600 */
ea734963 12601static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12602 [ALC262_BASIC] = "basic",
12603 [ALC262_HIPPO] = "hippo",
12604 [ALC262_HIPPO_1] = "hippo_1",
12605 [ALC262_FUJITSU] = "fujitsu",
12606 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12607 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12608 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12609 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12610 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12611 [ALC262_BENQ_T31] = "benq-t31",
12612 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12613 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12614 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12615 [ALC262_ULTRA] = "ultra",
0e31daf7 12616 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12617 [ALC262_NEC] = "nec",
ba340e82 12618 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12619 [ALC262_AUTO] = "auto",
12620};
12621
a9111321 12622static const struct snd_pci_quirk alc262_cfg_tbl[] = {
f5fcc13c 12623 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12624 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12625 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12626 ALC262_HP_BPC),
12627 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12628 ALC262_HP_BPC),
5734a07c
TI
12629 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12630 ALC262_HP_BPC),
d2a19da7
DH
12631 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12632 ALC262_AUTO),
53eff7e1
TI
12633 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12634 ALC262_HP_BPC),
cd7509a4 12635 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12636 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12637 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12638 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12639 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12640 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12641 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12642 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12643 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12644 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12645 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12646 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12647 ALC262_HP_TC_T5735),
8c427226 12648 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12649 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12650 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12651 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12652 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12653 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12654 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12655 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12656#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12657 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12658 ALC262_SONY_ASSAMD),
c5b5165c 12659#endif
36ca6e13 12660 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12661 ALC262_TOSHIBA_RX1),
80ffe869 12662 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12663 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12664 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12665 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12666 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12667 ALC262_ULTRA),
3e420e78 12668 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12669 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12670 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12671 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12672 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12673 {}
12674};
12675
a9111321 12676static const struct alc_config_preset alc262_presets[] = {
df694daa
KY
12677 [ALC262_BASIC] = {
12678 .mixers = { alc262_base_mixer },
12679 .init_verbs = { alc262_init_verbs },
12680 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12681 .dac_nids = alc262_dac_nids,
12682 .hp_nid = 0x03,
12683 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12684 .channel_mode = alc262_modes,
a3bcba38 12685 .input_mux = &alc262_capture_source,
df694daa 12686 },
ccc656ce 12687 [ALC262_HIPPO] = {
42171c17 12688 .mixers = { alc262_hippo_mixer },
6732bd0d 12689 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12690 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12691 .dac_nids = alc262_dac_nids,
12692 .hp_nid = 0x03,
12693 .dig_out_nid = ALC262_DIGOUT_NID,
12694 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12695 .channel_mode = alc262_modes,
12696 .input_mux = &alc262_capture_source,
e9427969 12697 .unsol_event = alc_sku_unsol_event,
4f5d1706 12698 .setup = alc262_hippo_setup,
e9427969 12699 .init_hook = alc_inithook,
ccc656ce
KY
12700 },
12701 [ALC262_HIPPO_1] = {
12702 .mixers = { alc262_hippo1_mixer },
12703 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12704 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12705 .dac_nids = alc262_dac_nids,
12706 .hp_nid = 0x02,
12707 .dig_out_nid = ALC262_DIGOUT_NID,
12708 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12709 .channel_mode = alc262_modes,
12710 .input_mux = &alc262_capture_source,
e9427969 12711 .unsol_event = alc_sku_unsol_event,
4f5d1706 12712 .setup = alc262_hippo1_setup,
e9427969 12713 .init_hook = alc_inithook,
ccc656ce 12714 },
834be88d
TI
12715 [ALC262_FUJITSU] = {
12716 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12717 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12718 alc262_fujitsu_unsol_verbs },
834be88d
TI
12719 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12720 .dac_nids = alc262_dac_nids,
12721 .hp_nid = 0x03,
12722 .dig_out_nid = ALC262_DIGOUT_NID,
12723 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12724 .channel_mode = alc262_modes,
12725 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12726 .unsol_event = alc_sku_unsol_event,
12727 .setup = alc262_fujitsu_setup,
12728 .init_hook = alc_inithook,
834be88d 12729 },
9c7f852e
TI
12730 [ALC262_HP_BPC] = {
12731 .mixers = { alc262_HP_BPC_mixer },
12732 .init_verbs = { alc262_HP_BPC_init_verbs },
12733 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12734 .dac_nids = alc262_dac_nids,
12735 .hp_nid = 0x03,
12736 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12737 .channel_mode = alc262_modes,
12738 .input_mux = &alc262_HP_capture_source,
e9427969
TI
12739 .unsol_event = alc_sku_unsol_event,
12740 .setup = alc262_hp_bpc_setup,
12741 .init_hook = alc_inithook,
f12ab1e0 12742 },
cd7509a4
KY
12743 [ALC262_HP_BPC_D7000_WF] = {
12744 .mixers = { alc262_HP_BPC_WildWest_mixer },
12745 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12746 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12747 .dac_nids = alc262_dac_nids,
12748 .hp_nid = 0x03,
12749 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12750 .channel_mode = alc262_modes,
accbe498 12751 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12752 .unsol_event = alc_sku_unsol_event,
12753 .setup = alc262_hp_wildwest_setup,
12754 .init_hook = alc_inithook,
f12ab1e0 12755 },
cd7509a4
KY
12756 [ALC262_HP_BPC_D7000_WL] = {
12757 .mixers = { alc262_HP_BPC_WildWest_mixer,
12758 alc262_HP_BPC_WildWest_option_mixer },
12759 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12760 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12761 .dac_nids = alc262_dac_nids,
12762 .hp_nid = 0x03,
12763 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12764 .channel_mode = alc262_modes,
accbe498 12765 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12766 .unsol_event = alc_sku_unsol_event,
12767 .setup = alc262_hp_wildwest_setup,
12768 .init_hook = alc_inithook,
f12ab1e0 12769 },
66d2a9d6
KY
12770 [ALC262_HP_TC_T5735] = {
12771 .mixers = { alc262_hp_t5735_mixer },
12772 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12773 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12774 .dac_nids = alc262_dac_nids,
12775 .hp_nid = 0x03,
12776 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12777 .channel_mode = alc262_modes,
12778 .input_mux = &alc262_capture_source,
dc99be47 12779 .unsol_event = alc_sku_unsol_event,
4f5d1706 12780 .setup = alc262_hp_t5735_setup,
dc99be47 12781 .init_hook = alc_inithook,
8c427226
KY
12782 },
12783 [ALC262_HP_RP5700] = {
12784 .mixers = { alc262_hp_rp5700_mixer },
12785 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12786 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12787 .dac_nids = alc262_dac_nids,
12788 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12789 .channel_mode = alc262_modes,
12790 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12791 },
304dcaac
TI
12792 [ALC262_BENQ_ED8] = {
12793 .mixers = { alc262_base_mixer },
12794 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12795 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12796 .dac_nids = alc262_dac_nids,
12797 .hp_nid = 0x03,
12798 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12799 .channel_mode = alc262_modes,
12800 .input_mux = &alc262_capture_source,
f12ab1e0 12801 },
272a527c
KY
12802 [ALC262_SONY_ASSAMD] = {
12803 .mixers = { alc262_sony_mixer },
12804 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12805 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12806 .dac_nids = alc262_dac_nids,
12807 .hp_nid = 0x02,
12808 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12809 .channel_mode = alc262_modes,
12810 .input_mux = &alc262_capture_source,
e9427969 12811 .unsol_event = alc_sku_unsol_event,
4f5d1706 12812 .setup = alc262_hippo_setup,
e9427969 12813 .init_hook = alc_inithook,
83c34218
KY
12814 },
12815 [ALC262_BENQ_T31] = {
12816 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12817 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12818 alc_hp15_unsol_verbs },
83c34218
KY
12819 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12820 .dac_nids = alc262_dac_nids,
12821 .hp_nid = 0x03,
12822 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12823 .channel_mode = alc262_modes,
12824 .input_mux = &alc262_capture_source,
e9427969 12825 .unsol_event = alc_sku_unsol_event,
4f5d1706 12826 .setup = alc262_hippo_setup,
e9427969 12827 .init_hook = alc_inithook,
ea1fb29a 12828 },
f651b50b 12829 [ALC262_ULTRA] = {
f9e336f6
TI
12830 .mixers = { alc262_ultra_mixer },
12831 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12832 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12833 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12834 .dac_nids = alc262_dac_nids,
f651b50b
TD
12835 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12836 .channel_mode = alc262_modes,
12837 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12838 .adc_nids = alc262_adc_nids, /* ADC0 */
12839 .capsrc_nids = alc262_capsrc_nids,
12840 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12841 .unsol_event = alc262_ultra_unsol_event,
12842 .init_hook = alc262_ultra_automute,
12843 },
0e31daf7
J
12844 [ALC262_LENOVO_3000] = {
12845 .mixers = { alc262_lenovo_3000_mixer },
12846 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12847 alc262_lenovo_3000_unsol_verbs,
12848 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12849 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12850 .dac_nids = alc262_dac_nids,
12851 .hp_nid = 0x03,
12852 .dig_out_nid = ALC262_DIGOUT_NID,
12853 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12854 .channel_mode = alc262_modes,
12855 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12856 .unsol_event = alc_sku_unsol_event,
12857 .setup = alc262_lenovo_3000_setup,
12858 .init_hook = alc_inithook,
0e31daf7 12859 },
e8f9ae2a
PT
12860 [ALC262_NEC] = {
12861 .mixers = { alc262_nec_mixer },
12862 .init_verbs = { alc262_nec_verbs },
12863 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12864 .dac_nids = alc262_dac_nids,
12865 .hp_nid = 0x03,
12866 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12867 .channel_mode = alc262_modes,
12868 .input_mux = &alc262_capture_source,
12869 },
4e555fe5
KY
12870 [ALC262_TOSHIBA_S06] = {
12871 .mixers = { alc262_toshiba_s06_mixer },
12872 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12873 alc262_eapd_verbs },
12874 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12875 .capsrc_nids = alc262_dmic_capsrc_nids,
12876 .dac_nids = alc262_dac_nids,
12877 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12878 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12879 .dig_out_nid = ALC262_DIGOUT_NID,
12880 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12881 .channel_mode = alc262_modes,
4f5d1706
TI
12882 .unsol_event = alc_sku_unsol_event,
12883 .setup = alc262_toshiba_s06_setup,
12884 .init_hook = alc_inithook,
4e555fe5 12885 },
9f99a638
HM
12886 [ALC262_TOSHIBA_RX1] = {
12887 .mixers = { alc262_toshiba_rx1_mixer },
12888 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12889 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12890 .dac_nids = alc262_dac_nids,
12891 .hp_nid = 0x03,
12892 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12893 .channel_mode = alc262_modes,
12894 .input_mux = &alc262_capture_source,
e9427969 12895 .unsol_event = alc_sku_unsol_event,
4f5d1706 12896 .setup = alc262_hippo_setup,
e9427969 12897 .init_hook = alc_inithook,
9f99a638 12898 },
ba340e82
TV
12899 [ALC262_TYAN] = {
12900 .mixers = { alc262_tyan_mixer },
12901 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12902 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12903 .dac_nids = alc262_dac_nids,
12904 .hp_nid = 0x02,
12905 .dig_out_nid = ALC262_DIGOUT_NID,
12906 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12907 .channel_mode = alc262_modes,
12908 .input_mux = &alc262_capture_source,
d922b51d 12909 .unsol_event = alc_sku_unsol_event,
4f5d1706 12910 .setup = alc262_tyan_setup,
d922b51d 12911 .init_hook = alc_hp_automute,
ba340e82 12912 },
df694daa
KY
12913};
12914
12915static int patch_alc262(struct hda_codec *codec)
12916{
12917 struct alc_spec *spec;
12918 int board_config;
12919 int err;
12920
dc041e0b 12921 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12922 if (spec == NULL)
12923 return -ENOMEM;
12924
12925 codec->spec = spec;
1f0f4b80
TI
12926
12927 spec->mixer_nid = 0x0b;
12928
df694daa 12929#if 0
f12ab1e0
TI
12930 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12931 * under-run
12932 */
df694daa
KY
12933 {
12934 int tmp;
12935 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12936 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12937 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12938 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12939 }
12940#endif
da00c244 12941 alc_auto_parse_customize_define(codec);
df694daa 12942
2c3bf9ab
TI
12943 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12944
f5fcc13c
TI
12945 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12946 alc262_models,
12947 alc262_cfg_tbl);
cd7509a4 12948
f5fcc13c 12949 if (board_config < 0) {
9a11f1aa
TI
12950 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12951 codec->chip_name);
df694daa
KY
12952 board_config = ALC262_AUTO;
12953 }
12954
b5bfbc67
TI
12955 if (board_config == ALC262_AUTO) {
12956 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12957 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12958 }
18675e42 12959
df694daa
KY
12960 if (board_config == ALC262_AUTO) {
12961 /* automatic parse from the BIOS config */
12962 err = alc262_parse_auto_config(codec);
12963 if (err < 0) {
12964 alc_free(codec);
12965 return err;
f12ab1e0 12966 } else if (!err) {
9c7f852e
TI
12967 printk(KERN_INFO
12968 "hda_codec: Cannot set up configuration "
12969 "from BIOS. Using base mode...\n");
df694daa
KY
12970 board_config = ALC262_BASIC;
12971 }
12972 }
12973
dc1eae25 12974 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12975 err = snd_hda_attach_beep_device(codec, 0x1);
12976 if (err < 0) {
12977 alc_free(codec);
12978 return err;
12979 }
680cd536
KK
12980 }
12981
df694daa 12982 if (board_config != ALC262_AUTO)
e9c364c0 12983 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12984
df694daa
KY
12985 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12986 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12987
df694daa
KY
12988 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12989 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12990
f12ab1e0 12991 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12992 int i;
12993 /* check whether the digital-mic has to be supported */
12994 for (i = 0; i < spec->input_mux->num_items; i++) {
12995 if (spec->input_mux->items[i].index >= 9)
12996 break;
12997 }
12998 if (i < spec->input_mux->num_items) {
12999 /* use only ADC0 */
13000 spec->adc_nids = alc262_dmic_adc_nids;
13001 spec->num_adc_nids = 1;
13002 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 13003 } else {
8c927b4a
TI
13004 /* all analog inputs */
13005 /* check whether NID 0x07 is valid */
13006 unsigned int wcap = get_wcaps(codec, 0x07);
13007
13008 /* get type */
a22d543a 13009 wcap = get_wcaps_type(wcap);
8c927b4a
TI
13010 if (wcap != AC_WID_AUD_IN) {
13011 spec->adc_nids = alc262_adc_nids_alt;
13012 spec->num_adc_nids =
13013 ARRAY_SIZE(alc262_adc_nids_alt);
13014 spec->capsrc_nids = alc262_capsrc_nids_alt;
13015 } else {
13016 spec->adc_nids = alc262_adc_nids;
13017 spec->num_adc_nids =
13018 ARRAY_SIZE(alc262_adc_nids);
13019 spec->capsrc_nids = alc262_capsrc_nids;
13020 }
df694daa
KY
13021 }
13022 }
e64f14f4 13023 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13024 set_capture_mixer(codec);
dc1eae25 13025 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13026 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13027
b5bfbc67 13028 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13029
2134ea4f
TI
13030 spec->vmaster_nid = 0x0c;
13031
df694daa
KY
13032 codec->patch_ops = alc_patch_ops;
13033 if (board_config == ALC262_AUTO)
ae6b813a 13034 spec->init_hook = alc262_auto_init;
1c716153 13035 spec->shutup = alc_eapd_shutup;
bf1b0225
KY
13036
13037 alc_init_jacks(codec);
cb53c626
TI
13038#ifdef CONFIG_SND_HDA_POWER_SAVE
13039 if (!spec->loopback.amplist)
13040 spec->loopback.amplist = alc262_loopbacks;
13041#endif
ea1fb29a 13042
df694daa
KY
13043 return 0;
13044}
13045
a361d84b
KY
13046/*
13047 * ALC268 channel source setting (2 channel)
13048 */
13049#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13050#define alc268_modes alc260_modes
ea1fb29a 13051
4c6d72d1 13052static const hda_nid_t alc268_dac_nids[2] = {
a361d84b
KY
13053 /* front, hp */
13054 0x02, 0x03
13055};
13056
4c6d72d1 13057static const hda_nid_t alc268_adc_nids[2] = {
a361d84b
KY
13058 /* ADC0-1 */
13059 0x08, 0x07
13060};
13061
4c6d72d1 13062static const hda_nid_t alc268_adc_nids_alt[1] = {
a361d84b
KY
13063 /* ADC0 */
13064 0x08
13065};
13066
4c6d72d1 13067static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
e1406348 13068
a9111321 13069static const struct snd_kcontrol_new alc268_base_mixer[] = {
a361d84b
KY
13070 /* output mixer control */
13071 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13072 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13073 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13074 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13075 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13076 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13077 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13078 { }
13079};
13080
a9111321 13081static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
42171c17
TI
13082 /* output mixer control */
13083 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13084 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13085 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13086 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13087 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13088 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13089 { }
13090};
13091
aef9d318 13092/* bind Beep switches of both NID 0x0f and 0x10 */
a9111321 13093static const struct hda_bind_ctls alc268_bind_beep_sw = {
aef9d318
TI
13094 .ops = &snd_hda_bind_sw,
13095 .values = {
13096 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13097 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13098 0
13099 },
13100};
13101
a9111321 13102static const struct snd_kcontrol_new alc268_beep_mixer[] = {
aef9d318
TI
13103 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13104 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13105 { }
13106};
13107
a9111321 13108static const struct hda_verb alc268_eapd_verbs[] = {
d1a991a6
KY
13109 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13110 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13111 { }
13112};
13113
d273809e 13114/* Toshiba specific */
a9111321 13115static const struct hda_verb alc268_toshiba_verbs[] = {
d273809e
TI
13116 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13117 { } /* end */
13118};
13119
13120/* Acer specific */
889c4395 13121/* bind volumes of both NID 0x02 and 0x03 */
a9111321 13122static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
6bc96857
TI
13123 .ops = &snd_hda_bind_vol,
13124 .values = {
13125 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13126 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13127 0
13128 },
13129};
13130
0f0f391c 13131static void alc268_acer_setup(struct hda_codec *codec)
889c4395
TI
13132{
13133 struct alc_spec *spec = codec->spec;
889c4395 13134
0f0f391c
TI
13135 spec->autocfg.hp_pins[0] = 0x14;
13136 spec->autocfg.speaker_pins[0] = 0x15;
13137 spec->automute = 1;
13138 spec->automute_mode = ALC_AUTOMUTE_AMP;
889c4395
TI
13139}
13140
0f0f391c
TI
13141#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13142#define alc268_acer_master_sw_put alc262_hp_master_sw_put
d273809e 13143
a9111321 13144static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
8ef355da
KY
13145 /* output mixer control */
13146 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13147 {
13148 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13149 .name = "Master Playback Switch",
0f0f391c
TI
13150 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13151 .info = snd_ctl_boolean_mono_info,
13152 .get = alc268_acer_master_sw_get,
8ef355da 13153 .put = alc268_acer_master_sw_put,
8ef355da
KY
13154 },
13155 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13156 { }
13157};
13158
a9111321 13159static const struct snd_kcontrol_new alc268_acer_mixer[] = {
d273809e
TI
13160 /* output mixer control */
13161 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13162 {
13163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13164 .name = "Master Playback Switch",
0f0f391c
TI
13165 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13166 .info = snd_ctl_boolean_mono_info,
13167 .get = alc268_acer_master_sw_get,
d273809e 13168 .put = alc268_acer_master_sw_put,
d273809e 13169 },
5f99f86a
DH
13170 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13171 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13172 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13173 { }
13174};
13175
a9111321 13176static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
c238b4f4
TI
13177 /* output mixer control */
13178 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13179 {
13180 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13181 .name = "Master Playback Switch",
0f0f391c
TI
13182 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13183 .info = snd_ctl_boolean_mono_info,
13184 .get = alc268_acer_master_sw_get,
c238b4f4 13185 .put = alc268_acer_master_sw_put,
c238b4f4 13186 },
5f99f86a
DH
13187 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13188 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13189 { }
13190};
13191
a9111321 13192static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
8ef355da
KY
13193 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13194 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13195 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13196 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13197 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13198 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13199 { }
13200};
13201
a9111321 13202static const struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13203 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13204 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13206 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13207 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13208 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13209 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13210 { }
13211};
13212
13213/* unsolicited event for HP jack sensing */
4f5d1706 13214#define alc268_toshiba_setup alc262_hippo_setup
d273809e 13215
4f5d1706
TI
13216static void alc268_acer_lc_setup(struct hda_codec *codec)
13217{
13218 struct alc_spec *spec = codec->spec;
3b8510ce
TI
13219 spec->autocfg.hp_pins[0] = 0x15;
13220 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce 13221 spec->automute = 1;
54463a66 13222 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
13223 spec->ext_mic.pin = 0x18;
13224 spec->ext_mic.mux_idx = 0;
13225 spec->int_mic.pin = 0x12;
13226 spec->int_mic.mux_idx = 6;
13227 spec->auto_mic = 1;
8ef355da
KY
13228}
13229
a9111321 13230static const struct snd_kcontrol_new alc268_dell_mixer[] = {
3866f0b0
TI
13231 /* output mixer control */
13232 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13233 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13234 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13235 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13237 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13238 { }
13239};
13240
a9111321 13241static const struct hda_verb alc268_dell_verbs[] = {
3866f0b0
TI
13242 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13243 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13244 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13245 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13246 { }
13247};
13248
13249/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13250static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13251{
a9fd4f3f 13252 struct alc_spec *spec = codec->spec;
3866f0b0 13253
a9fd4f3f
TI
13254 spec->autocfg.hp_pins[0] = 0x15;
13255 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13256 spec->ext_mic.pin = 0x18;
13257 spec->ext_mic.mux_idx = 0;
13258 spec->int_mic.pin = 0x19;
13259 spec->int_mic.mux_idx = 1;
13260 spec->auto_mic = 1;
d922b51d
TI
13261 spec->automute = 1;
13262 spec->automute_mode = ALC_AUTOMUTE_PIN;
3866f0b0
TI
13263}
13264
a9111321 13265static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
eb5a6621
HRK
13266 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13267 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13268 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13269 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13270 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13271 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13272 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13273 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13274 { }
13275};
13276
a9111321 13277static const struct hda_verb alc267_quanta_il1_verbs[] = {
eb5a6621
HRK
13278 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13279 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13280 { }
13281};
13282
4f5d1706 13283static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13284{
a9fd4f3f 13285 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13286 spec->autocfg.hp_pins[0] = 0x15;
13287 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13288 spec->ext_mic.pin = 0x18;
13289 spec->ext_mic.mux_idx = 0;
13290 spec->int_mic.pin = 0x19;
13291 spec->int_mic.mux_idx = 1;
13292 spec->auto_mic = 1;
d922b51d
TI
13293 spec->automute = 1;
13294 spec->automute_mode = ALC_AUTOMUTE_PIN;
eb5a6621
HRK
13295}
13296
a361d84b
KY
13297/*
13298 * generic initialization of ADC, input mixers and output mixers
13299 */
a9111321 13300static const struct hda_verb alc268_base_init_verbs[] = {
a361d84b
KY
13301 /* Unmute DAC0-1 and set vol = 0 */
13302 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13303 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13304
13305 /*
13306 * Set up output mixers (0x0c - 0x0e)
13307 */
13308 /* set vol=0 to output mixers */
13309 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13310 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13311
13312 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13313 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13314
13315 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13316 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13317 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13318 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13319 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13320 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13321 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13322 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13323
13324 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13325 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13326 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13327 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13328 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13329
13330 /* set PCBEEP vol = 0, mute connections */
13331 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13332 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13333 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13334
a9b3aa8a 13335 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13336
a9b3aa8a
JZ
13337 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13338 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13339 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13340 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13341
a361d84b
KY
13342 { }
13343};
13344
1f0f4b80
TI
13345/* only for model=test */
13346#ifdef CONFIG_SND_DEBUG
a361d84b
KY
13347/*
13348 * generic initialization of ADC, input mixers and output mixers
13349 */
a9111321 13350static const struct hda_verb alc268_volume_init_verbs[] = {
a361d84b 13351 /* set output DAC */
4cfb91c6
TI
13352 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13353 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13354
13355 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13356 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13357 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13358 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13359 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13360
a361d84b 13361 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13362 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13363 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13364
13365 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13366 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1f0f4b80
TI
13367 { }
13368};
13369#endif /* CONFIG_SND_DEBUG */
a361d84b 13370
1f0f4b80
TI
13371/* set PCBEEP vol = 0, mute connections */
13372static const struct hda_verb alc268_beep_init_verbs[] = {
aef9d318
TI
13373 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13374 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13375 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13376 { }
13377};
13378
a9111321 13379static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
fdbc6626
TI
13380 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13381 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13382 { } /* end */
13383};
13384
a9111321 13385static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
a361d84b
KY
13386 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13387 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13388 _DEFINE_CAPSRC(1),
a361d84b
KY
13389 { } /* end */
13390};
13391
a9111321 13392static const struct snd_kcontrol_new alc268_capture_mixer[] = {
a361d84b
KY
13393 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13394 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13395 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13396 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13397 _DEFINE_CAPSRC(2),
a361d84b
KY
13398 { } /* end */
13399};
13400
a9111321 13401static const struct hda_input_mux alc268_capture_source = {
a361d84b
KY
13402 .num_items = 4,
13403 .items = {
13404 { "Mic", 0x0 },
13405 { "Front Mic", 0x1 },
13406 { "Line", 0x2 },
13407 { "CD", 0x3 },
13408 },
13409};
13410
a9111321 13411static const struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13412 .num_items = 3,
13413 .items = {
13414 { "Mic", 0x0 },
13415 { "Internal Mic", 0x1 },
13416 { "Line", 0x2 },
13417 },
13418};
13419
a9111321 13420static const struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13421 .num_items = 3,
13422 .items = {
13423 { "Mic", 0x0 },
13424 { "Internal Mic", 0x6 },
13425 { "Line", 0x2 },
13426 },
13427};
13428
86c53bd2 13429#ifdef CONFIG_SND_DEBUG
a9111321 13430static const struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13431 /* Volume widgets */
13432 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13433 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13434 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13435 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13436 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13437 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13438 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13439 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13440 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13441 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13442 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13443 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13444 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13445 /* The below appears problematic on some hardwares */
13446 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13447 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13448 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13449 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13450 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13451
13452 /* Modes for retasking pin widgets */
13453 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13454 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13455 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13456 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13457
13458 /* Controls for GPIO pins, assuming they are configured as outputs */
13459 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13460 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13461 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13462 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13463
13464 /* Switches to allow the digital SPDIF output pin to be enabled.
13465 * The ALC268 does not have an SPDIF input.
13466 */
13467 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13468
13469 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13470 * this output to turn on an external amplifier.
13471 */
13472 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13473 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13474
13475 { } /* end */
13476};
13477#endif
13478
a361d84b
KY
13479/* create input playback/capture controls for the given pin */
13480static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13481 const char *ctlname, int idx)
13482{
3f3b7c1a 13483 hda_nid_t dac;
a361d84b
KY
13484 int err;
13485
3f3b7c1a
TI
13486 switch (nid) {
13487 case 0x14:
13488 case 0x16:
13489 dac = 0x02;
13490 break;
13491 case 0x15:
b08b1637
TI
13492 case 0x1a: /* ALC259/269 only */
13493 case 0x1b: /* ALC259/269 only */
531d8791 13494 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13495 dac = 0x03;
13496 break;
13497 default:
c7a9434d
TI
13498 snd_printd(KERN_WARNING "hda_codec: "
13499 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13500 return 0;
13501 }
13502 if (spec->multiout.dac_nids[0] != dac &&
13503 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13504 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13505 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13506 HDA_OUTPUT));
13507 if (err < 0)
13508 return err;
dda14410 13509 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3f3b7c1a
TI
13510 }
13511
3f3b7c1a 13512 if (nid != 0x16)
0afe5f89 13513 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13514 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13515 else /* mono */
0afe5f89 13516 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13517 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13518 if (err < 0)
13519 return err;
13520 return 0;
13521}
13522
13523/* add playback controls from the parsed DAC table */
13524static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13525 const struct auto_pin_cfg *cfg)
13526{
13527 hda_nid_t nid;
13528 int err;
13529
a361d84b 13530 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13531
13532 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13533 if (nid) {
13534 const char *name;
2e925dde
TI
13535 int index;
13536 name = alc_get_line_out_pfx(spec, 0, true, &index);
3f3b7c1a
TI
13537 err = alc268_new_analog_output(spec, nid, name, 0);
13538 if (err < 0)
13539 return err;
13540 }
a361d84b
KY
13541
13542 nid = cfg->speaker_pins[0];
13543 if (nid == 0x1d) {
0afe5f89 13544 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13545 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13546 if (err < 0)
13547 return err;
7bfb9c03 13548 } else if (nid) {
3f3b7c1a
TI
13549 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13550 if (err < 0)
13551 return err;
a361d84b
KY
13552 }
13553 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13554 if (nid) {
13555 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13556 if (err < 0)
13557 return err;
13558 }
a361d84b
KY
13559
13560 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13561 if (nid == 0x16) {
0afe5f89 13562 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13563 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13564 if (err < 0)
13565 return err;
13566 }
ea1fb29a 13567 return 0;
a361d84b
KY
13568}
13569
13570/* create playback/capture controls for input pins */
05f5f477 13571static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13572 const struct auto_pin_cfg *cfg)
13573{
05f5f477 13574 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13575}
13576
e9af4f36
TI
13577static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13578 hda_nid_t nid, int pin_type)
13579{
13580 int idx;
13581
13582 alc_set_pin_output(codec, nid, pin_type);
13583 if (nid == 0x14 || nid == 0x16)
13584 idx = 0;
13585 else
13586 idx = 1;
13587 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13588}
13589
1f0f4b80
TI
13590static void alc268_auto_init_dac(struct hda_codec *codec, hda_nid_t nid)
13591{
13592 if (!nid)
13593 return;
13594 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7ec9c6cc 13595 AMP_OUT_ZERO);
1f0f4b80
TI
13596}
13597
e9af4f36
TI
13598static void alc268_auto_init_multi_out(struct hda_codec *codec)
13599{
13600 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13601 int i;
13602
13603 for (i = 0; i < spec->autocfg.line_outs; i++) {
13604 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13605 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13606 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13607 }
1f0f4b80
TI
13608 /* mute DACs */
13609 for (i = 0; i < spec->multiout.num_dacs; i++)
13610 alc268_auto_init_dac(codec, spec->multiout.dac_nids[i]);
e9af4f36
TI
13611}
13612
13613static void alc268_auto_init_hp_out(struct hda_codec *codec)
13614{
13615 struct alc_spec *spec = codec->spec;
13616 hda_nid_t pin;
e1ca7b4e 13617 int i;
e9af4f36 13618
e1ca7b4e
TI
13619 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13620 pin = spec->autocfg.hp_pins[i];
e9af4f36 13621 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13622 }
13623 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13624 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13625 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13626 }
13627 if (spec->autocfg.mono_out_pin)
13628 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13629 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1f0f4b80
TI
13630 /* mute DACs */
13631 alc268_auto_init_dac(codec, spec->multiout.hp_nid);
13632 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
13633 alc268_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
e9af4f36
TI
13634}
13635
a361d84b
KY
13636static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13637{
13638 struct alc_spec *spec = codec->spec;
13639 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13640 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13641 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13642 unsigned int dac_vol1, dac_vol2;
13643
e9af4f36 13644 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13645 snd_hda_codec_write(codec, speaker_nid, 0,
13646 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13647 /* mute mixer inputs from 0x1d */
a361d84b
KY
13648 snd_hda_codec_write(codec, 0x0f, 0,
13649 AC_VERB_SET_AMP_GAIN_MUTE,
13650 AMP_IN_UNMUTE(1));
13651 snd_hda_codec_write(codec, 0x10, 0,
13652 AC_VERB_SET_AMP_GAIN_MUTE,
13653 AMP_IN_UNMUTE(1));
13654 } else {
e9af4f36 13655 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13656 snd_hda_codec_write(codec, 0x0f, 0,
13657 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13658 snd_hda_codec_write(codec, 0x10, 0,
13659 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13660 }
13661
13662 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13663 if (line_nid == 0x14)
a361d84b
KY
13664 dac_vol2 = AMP_OUT_ZERO;
13665 else if (line_nid == 0x15)
13666 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13667 if (hp_nid == 0x14)
a361d84b
KY
13668 dac_vol2 = AMP_OUT_ZERO;
13669 else if (hp_nid == 0x15)
13670 dac_vol1 = AMP_OUT_ZERO;
13671 if (line_nid != 0x16 || hp_nid != 0x16 ||
13672 spec->autocfg.line_out_pins[1] != 0x16 ||
13673 spec->autocfg.line_out_pins[2] != 0x16)
13674 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13675
13676 snd_hda_codec_write(codec, 0x02, 0,
13677 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13678 snd_hda_codec_write(codec, 0x03, 0,
13679 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13680}
13681
def319f9 13682/* pcm configuration: identical with ALC880 */
a361d84b
KY
13683#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13684#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13685#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13686#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13687
13688/*
13689 * BIOS auto configuration
13690 */
13691static int alc268_parse_auto_config(struct hda_codec *codec)
13692{
13693 struct alc_spec *spec = codec->spec;
13694 int err;
4c6d72d1 13695 static const hda_nid_t alc268_ignore[] = { 0 };
a361d84b
KY
13696
13697 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13698 alc268_ignore);
13699 if (err < 0)
13700 return err;
7e0e44d4
TI
13701 if (!spec->autocfg.line_outs) {
13702 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13703 spec->multiout.max_channels = 2;
13704 spec->no_analog = 1;
13705 goto dig_only;
13706 }
a361d84b 13707 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13708 }
a361d84b
KY
13709 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13710 if (err < 0)
13711 return err;
05f5f477 13712 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13713 if (err < 0)
13714 return err;
13715
13716 spec->multiout.max_channels = 2;
13717
7e0e44d4 13718 dig_only:
a361d84b 13719 /* digital only support output */
757899ac 13720 alc_auto_parse_digital(codec);
603c4019 13721 if (spec->kctls.list)
d88897ea 13722 add_mixer(spec, spec->kctls.list);
a361d84b 13723
892981ff 13724 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13725 add_mixer(spec, alc268_beep_mixer);
aef9d318 13726
1f0f4b80 13727 add_verb(spec, alc268_beep_init_verbs);
5908589f 13728 spec->num_mux_defs = 2;
61b9b9b1 13729 spec->input_mux = &spec->private_imux[0];
a361d84b 13730
776e184e
TI
13731 err = alc_auto_add_mic_boost(codec);
13732 if (err < 0)
13733 return err;
13734
6227cdce 13735 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13736
a361d84b
KY
13737 return 1;
13738}
13739
a361d84b 13740#define alc268_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 13741#define alc268_auto_init_input_src alc882_auto_init_input_src
a361d84b
KY
13742
13743/* init callback for auto-configuration model -- overriding the default init */
13744static void alc268_auto_init(struct hda_codec *codec)
13745{
f6c7e546 13746 struct alc_spec *spec = codec->spec;
a361d84b
KY
13747 alc268_auto_init_multi_out(codec);
13748 alc268_auto_init_hp_out(codec);
13749 alc268_auto_init_mono_speaker_out(codec);
13750 alc268_auto_init_analog_input(codec);
ae0ebbf7 13751 alc268_auto_init_input_src(codec);
757899ac 13752 alc_auto_init_digital(codec);
f6c7e546 13753 if (spec->unsol_event)
7fb0d78f 13754 alc_inithook(codec);
a361d84b
KY
13755}
13756
13757/*
13758 * configuration and preset
13759 */
ea734963 13760static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13761 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13762 [ALC268_3ST] = "3stack",
983f8ae4 13763 [ALC268_TOSHIBA] = "toshiba",
d273809e 13764 [ALC268_ACER] = "acer",
c238b4f4 13765 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13766 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13767 [ALC268_DELL] = "dell",
f12462c5 13768 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13769#ifdef CONFIG_SND_DEBUG
13770 [ALC268_TEST] = "test",
13771#endif
a361d84b
KY
13772 [ALC268_AUTO] = "auto",
13773};
13774
a9111321 13775static const struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13776 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13777 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13778 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13779 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13780 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13781 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13782 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13783 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
0a1896b2 13784 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
a1bf8088
DC
13785 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13786 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13787 /* almost compatible with toshiba but with optional digital outs;
13788 * auto-probing seems working fine
13789 */
8871e5b9 13790 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13791 ALC268_AUTO),
a361d84b 13792 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13793 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13794 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
eb5a6621 13795 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13796 {}
13797};
13798
3abf2f36 13799/* Toshiba laptops have no unique PCI SSID but only codec SSID */
a9111321 13800static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
3abf2f36
TI
13801 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13802 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13803 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13804 ALC268_TOSHIBA),
13805 {}
13806};
13807
a9111321 13808static const struct alc_config_preset alc268_presets[] = {
eb5a6621 13809 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13810 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13811 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13812 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13813 alc267_quanta_il1_verbs },
13814 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13815 .dac_nids = alc268_dac_nids,
13816 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13817 .adc_nids = alc268_adc_nids_alt,
13818 .hp_nid = 0x03,
13819 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13820 .channel_mode = alc268_modes,
4f5d1706
TI
13821 .unsol_event = alc_sku_unsol_event,
13822 .setup = alc267_quanta_il1_setup,
13823 .init_hook = alc_inithook,
eb5a6621 13824 },
a361d84b 13825 [ALC268_3ST] = {
aef9d318
TI
13826 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13827 alc268_beep_mixer },
a361d84b
KY
13828 .init_verbs = { alc268_base_init_verbs },
13829 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13830 .dac_nids = alc268_dac_nids,
13831 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13832 .adc_nids = alc268_adc_nids_alt,
e1406348 13833 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13834 .hp_nid = 0x03,
13835 .dig_out_nid = ALC268_DIGOUT_NID,
13836 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13837 .channel_mode = alc268_modes,
13838 .input_mux = &alc268_capture_source,
13839 },
d1a991a6 13840 [ALC268_TOSHIBA] = {
42171c17 13841 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13842 alc268_beep_mixer },
d273809e
TI
13843 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13844 alc268_toshiba_verbs },
d1a991a6
KY
13845 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13846 .dac_nids = alc268_dac_nids,
13847 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13848 .adc_nids = alc268_adc_nids_alt,
e1406348 13849 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13850 .hp_nid = 0x03,
13851 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13852 .channel_mode = alc268_modes,
13853 .input_mux = &alc268_capture_source,
e9427969 13854 .unsol_event = alc_sku_unsol_event,
4f5d1706 13855 .setup = alc268_toshiba_setup,
e9427969 13856 .init_hook = alc_inithook,
d273809e
TI
13857 },
13858 [ALC268_ACER] = {
432fd133 13859 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13860 alc268_beep_mixer },
d273809e
TI
13861 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13862 alc268_acer_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,
d273809e
TI
13868 .hp_nid = 0x02,
13869 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13870 .channel_mode = alc268_modes,
0ccb541c 13871 .input_mux = &alc268_acer_capture_source,
0f0f391c
TI
13872 .unsol_event = alc_sku_unsol_event,
13873 .setup = alc268_acer_setup,
13874 .init_hook = alc_inithook,
d1a991a6 13875 },
c238b4f4
TI
13876 [ALC268_ACER_DMIC] = {
13877 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13878 alc268_beep_mixer },
13879 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13880 alc268_acer_verbs },
13881 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13882 .dac_nids = alc268_dac_nids,
13883 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13884 .adc_nids = alc268_adc_nids_alt,
13885 .capsrc_nids = alc268_capsrc_nids,
13886 .hp_nid = 0x02,
13887 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13888 .channel_mode = alc268_modes,
13889 .input_mux = &alc268_acer_dmic_capture_source,
0f0f391c
TI
13890 .unsol_event = alc_sku_unsol_event,
13891 .setup = alc268_acer_setup,
13892 .init_hook = alc_inithook,
c238b4f4 13893 },
8ef355da
KY
13894 [ALC268_ACER_ASPIRE_ONE] = {
13895 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13896 alc268_beep_mixer,
fdbc6626 13897 alc268_capture_nosrc_mixer },
8ef355da
KY
13898 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13899 alc268_acer_aspire_one_verbs },
13900 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13901 .dac_nids = alc268_dac_nids,
13902 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13903 .adc_nids = alc268_adc_nids_alt,
13904 .capsrc_nids = alc268_capsrc_nids,
13905 .hp_nid = 0x03,
13906 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13907 .channel_mode = alc268_modes,
3b8510ce 13908 .unsol_event = alc_sku_unsol_event,
4f5d1706 13909 .setup = alc268_acer_lc_setup,
3b8510ce 13910 .init_hook = alc_inithook,
8ef355da 13911 },
3866f0b0 13912 [ALC268_DELL] = {
fdbc6626
TI
13913 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13914 alc268_capture_nosrc_mixer },
3866f0b0
TI
13915 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13916 alc268_dell_verbs },
13917 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13918 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13919 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13920 .adc_nids = alc268_adc_nids_alt,
13921 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13922 .hp_nid = 0x02,
13923 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13924 .channel_mode = alc268_modes,
a9fd4f3f 13925 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13926 .setup = alc268_dell_setup,
13927 .init_hook = alc_inithook,
3866f0b0 13928 },
f12462c5 13929 [ALC268_ZEPTO] = {
aef9d318
TI
13930 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13931 alc268_beep_mixer },
f12462c5
MT
13932 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13933 alc268_toshiba_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,
e1406348 13938 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13939 .hp_nid = 0x03,
13940 .dig_out_nid = ALC268_DIGOUT_NID,
13941 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13942 .channel_mode = alc268_modes,
13943 .input_mux = &alc268_capture_source,
e9427969 13944 .unsol_event = alc_sku_unsol_event,
4f5d1706 13945 .setup = alc268_toshiba_setup,
e9427969 13946 .init_hook = alc_inithook,
f12462c5 13947 },
86c53bd2
JW
13948#ifdef CONFIG_SND_DEBUG
13949 [ALC268_TEST] = {
13950 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13951 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
1f0f4b80
TI
13952 alc268_volume_init_verbs,
13953 alc268_beep_init_verbs },
86c53bd2
JW
13954 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13955 .dac_nids = alc268_dac_nids,
13956 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13957 .adc_nids = alc268_adc_nids_alt,
e1406348 13958 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13959 .hp_nid = 0x03,
13960 .dig_out_nid = ALC268_DIGOUT_NID,
13961 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13962 .channel_mode = alc268_modes,
13963 .input_mux = &alc268_capture_source,
13964 },
13965#endif
a361d84b
KY
13966};
13967
13968static int patch_alc268(struct hda_codec *codec)
13969{
13970 struct alc_spec *spec;
13971 int board_config;
22971e3a 13972 int i, has_beep, err;
a361d84b 13973
ef86f581 13974 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13975 if (spec == NULL)
13976 return -ENOMEM;
13977
13978 codec->spec = spec;
13979
1f0f4b80
TI
13980 /* ALC268 has no aa-loopback mixer */
13981
a361d84b
KY
13982 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13983 alc268_models,
13984 alc268_cfg_tbl);
13985
3abf2f36
TI
13986 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13987 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13988 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13989
a361d84b 13990 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13991 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13992 codec->chip_name);
a361d84b
KY
13993 board_config = ALC268_AUTO;
13994 }
13995
13996 if (board_config == ALC268_AUTO) {
13997 /* automatic parse from the BIOS config */
13998 err = alc268_parse_auto_config(codec);
13999 if (err < 0) {
14000 alc_free(codec);
14001 return err;
14002 } else if (!err) {
14003 printk(KERN_INFO
14004 "hda_codec: Cannot set up configuration "
14005 "from BIOS. Using base mode...\n");
14006 board_config = ALC268_3ST;
14007 }
14008 }
14009
14010 if (board_config != ALC268_AUTO)
e9c364c0 14011 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14012
a361d84b
KY
14013 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14014 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14015 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14016
a361d84b
KY
14017 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14018
22971e3a
TI
14019 has_beep = 0;
14020 for (i = 0; i < spec->num_mixers; i++) {
14021 if (spec->mixers[i] == alc268_beep_mixer) {
14022 has_beep = 1;
14023 break;
14024 }
14025 }
14026
14027 if (has_beep) {
14028 err = snd_hda_attach_beep_device(codec, 0x1);
14029 if (err < 0) {
14030 alc_free(codec);
14031 return err;
14032 }
14033 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14034 /* override the amp caps for beep generator */
14035 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14036 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14037 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14038 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14039 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14040 }
aef9d318 14041
7e0e44d4 14042 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14043 /* check whether NID 0x07 is valid */
14044 unsigned int wcap = get_wcaps(codec, 0x07);
14045
defb5ab2 14046 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14047 /* get type */
a22d543a 14048 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14049 if (spec->auto_mic ||
14050 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14051 spec->adc_nids = alc268_adc_nids_alt;
14052 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14053 if (spec->auto_mic)
14054 fixup_automic_adc(codec);
fdbc6626
TI
14055 if (spec->auto_mic || spec->input_mux->num_items == 1)
14056 add_mixer(spec, alc268_capture_nosrc_mixer);
14057 else
14058 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14059 } else {
14060 spec->adc_nids = alc268_adc_nids;
14061 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14062 add_mixer(spec, alc268_capture_mixer);
a361d84b
KY
14063 }
14064 }
2134ea4f
TI
14065
14066 spec->vmaster_nid = 0x02;
14067
a361d84b
KY
14068 codec->patch_ops = alc_patch_ops;
14069 if (board_config == ALC268_AUTO)
14070 spec->init_hook = alc268_auto_init;
1c716153 14071 spec->shutup = alc_eapd_shutup;
ea1fb29a 14072
bf1b0225
KY
14073 alc_init_jacks(codec);
14074
a361d84b
KY
14075 return 0;
14076}
14077
f6a92248
KY
14078/*
14079 * ALC269 channel source setting (2 channel)
14080 */
14081#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14082
14083#define alc269_dac_nids alc260_dac_nids
14084
4c6d72d1 14085static const hda_nid_t alc269_adc_nids[1] = {
f6a92248 14086 /* ADC1 */
f53281e6
KY
14087 0x08,
14088};
14089
4c6d72d1 14090static const hda_nid_t alc269_capsrc_nids[1] = {
e01bf509
TI
14091 0x23,
14092};
14093
4c6d72d1 14094static const hda_nid_t alc269vb_adc_nids[1] = {
84898e87
KY
14095 /* ADC1 */
14096 0x09,
14097};
14098
4c6d72d1 14099static const hda_nid_t alc269vb_capsrc_nids[1] = {
84898e87
KY
14100 0x22,
14101};
14102
4c6d72d1 14103static const hda_nid_t alc269_adc_candidates[] = {
262ac22d 14104 0x08, 0x09, 0x07, 0x11,
6694635d 14105};
e01bf509 14106
f6a92248
KY
14107#define alc269_modes alc260_modes
14108#define alc269_capture_source alc880_lg_lw_capture_source
14109
a9111321 14110static const struct snd_kcontrol_new alc269_base_mixer[] = {
f6a92248
KY
14111 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14112 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14113 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14114 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14115 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14117 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14118 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14119 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14120 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14121 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14122 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14123 { } /* end */
14124};
14125
a9111321 14126static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
60db6b53
KY
14127 /* output mixer control */
14128 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14129 {
14130 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14131 .name = "Master Playback Switch",
5e26dfd0 14132 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14133 .info = snd_hda_mixer_amp_switch_info,
14134 .get = snd_hda_mixer_amp_switch_get,
14135 .put = alc268_acer_master_sw_put,
14136 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14137 },
14138 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14140 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14141 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14142 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14143 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14144 { }
14145};
14146
a9111321 14147static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
64154835
TV
14148 /* output mixer control */
14149 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14150 {
14151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14152 .name = "Master Playback Switch",
5e26dfd0 14153 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14154 .info = snd_hda_mixer_amp_switch_info,
14155 .get = snd_hda_mixer_amp_switch_get,
14156 .put = alc268_acer_master_sw_put,
14157 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14158 },
14159 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14160 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14161 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14162 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14163 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14164 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14165 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14166 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14167 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14168 { }
14169};
14170
a9111321 14171static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14172 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14173 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14175 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14176 { } /* end */
14177};
14178
a9111321 14179static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
84898e87
KY
14180 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14181 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14182 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14183 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14184 { } /* end */
14185};
14186
a9111321 14187static const struct snd_kcontrol_new alc269_asus_mixer[] = {
fe3eb0a7
KY
14188 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14189 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14190 { } /* end */
14191};
14192
f53281e6 14193/* capture mixer elements */
a9111321 14194static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
84898e87
KY
14195 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14196 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14197 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14198 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14199 { } /* end */
14200};
14201
a9111321 14202static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14203 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14204 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14205 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14206 { } /* end */
14207};
14208
a9111321 14209static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
84898e87
KY
14210 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14211 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14212 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14213 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14214 { } /* end */
14215};
14216
a9111321 14217static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
84898e87
KY
14218 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14219 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14220 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14221 { } /* end */
14222};
14223
26f5df26 14224/* FSC amilo */
84898e87 14225#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14226
a9111321 14227static const struct hda_verb alc269_quanta_fl1_verbs[] = {
60db6b53
KY
14228 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14229 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14230 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14231 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14232 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14233 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14234 { }
14235};
f6a92248 14236
a9111321 14237static const struct hda_verb alc269_lifebook_verbs[] = {
64154835
TV
14238 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14239 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14240 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14241 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14242 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14243 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14244 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14245 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14246 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14247 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14248 { }
14249};
14250
60db6b53
KY
14251/* toggle speaker-output according to the hp-jack state */
14252static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14253{
3b8510ce 14254 alc_hp_automute(codec);
f6a92248 14255
60db6b53
KY
14256 snd_hda_codec_write(codec, 0x20, 0,
14257 AC_VERB_SET_COEF_INDEX, 0x0c);
14258 snd_hda_codec_write(codec, 0x20, 0,
14259 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14260
60db6b53
KY
14261 snd_hda_codec_write(codec, 0x20, 0,
14262 AC_VERB_SET_COEF_INDEX, 0x0c);
14263 snd_hda_codec_write(codec, 0x20, 0,
14264 AC_VERB_SET_PROC_COEF, 0x480);
14265}
f6a92248 14266
3b8510ce
TI
14267#define alc269_lifebook_speaker_automute \
14268 alc269_quanta_fl1_speaker_automute
64154835 14269
64154835
TV
14270static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14271{
14272 unsigned int present_laptop;
14273 unsigned int present_dock;
14274
864f92be
WF
14275 present_laptop = snd_hda_jack_detect(codec, 0x18);
14276 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14277
14278 /* Laptop mic port overrides dock mic port, design decision */
14279 if (present_dock)
14280 snd_hda_codec_write(codec, 0x23, 0,
14281 AC_VERB_SET_CONNECT_SEL, 0x3);
14282 if (present_laptop)
14283 snd_hda_codec_write(codec, 0x23, 0,
14284 AC_VERB_SET_CONNECT_SEL, 0x0);
14285 if (!present_dock && !present_laptop)
14286 snd_hda_codec_write(codec, 0x23, 0,
14287 AC_VERB_SET_CONNECT_SEL, 0x1);
14288}
14289
60db6b53
KY
14290static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14291 unsigned int res)
14292{
4f5d1706
TI
14293 switch (res >> 26) {
14294 case ALC880_HP_EVENT:
60db6b53 14295 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14296 break;
14297 case ALC880_MIC_EVENT:
14298 alc_mic_automute(codec);
14299 break;
14300 }
60db6b53 14301}
f6a92248 14302
64154835
TV
14303static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14304 unsigned int res)
14305{
14306 if ((res >> 26) == ALC880_HP_EVENT)
14307 alc269_lifebook_speaker_automute(codec);
14308 if ((res >> 26) == ALC880_MIC_EVENT)
14309 alc269_lifebook_mic_autoswitch(codec);
14310}
14311
4f5d1706
TI
14312static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14313{
14314 struct alc_spec *spec = codec->spec;
20645d70
TI
14315 spec->autocfg.hp_pins[0] = 0x15;
14316 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14317 spec->automute_mixer_nid[0] = 0x0c;
14318 spec->automute = 1;
14319 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14320 spec->ext_mic.pin = 0x18;
14321 spec->ext_mic.mux_idx = 0;
14322 spec->int_mic.pin = 0x19;
14323 spec->int_mic.mux_idx = 1;
14324 spec->auto_mic = 1;
14325}
14326
60db6b53
KY
14327static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14328{
14329 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14330 alc_mic_automute(codec);
60db6b53 14331}
f6a92248 14332
3b8510ce
TI
14333static void alc269_lifebook_setup(struct hda_codec *codec)
14334{
14335 struct alc_spec *spec = codec->spec;
14336 spec->autocfg.hp_pins[0] = 0x15;
14337 spec->autocfg.hp_pins[1] = 0x1a;
14338 spec->autocfg.speaker_pins[0] = 0x14;
14339 spec->automute_mixer_nid[0] = 0x0c;
14340 spec->automute = 1;
14341 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14342}
14343
64154835
TV
14344static void alc269_lifebook_init_hook(struct hda_codec *codec)
14345{
14346 alc269_lifebook_speaker_automute(codec);
14347 alc269_lifebook_mic_autoswitch(codec);
14348}
14349
a9111321 14350static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14351 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14352 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14353 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14354 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14355 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14356 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14357 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14358 {}
14359};
14360
a9111321 14361static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14362 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14363 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14364 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14365 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14366 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14367 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14368 {}
14369};
14370
a9111321 14371static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
84898e87
KY
14372 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14373 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14374 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14375 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14376 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14377 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14378 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14379 {}
14380};
14381
a9111321 14382static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
84898e87
KY
14383 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14384 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14385 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14387 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14388 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14389 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14390 {}
14391};
14392
a9111321 14393static const struct hda_verb alc271_acer_dmic_verbs[] = {
fe3eb0a7
KY
14394 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14395 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14396 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14397 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14398 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14399 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14400 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14401 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14402 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14403 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14404 { }
14405};
14406
226b1ec8 14407static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14408{
4f5d1706 14409 struct alc_spec *spec = codec->spec;
20645d70
TI
14410 spec->autocfg.hp_pins[0] = 0x15;
14411 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14412 spec->automute_mixer_nid[0] = 0x0c;
14413 spec->automute = 1;
14414 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14415 spec->ext_mic.pin = 0x18;
14416 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14417 spec->int_mic.pin = 0x19;
14418 spec->int_mic.mux_idx = 1;
4f5d1706 14419 spec->auto_mic = 1;
f53281e6
KY
14420}
14421
226b1ec8 14422static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14423{
14424 struct alc_spec *spec = codec->spec;
20645d70
TI
14425 spec->autocfg.hp_pins[0] = 0x15;
14426 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14427 spec->automute_mixer_nid[0] = 0x0c;
14428 spec->automute = 1;
14429 spec->automute_mode = ALC_AUTOMUTE_MIXER;
84898e87
KY
14430 spec->ext_mic.pin = 0x18;
14431 spec->ext_mic.mux_idx = 0;
14432 spec->int_mic.pin = 0x12;
226b1ec8 14433 spec->int_mic.mux_idx = 5;
84898e87
KY
14434 spec->auto_mic = 1;
14435}
14436
226b1ec8 14437static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14438{
4f5d1706 14439 struct alc_spec *spec = codec->spec;
226b1ec8 14440 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14441 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14442 spec->automute_mixer_nid[0] = 0x0c;
14443 spec->automute = 1;
14444 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14445 spec->ext_mic.pin = 0x18;
14446 spec->ext_mic.mux_idx = 0;
14447 spec->int_mic.pin = 0x19;
14448 spec->int_mic.mux_idx = 1;
14449 spec->auto_mic = 1;
f53281e6
KY
14450}
14451
226b1ec8
KY
14452static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14453{
14454 struct alc_spec *spec = codec->spec;
14455 spec->autocfg.hp_pins[0] = 0x21;
14456 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14457 spec->automute_mixer_nid[0] = 0x0c;
14458 spec->automute = 1;
14459 spec->automute_mode = ALC_AUTOMUTE_MIXER;
226b1ec8
KY
14460 spec->ext_mic.pin = 0x18;
14461 spec->ext_mic.mux_idx = 0;
14462 spec->int_mic.pin = 0x12;
14463 spec->int_mic.mux_idx = 6;
14464 spec->auto_mic = 1;
14465}
14466
60db6b53
KY
14467/*
14468 * generic initialization of ADC, input mixers and output mixers
14469 */
a9111321 14470static const struct hda_verb alc269_init_verbs[] = {
60db6b53
KY
14471 /*
14472 * Unmute ADC0 and set the default input to mic-in
14473 */
84898e87 14474 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14475
14476 /*
84898e87 14477 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14478 */
14479 /* set vol=0 to output mixers */
14480 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14481 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14482
14483 /* set up input amps for analog loopback */
14484 /* Amp Indices: DAC = 0, mixer = 1 */
14485 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14486 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14487 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14488 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14491
14492 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14493 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14494 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14495 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14496 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14497 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14498 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14499
14500 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14502
84898e87
KY
14503 /* FIXME: use Mux-type input source selection */
14504 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14505 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14506 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14507
84898e87
KY
14508 /* set EAPD */
14509 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14510 { }
14511};
14512
a9111321 14513static const struct hda_verb alc269vb_init_verbs[] = {
84898e87
KY
14514 /*
14515 * Unmute ADC0 and set the default input to mic-in
14516 */
14517 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14518
14519 /*
14520 * Set up output mixers (0x02 - 0x03)
14521 */
14522 /* set vol=0 to output mixers */
14523 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14524 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14525
14526 /* set up input amps for analog loopback */
14527 /* Amp Indices: DAC = 0, mixer = 1 */
14528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14529 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14530 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14531 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14532 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14533 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14534
14535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14536 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14538 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14539 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14540 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14541 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14542
14543 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14544 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14545
14546 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14547 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14548 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14549 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14550
14551 /* set EAPD */
14552 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14553 { }
14554};
14555
9d0b71b1
TI
14556#define alc269_auto_create_multi_out_ctls \
14557 alc268_auto_create_multi_out_ctls
05f5f477
TI
14558#define alc269_auto_create_input_ctls \
14559 alc268_auto_create_input_ctls
f6a92248
KY
14560
14561#ifdef CONFIG_SND_HDA_POWER_SAVE
14562#define alc269_loopbacks alc880_loopbacks
14563#endif
14564
def319f9 14565/* pcm configuration: identical with ALC880 */
f6a92248
KY
14566#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14567#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14568#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14569#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14570
a9111321 14571static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
f03d3115
TI
14572 .substreams = 1,
14573 .channels_min = 2,
14574 .channels_max = 8,
14575 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14576 /* NID is set in alc_build_pcms */
14577 .ops = {
14578 .open = alc880_playback_pcm_open,
14579 .prepare = alc880_playback_pcm_prepare,
14580 .cleanup = alc880_playback_pcm_cleanup
14581 },
14582};
14583
a9111321 14584static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
f03d3115
TI
14585 .substreams = 1,
14586 .channels_min = 2,
14587 .channels_max = 2,
14588 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14589 /* NID is set in alc_build_pcms */
14590};
14591
ad35879a
TI
14592#ifdef CONFIG_SND_HDA_POWER_SAVE
14593static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14594{
14595 switch (codec->subsystem_id) {
14596 case 0x103c1586:
14597 return 1;
14598 }
14599 return 0;
14600}
14601
14602static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14603{
14604 /* update mute-LED according to the speaker mute state */
14605 if (nid == 0x01 || nid == 0x14) {
14606 int pinval;
14607 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14608 HDA_AMP_MUTE)
14609 pinval = 0x24;
14610 else
14611 pinval = 0x20;
14612 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14613 snd_hda_codec_update_cache(codec, 0x19, 0,
14614 AC_VERB_SET_PIN_WIDGET_CONTROL,
14615 pinval);
ad35879a
TI
14616 }
14617 return alc_check_power_status(codec, nid);
14618}
14619#endif /* CONFIG_SND_HDA_POWER_SAVE */
14620
840b64c0
TI
14621static int alc275_setup_dual_adc(struct hda_codec *codec)
14622{
14623 struct alc_spec *spec = codec->spec;
14624
14625 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14626 return 0;
14627 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14628 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14629 if (spec->ext_mic.pin <= 0x12) {
14630 spec->private_adc_nids[0] = 0x08;
14631 spec->private_adc_nids[1] = 0x11;
14632 spec->private_capsrc_nids[0] = 0x23;
14633 spec->private_capsrc_nids[1] = 0x22;
14634 } else {
14635 spec->private_adc_nids[0] = 0x11;
14636 spec->private_adc_nids[1] = 0x08;
14637 spec->private_capsrc_nids[0] = 0x22;
14638 spec->private_capsrc_nids[1] = 0x23;
14639 }
14640 spec->adc_nids = spec->private_adc_nids;
14641 spec->capsrc_nids = spec->private_capsrc_nids;
14642 spec->num_adc_nids = 2;
14643 spec->dual_adc_switch = 1;
14644 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14645 spec->adc_nids[0], spec->adc_nids[1]);
14646 return 1;
14647 }
14648 return 0;
14649}
14650
d433a678
TI
14651/* different alc269-variants */
14652enum {
14653 ALC269_TYPE_NORMAL,
48c88e82 14654 ALC269_TYPE_ALC258,
d433a678 14655 ALC269_TYPE_ALC259,
48c88e82
KY
14656 ALC269_TYPE_ALC269VB,
14657 ALC269_TYPE_ALC270,
d433a678
TI
14658 ALC269_TYPE_ALC271X,
14659};
14660
f6a92248
KY
14661/*
14662 * BIOS auto configuration
14663 */
14664static int alc269_parse_auto_config(struct hda_codec *codec)
14665{
14666 struct alc_spec *spec = codec->spec;
cfb9fb55 14667 int err;
4c6d72d1 14668 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
f6a92248
KY
14669
14670 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14671 alc269_ignore);
14672 if (err < 0)
14673 return err;
14674
14675 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14676 if (err < 0)
14677 return err;
f3550d1b
TI
14678 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14679 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14680 else
14681 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14682 0x22, 0);
f6a92248
KY
14683 if (err < 0)
14684 return err;
14685
14686 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14687
757899ac 14688 alc_auto_parse_digital(codec);
f6a92248 14689
603c4019 14690 if (spec->kctls.list)
d88897ea 14691 add_mixer(spec, spec->kctls.list);
f6a92248 14692
1f0f4b80 14693 if (spec->codec_variant != ALC269_TYPE_NORMAL)
6227cdce 14694 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
1f0f4b80 14695 else
6227cdce 14696 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87 14697
f6a92248 14698 spec->num_mux_defs = 1;
61b9b9b1 14699 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14700
14701 if (!alc275_setup_dual_adc(codec))
14702 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14703 sizeof(alc269_adc_candidates));
6694635d 14704
f6a92248
KY
14705 err = alc_auto_add_mic_boost(codec);
14706 if (err < 0)
14707 return err;
14708
7e0e44d4 14709 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14710 set_capture_mixer(codec);
f53281e6 14711
f6a92248
KY
14712 return 1;
14713}
14714
e9af4f36
TI
14715#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14716#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248 14717#define alc269_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 14718#define alc269_auto_init_input_src alc882_auto_init_input_src
f6a92248
KY
14719
14720
14721/* init callback for auto-configuration model -- overriding the default init */
14722static void alc269_auto_init(struct hda_codec *codec)
14723{
f6c7e546 14724 struct alc_spec *spec = codec->spec;
f6a92248
KY
14725 alc269_auto_init_multi_out(codec);
14726 alc269_auto_init_hp_out(codec);
14727 alc269_auto_init_analog_input(codec);
ae0ebbf7
TI
14728 if (!spec->dual_adc_switch)
14729 alc269_auto_init_input_src(codec);
757899ac 14730 alc_auto_init_digital(codec);
f6c7e546 14731 if (spec->unsol_event)
7fb0d78f 14732 alc_inithook(codec);
f6a92248
KY
14733}
14734
0ec33d1f
TI
14735static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14736{
14737 int val = alc_read_coef_idx(codec, 0x04);
14738 if (power_up)
14739 val |= 1 << 11;
14740 else
14741 val &= ~(1 << 11);
14742 alc_write_coef_idx(codec, 0x04, val);
14743}
14744
5402e4cb 14745static void alc269_shutup(struct hda_codec *codec)
977ddd6b 14746{
0ec33d1f
TI
14747 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14748 alc269_toggle_power_output(codec, 0);
977ddd6b 14749 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14750 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14751 msleep(150);
14752 }
977ddd6b 14753}
0ec33d1f 14754
5402e4cb 14755#ifdef SND_HDA_NEEDS_RESUME
977ddd6b
KY
14756static int alc269_resume(struct hda_codec *codec)
14757{
977ddd6b 14758 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14759 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14760 msleep(150);
14761 }
14762
14763 codec->patch_ops.init(codec);
14764
14765 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14766 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14767 msleep(200);
14768 }
14769
0ec33d1f
TI
14770 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14771 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14772
14773 snd_hda_codec_resume_amp(codec);
14774 snd_hda_codec_resume_cache(codec);
9e5341b9 14775 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14776 return 0;
14777}
0ec33d1f 14778#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14779
1a99d4a4 14780static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14781 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14782{
14783 int coef;
14784
58701120 14785 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14786 return;
1a99d4a4
KY
14787 coef = alc_read_coef_idx(codec, 0x1e);
14788 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14789}
14790
6981d184
TI
14791static void alc271_fixup_dmic(struct hda_codec *codec,
14792 const struct alc_fixup *fix, int action)
14793{
a9111321 14794 static const struct hda_verb verbs[] = {
6981d184
TI
14795 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14796 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14797 {}
14798 };
14799 unsigned int cfg;
14800
14801 if (strcmp(codec->chip_name, "ALC271X"))
14802 return;
14803 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14804 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14805 snd_hda_sequence_write(codec, verbs);
14806}
14807
ff818c24
TI
14808enum {
14809 ALC269_FIXUP_SONY_VAIO,
74dc8909 14810 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14811 ALC269_FIXUP_DELL_M101Z,
022c92be 14812 ALC269_FIXUP_SKU_IGNORE,
ac612407 14813 ALC269_FIXUP_ASUS_G73JW,
357f915e 14814 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14815 ALC275_FIXUP_SONY_HWEQ,
6981d184 14816 ALC271_FIXUP_DMIC,
ff818c24
TI
14817};
14818
ff818c24
TI
14819static const struct alc_fixup alc269_fixups[] = {
14820 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14821 .type = ALC_FIXUP_VERBS,
14822 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14823 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14824 {}
14825 }
ff818c24 14826 },
74dc8909 14827 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14828 .type = ALC_FIXUP_VERBS,
14829 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14830 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14831 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14832 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14833 { }
b5bfbc67
TI
14834 },
14835 .chained = true,
14836 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14837 },
145a902b 14838 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14839 .type = ALC_FIXUP_VERBS,
14840 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14841 /* Enables internal speaker */
14842 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14843 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14844 {}
14845 }
14846 },
022c92be 14847 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14848 .type = ALC_FIXUP_SKU,
14849 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14850 },
ac612407 14851 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14852 .type = ALC_FIXUP_PINS,
14853 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14854 { 0x17, 0x99130111 }, /* subwoofer */
14855 { }
14856 }
14857 },
357f915e 14858 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14859 .type = ALC_FIXUP_VERBS,
14860 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14861 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14862 {}
14863 }
14864 },
1a99d4a4 14865 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14866 .type = ALC_FIXUP_FUNC,
14867 .v.func = alc269_fixup_hweq,
14868 .chained = true,
14869 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6981d184
TI
14870 },
14871 [ALC271_FIXUP_DMIC] = {
14872 .type = ALC_FIXUP_FUNC,
14873 .v.func = alc271_fixup_dmic,
14874 },
ff818c24
TI
14875};
14876
a9111321 14877static const struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14878 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14879 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14880 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14881 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14882 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6981d184 14883 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
022c92be 14884 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14885 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14886 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14887 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14888 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14889 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14890 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14891 {}
14892};
14893
14894
f6a92248
KY
14895/*
14896 * configuration and preset
14897 */
ea734963 14898static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14899 [ALC269_BASIC] = "basic",
2922c9af 14900 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14901 [ALC269_AMIC] = "laptop-amic",
14902 [ALC269_DMIC] = "laptop-dmic",
64154835 14903 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14904 [ALC269_LIFEBOOK] = "lifebook",
14905 [ALC269_AUTO] = "auto",
f6a92248
KY
14906};
14907
a9111321 14908static const struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14909 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14910 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14911 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14912 ALC269_AMIC),
14913 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14914 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14915 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14916 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14917 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14918 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14919 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14920 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14921 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14922 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14923 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14924 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14925 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14926 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14927 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14928 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14929 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14930 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14931 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14932 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14933 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14934 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14935 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14936 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14937 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14938 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14939 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14940 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14941 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14942 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14943 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14944 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14945 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14946 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14947 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14948 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14949 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14950 ALC269_DMIC),
60db6b53 14951 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14952 ALC269_DMIC),
14953 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14954 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14955 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14956 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14957 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14958 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14959 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14960 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14961 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14962 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14963 {}
14964};
14965
a9111321 14966static const struct alc_config_preset alc269_presets[] = {
f6a92248 14967 [ALC269_BASIC] = {
f9e336f6 14968 .mixers = { alc269_base_mixer },
f6a92248
KY
14969 .init_verbs = { alc269_init_verbs },
14970 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14971 .dac_nids = alc269_dac_nids,
14972 .hp_nid = 0x03,
14973 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14974 .channel_mode = alc269_modes,
14975 .input_mux = &alc269_capture_source,
14976 },
60db6b53
KY
14977 [ALC269_QUANTA_FL1] = {
14978 .mixers = { alc269_quanta_fl1_mixer },
14979 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14980 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14981 .dac_nids = alc269_dac_nids,
14982 .hp_nid = 0x03,
14983 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14984 .channel_mode = alc269_modes,
14985 .input_mux = &alc269_capture_source,
14986 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14987 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14988 .init_hook = alc269_quanta_fl1_init_hook,
14989 },
84898e87
KY
14990 [ALC269_AMIC] = {
14991 .mixers = { alc269_laptop_mixer },
14992 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14993 .init_verbs = { alc269_init_verbs,
84898e87 14994 alc269_laptop_amic_init_verbs },
f53281e6
KY
14995 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14996 .dac_nids = alc269_dac_nids,
14997 .hp_nid = 0x03,
14998 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14999 .channel_mode = alc269_modes,
3b8510ce 15000 .unsol_event = alc_sku_unsol_event,
84898e87 15001 .setup = alc269_laptop_amic_setup,
3b8510ce 15002 .init_hook = alc_inithook,
f53281e6 15003 },
84898e87
KY
15004 [ALC269_DMIC] = {
15005 .mixers = { alc269_laptop_mixer },
15006 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15007 .init_verbs = { alc269_init_verbs,
84898e87
KY
15008 alc269_laptop_dmic_init_verbs },
15009 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15010 .dac_nids = alc269_dac_nids,
15011 .hp_nid = 0x03,
15012 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15013 .channel_mode = alc269_modes,
3b8510ce 15014 .unsol_event = alc_sku_unsol_event,
84898e87 15015 .setup = alc269_laptop_dmic_setup,
3b8510ce 15016 .init_hook = alc_inithook,
84898e87
KY
15017 },
15018 [ALC269VB_AMIC] = {
15019 .mixers = { alc269vb_laptop_mixer },
15020 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15021 .init_verbs = { alc269vb_init_verbs,
15022 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15023 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15024 .dac_nids = alc269_dac_nids,
15025 .hp_nid = 0x03,
15026 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15027 .channel_mode = alc269_modes,
3b8510ce 15028 .unsol_event = alc_sku_unsol_event,
226b1ec8 15029 .setup = alc269vb_laptop_amic_setup,
3b8510ce 15030 .init_hook = alc_inithook,
84898e87
KY
15031 },
15032 [ALC269VB_DMIC] = {
15033 .mixers = { alc269vb_laptop_mixer },
15034 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15035 .init_verbs = { alc269vb_init_verbs,
15036 alc269vb_laptop_dmic_init_verbs },
15037 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15038 .dac_nids = alc269_dac_nids,
15039 .hp_nid = 0x03,
15040 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15041 .channel_mode = alc269_modes,
3b8510ce 15042 .unsol_event = alc_sku_unsol_event,
84898e87 15043 .setup = alc269vb_laptop_dmic_setup,
3b8510ce 15044 .init_hook = alc_inithook,
f53281e6 15045 },
26f5df26 15046 [ALC269_FUJITSU] = {
45bdd1c1 15047 .mixers = { alc269_fujitsu_mixer },
84898e87 15048 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15049 .init_verbs = { alc269_init_verbs,
84898e87 15050 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15051 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15052 .dac_nids = alc269_dac_nids,
15053 .hp_nid = 0x03,
15054 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15055 .channel_mode = alc269_modes,
3b8510ce 15056 .unsol_event = alc_sku_unsol_event,
84898e87 15057 .setup = alc269_laptop_dmic_setup,
3b8510ce 15058 .init_hook = alc_inithook,
26f5df26 15059 },
64154835
TV
15060 [ALC269_LIFEBOOK] = {
15061 .mixers = { alc269_lifebook_mixer },
15062 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15063 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15064 .dac_nids = alc269_dac_nids,
15065 .hp_nid = 0x03,
15066 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15067 .channel_mode = alc269_modes,
15068 .input_mux = &alc269_capture_source,
15069 .unsol_event = alc269_lifebook_unsol_event,
3b8510ce 15070 .setup = alc269_lifebook_setup,
64154835
TV
15071 .init_hook = alc269_lifebook_init_hook,
15072 },
fe3eb0a7
KY
15073 [ALC271_ACER] = {
15074 .mixers = { alc269_asus_mixer },
15075 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15076 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15077 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15078 .dac_nids = alc269_dac_nids,
15079 .adc_nids = alc262_dmic_adc_nids,
15080 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15081 .capsrc_nids = alc262_dmic_capsrc_nids,
15082 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15083 .channel_mode = alc269_modes,
15084 .input_mux = &alc269_capture_source,
15085 .dig_out_nid = ALC880_DIGOUT_NID,
15086 .unsol_event = alc_sku_unsol_event,
15087 .setup = alc269vb_laptop_dmic_setup,
15088 .init_hook = alc_inithook,
15089 },
f6a92248
KY
15090};
15091
977ddd6b
KY
15092static int alc269_fill_coef(struct hda_codec *codec)
15093{
15094 int val;
15095
15096 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15097 alc_write_coef_idx(codec, 0xf, 0x960b);
15098 alc_write_coef_idx(codec, 0xe, 0x8817);
15099 }
15100
15101 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15102 alc_write_coef_idx(codec, 0xf, 0x960b);
15103 alc_write_coef_idx(codec, 0xe, 0x8814);
15104 }
15105
15106 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15107 val = alc_read_coef_idx(codec, 0x04);
15108 /* Power up output pin */
15109 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15110 }
15111
15112 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15113 val = alc_read_coef_idx(codec, 0xd);
15114 if ((val & 0x0c00) >> 10 != 0x1) {
15115 /* Capless ramp up clock control */
b896b4eb 15116 alc_write_coef_idx(codec, 0xd, val | (1<<10));
977ddd6b
KY
15117 }
15118 val = alc_read_coef_idx(codec, 0x17);
15119 if ((val & 0x01c0) >> 6 != 0x4) {
15120 /* Class D power on reset */
b896b4eb 15121 alc_write_coef_idx(codec, 0x17, val | (1<<7));
977ddd6b
KY
15122 }
15123 }
b896b4eb
KY
15124
15125 val = alc_read_coef_idx(codec, 0xd); /* Class D */
15126 alc_write_coef_idx(codec, 0xd, val | (1<<14));
15127
15128 val = alc_read_coef_idx(codec, 0x4); /* HP */
15129 alc_write_coef_idx(codec, 0x4, val | (1<<11));
15130
977ddd6b
KY
15131 return 0;
15132}
15133
f6a92248
KY
15134static int patch_alc269(struct hda_codec *codec)
15135{
15136 struct alc_spec *spec;
48c88e82 15137 int board_config, coef;
f6a92248
KY
15138 int err;
15139
15140 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15141 if (spec == NULL)
15142 return -ENOMEM;
15143
15144 codec->spec = spec;
15145
1f0f4b80
TI
15146 spec->mixer_nid = 0x0b;
15147
da00c244
KY
15148 alc_auto_parse_customize_define(codec);
15149
c793bec5
KY
15150 if (codec->vendor_id == 0x10ec0269) {
15151 coef = alc_read_coef_idx(codec, 0);
15152 if ((coef & 0x00f0) == 0x0010) {
15153 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15154 spec->cdefine.platform_type == 1) {
15155 alc_codec_rename(codec, "ALC271X");
15156 spec->codec_variant = ALC269_TYPE_ALC271X;
15157 } else if ((coef & 0xf000) == 0x1000) {
15158 spec->codec_variant = ALC269_TYPE_ALC270;
15159 } else if ((coef & 0xf000) == 0x2000) {
15160 alc_codec_rename(codec, "ALC259");
15161 spec->codec_variant = ALC269_TYPE_ALC259;
15162 } else if ((coef & 0xf000) == 0x3000) {
15163 alc_codec_rename(codec, "ALC258");
15164 spec->codec_variant = ALC269_TYPE_ALC258;
15165 } else {
15166 alc_codec_rename(codec, "ALC269VB");
15167 spec->codec_variant = ALC269_TYPE_ALC269VB;
15168 }
15169 } else
15170 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15171 alc269_fill_coef(codec);
15172 }
977ddd6b 15173
f6a92248
KY
15174 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15175 alc269_models,
15176 alc269_cfg_tbl);
15177
15178 if (board_config < 0) {
9a11f1aa
TI
15179 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15180 codec->chip_name);
f6a92248
KY
15181 board_config = ALC269_AUTO;
15182 }
15183
b5bfbc67
TI
15184 if (board_config == ALC269_AUTO) {
15185 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15186 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15187 }
ff818c24 15188
f6a92248
KY
15189 if (board_config == ALC269_AUTO) {
15190 /* automatic parse from the BIOS config */
15191 err = alc269_parse_auto_config(codec);
15192 if (err < 0) {
15193 alc_free(codec);
15194 return err;
15195 } else if (!err) {
15196 printk(KERN_INFO
15197 "hda_codec: Cannot set up configuration "
15198 "from BIOS. Using base mode...\n");
15199 board_config = ALC269_BASIC;
15200 }
15201 }
15202
dc1eae25 15203 if (has_cdefine_beep(codec)) {
8af2591d
TI
15204 err = snd_hda_attach_beep_device(codec, 0x1);
15205 if (err < 0) {
15206 alc_free(codec);
15207 return err;
15208 }
680cd536
KK
15209 }
15210
f6a92248 15211 if (board_config != ALC269_AUTO)
e9c364c0 15212 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15213
84898e87 15214 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15215 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15216 * fix the sample rate of analog I/O to 44.1kHz
15217 */
15218 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15219 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15220 } else if (spec->dual_adc_switch) {
15221 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15222 /* switch ADC dynamically */
15223 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15224 } else {
15225 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15226 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15227 }
f6a92248
KY
15228 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15229 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15230
6694635d 15231 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15232 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15233 spec->adc_nids = alc269_adc_nids;
15234 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15235 spec->capsrc_nids = alc269_capsrc_nids;
15236 } else {
15237 spec->adc_nids = alc269vb_adc_nids;
15238 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15239 spec->capsrc_nids = alc269vb_capsrc_nids;
15240 }
84898e87
KY
15241 }
15242
f9e336f6 15243 if (!spec->cap_mixer)
b59bdf3b 15244 set_capture_mixer(codec);
dc1eae25 15245 if (has_cdefine_beep(codec))
da00c244 15246 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15247
b5bfbc67 15248 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15249
100d5eb3
TI
15250 spec->vmaster_nid = 0x02;
15251
f6a92248 15252 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15253#ifdef SND_HDA_NEEDS_RESUME
15254 codec->patch_ops.resume = alc269_resume;
15255#endif
f6a92248
KY
15256 if (board_config == ALC269_AUTO)
15257 spec->init_hook = alc269_auto_init;
5402e4cb 15258 spec->shutup = alc269_shutup;
bf1b0225
KY
15259
15260 alc_init_jacks(codec);
f6a92248
KY
15261#ifdef CONFIG_SND_HDA_POWER_SAVE
15262 if (!spec->loopback.amplist)
15263 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15264 if (alc269_mic2_for_mute_led(codec))
15265 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15266#endif
15267
15268 return 0;
15269}
15270
df694daa
KY
15271/*
15272 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15273 */
15274
15275/*
15276 * set the path ways for 2 channel output
15277 * need to set the codec line out and mic 1 pin widgets to inputs
15278 */
a9111321 15279static const struct hda_verb alc861_threestack_ch2_init[] = {
df694daa
KY
15280 /* set pin widget 1Ah (line in) for input */
15281 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15282 /* set pin widget 18h (mic1/2) for input, for mic also enable
15283 * the vref
15284 */
df694daa
KY
15285 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15286
9c7f852e
TI
15287 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15288#if 0
15289 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15290 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15291#endif
df694daa
KY
15292 { } /* end */
15293};
15294/*
15295 * 6ch mode
15296 * need to set the codec line out and mic 1 pin widgets to outputs
15297 */
a9111321 15298static const struct hda_verb alc861_threestack_ch6_init[] = {
df694daa
KY
15299 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15300 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15301 /* set pin widget 18h (mic1) for output (CLFE)*/
15302 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15303
15304 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15305 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15306
9c7f852e
TI
15307 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15308#if 0
15309 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15310 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15311#endif
df694daa
KY
15312 { } /* end */
15313};
15314
a9111321 15315static const struct hda_channel_mode alc861_threestack_modes[2] = {
df694daa
KY
15316 { 2, alc861_threestack_ch2_init },
15317 { 6, alc861_threestack_ch6_init },
15318};
22309c3e 15319/* Set mic1 as input and unmute the mixer */
a9111321 15320static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
22309c3e
TI
15321 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15322 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15323 { } /* end */
15324};
15325/* Set mic1 as output and mute mixer */
a9111321 15326static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
22309c3e
TI
15327 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15328 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15329 { } /* end */
15330};
15331
a9111321 15332static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
22309c3e
TI
15333 { 2, alc861_uniwill_m31_ch2_init },
15334 { 4, alc861_uniwill_m31_ch4_init },
15335};
df694daa 15336
7cdbff94 15337/* Set mic1 and line-in as input and unmute the mixer */
a9111321 15338static const struct hda_verb alc861_asus_ch2_init[] = {
7cdbff94
MD
15339 /* set pin widget 1Ah (line in) for input */
15340 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15341 /* set pin widget 18h (mic1/2) for input, for mic also enable
15342 * the vref
15343 */
7cdbff94
MD
15344 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15345
15346 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15347#if 0
15348 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15349 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15350#endif
15351 { } /* end */
15352};
15353/* Set mic1 nad line-in as output and mute mixer */
a9111321 15354static const struct hda_verb alc861_asus_ch6_init[] = {
7cdbff94
MD
15355 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15356 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15357 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15358 /* set pin widget 18h (mic1) for output (CLFE)*/
15359 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15360 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15361 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15362 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15363
15364 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15365#if 0
15366 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15367 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15368#endif
15369 { } /* end */
15370};
15371
a9111321 15372static const struct hda_channel_mode alc861_asus_modes[2] = {
7cdbff94
MD
15373 { 2, alc861_asus_ch2_init },
15374 { 6, alc861_asus_ch6_init },
15375};
15376
df694daa
KY
15377/* patch-ALC861 */
15378
a9111321 15379static const struct snd_kcontrol_new alc861_base_mixer[] = {
df694daa
KY
15380 /* output mixer control */
15381 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15382 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15383 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15384 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15385 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15386
15387 /*Input mixer control */
15388 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15389 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15390 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15391 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15392 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15393 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15395 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15396 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15397 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15398
df694daa
KY
15399 { } /* end */
15400};
15401
a9111321 15402static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
df694daa
KY
15403 /* output mixer control */
15404 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15405 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15406 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15407 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15408 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15409
15410 /* Input mixer control */
15411 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15412 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15413 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15414 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15415 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15416 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15418 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15419 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15421
df694daa
KY
15422 {
15423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15424 .name = "Channel Mode",
15425 .info = alc_ch_mode_info,
15426 .get = alc_ch_mode_get,
15427 .put = alc_ch_mode_put,
15428 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15429 },
15430 { } /* end */
a53d1aec
TD
15431};
15432
a9111321 15433static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15434 /* output mixer control */
15435 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15437 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15438
a53d1aec 15439 { } /* end */
f12ab1e0 15440};
a53d1aec 15441
a9111321 15442static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
22309c3e
TI
15443 /* output mixer control */
15444 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15445 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15446 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15447 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15448 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15449
15450 /* Input mixer control */
15451 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15452 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15453 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15454 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15455 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15456 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15458 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15459 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15461
22309c3e
TI
15462 {
15463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15464 .name = "Channel Mode",
15465 .info = alc_ch_mode_info,
15466 .get = alc_ch_mode_get,
15467 .put = alc_ch_mode_put,
15468 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15469 },
15470 { } /* end */
f12ab1e0 15471};
7cdbff94 15472
a9111321 15473static const struct snd_kcontrol_new alc861_asus_mixer[] = {
7cdbff94
MD
15474 /* output mixer control */
15475 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15476 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15477 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15478 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15479 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15480
15481 /* Input mixer control */
15482 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15483 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15484 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15485 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15486 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15487 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15488 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15489 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15490 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15491 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15492
7cdbff94
MD
15493 {
15494 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15495 .name = "Channel Mode",
15496 .info = alc_ch_mode_info,
15497 .get = alc_ch_mode_get,
15498 .put = alc_ch_mode_put,
15499 .private_value = ARRAY_SIZE(alc861_asus_modes),
15500 },
15501 { }
56bb0cab
TI
15502};
15503
15504/* additional mixer */
a9111321 15505static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15506 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15507 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15508 { }
15509};
7cdbff94 15510
df694daa
KY
15511/*
15512 * generic initialization of ADC, input mixers and output mixers
15513 */
a9111321 15514static const struct hda_verb alc861_base_init_verbs[] = {
df694daa
KY
15515 /*
15516 * Unmute ADC0 and set the default input to mic-in
15517 */
15518 /* port-A for surround (rear panel) */
15519 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15520 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15521 /* port-B for mic-in (rear panel) with vref */
15522 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15523 /* port-C for line-in (rear panel) */
15524 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15525 /* port-D for Front */
15526 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15527 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15528 /* port-E for HP out (front panel) */
15529 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15530 /* route front PCM to HP */
9dece1d7 15531 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15532 /* port-F for mic-in (front panel) with vref */
15533 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15534 /* port-G for CLFE (rear panel) */
15535 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15536 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15537 /* port-H for side (rear panel) */
15538 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15539 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15540 /* CD-in */
15541 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15542 /* route front mic to ADC1*/
15543 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15544 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15545
df694daa
KY
15546 /* Unmute DAC0~3 & spdif out*/
15547 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15548 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15549 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15550 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15552
df694daa
KY
15553 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15554 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15555 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15556 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15557 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15558
df694daa
KY
15559 /* Unmute Stereo Mixer 15 */
15560 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15561 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15562 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15564
15565 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15566 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15567 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15568 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15569 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15571 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15572 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15573 /* hp used DAC 3 (Front) */
15574 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15575 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15576
15577 { }
15578};
15579
a9111321 15580static const struct hda_verb alc861_threestack_init_verbs[] = {
df694daa
KY
15581 /*
15582 * Unmute ADC0 and set the default input to mic-in
15583 */
15584 /* port-A for surround (rear panel) */
15585 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15586 /* port-B for mic-in (rear panel) with vref */
15587 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15588 /* port-C for line-in (rear panel) */
15589 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15590 /* port-D for Front */
15591 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15592 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15593 /* port-E for HP out (front panel) */
15594 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15595 /* route front PCM to HP */
9dece1d7 15596 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15597 /* port-F for mic-in (front panel) with vref */
15598 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15599 /* port-G for CLFE (rear panel) */
15600 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15601 /* port-H for side (rear panel) */
15602 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15603 /* CD-in */
15604 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15605 /* route front mic to ADC1*/
15606 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15607 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15608 /* Unmute DAC0~3 & spdif out*/
15609 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15610 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15611 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15612 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15613 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15614
df694daa
KY
15615 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15616 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15617 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15618 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15619 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15620
df694daa
KY
15621 /* Unmute Stereo Mixer 15 */
15622 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15624 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15626
15627 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15628 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15629 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15630 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15631 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15633 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15635 /* hp used DAC 3 (Front) */
15636 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15638 { }
15639};
22309c3e 15640
a9111321 15641static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
22309c3e
TI
15642 /*
15643 * Unmute ADC0 and set the default input to mic-in
15644 */
15645 /* port-A for surround (rear panel) */
15646 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15647 /* port-B for mic-in (rear panel) with vref */
15648 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15649 /* port-C for line-in (rear panel) */
15650 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15651 /* port-D for Front */
15652 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15653 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15654 /* port-E for HP out (front panel) */
f12ab1e0
TI
15655 /* this has to be set to VREF80 */
15656 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15657 /* route front PCM to HP */
9dece1d7 15658 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15659 /* port-F for mic-in (front panel) with vref */
15660 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15661 /* port-G for CLFE (rear panel) */
15662 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15663 /* port-H for side (rear panel) */
15664 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15665 /* CD-in */
15666 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15667 /* route front mic to ADC1*/
15668 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15669 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15670 /* Unmute DAC0~3 & spdif out*/
15671 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15672 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15673 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15674 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15675 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15676
22309c3e
TI
15677 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15678 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15679 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15680 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15681 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15682
22309c3e
TI
15683 /* Unmute Stereo Mixer 15 */
15684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15688
15689 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15690 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15691 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15692 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15694 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15696 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15697 /* hp used DAC 3 (Front) */
15698 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15699 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15700 { }
15701};
15702
a9111321 15703static const struct hda_verb alc861_asus_init_verbs[] = {
7cdbff94
MD
15704 /*
15705 * Unmute ADC0 and set the default input to mic-in
15706 */
f12ab1e0
TI
15707 /* port-A for surround (rear panel)
15708 * according to codec#0 this is the HP jack
15709 */
7cdbff94
MD
15710 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15711 /* route front PCM to HP */
15712 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15713 /* port-B for mic-in (rear panel) with vref */
15714 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15715 /* port-C for line-in (rear panel) */
15716 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15717 /* port-D for Front */
15718 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15719 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15720 /* port-E for HP out (front panel) */
f12ab1e0
TI
15721 /* this has to be set to VREF80 */
15722 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15723 /* route front PCM to HP */
9dece1d7 15724 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15725 /* port-F for mic-in (front panel) with vref */
15726 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15727 /* port-G for CLFE (rear panel) */
15728 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15729 /* port-H for side (rear panel) */
15730 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15731 /* CD-in */
15732 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15733 /* route front mic to ADC1*/
15734 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15735 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15736 /* Unmute DAC0~3 & spdif out*/
15737 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15738 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15739 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15740 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15741 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15742 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15743 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15744 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15745 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15746 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15747
7cdbff94
MD
15748 /* Unmute Stereo Mixer 15 */
15749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15751 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15752 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15753
15754 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15755 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15756 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15757 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15758 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15759 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15760 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15761 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15762 /* hp used DAC 3 (Front) */
15763 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15764 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15765 { }
15766};
15767
56bb0cab 15768/* additional init verbs for ASUS laptops */
a9111321 15769static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
56bb0cab
TI
15770 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15771 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15772 { }
15773};
7cdbff94 15774
a9111321 15775static const struct hda_verb alc861_toshiba_init_verbs[] = {
a53d1aec 15776 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15777
a53d1aec
TD
15778 { }
15779};
15780
15781/* toggle speaker-output according to the hp-jack state */
15782static void alc861_toshiba_automute(struct hda_codec *codec)
15783{
864f92be 15784 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15785
47fd830a
TI
15786 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15787 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15788 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15789 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15790}
15791
15792static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15793 unsigned int res)
15794{
a53d1aec
TD
15795 if ((res >> 26) == ALC880_HP_EVENT)
15796 alc861_toshiba_automute(codec);
15797}
15798
def319f9 15799/* pcm configuration: identical with ALC880 */
df694daa
KY
15800#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15801#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15802#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15803#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15804
15805
15806#define ALC861_DIGOUT_NID 0x07
15807
a9111321 15808static const struct hda_channel_mode alc861_8ch_modes[1] = {
df694daa
KY
15809 { 8, NULL }
15810};
15811
4c6d72d1 15812static const hda_nid_t alc861_dac_nids[4] = {
df694daa
KY
15813 /* front, surround, clfe, side */
15814 0x03, 0x06, 0x05, 0x04
15815};
15816
4c6d72d1 15817static const hda_nid_t alc660_dac_nids[3] = {
9c7f852e
TI
15818 /* front, clfe, surround */
15819 0x03, 0x05, 0x06
15820};
15821
4c6d72d1 15822static const hda_nid_t alc861_adc_nids[1] = {
df694daa
KY
15823 /* ADC0-2 */
15824 0x08,
15825};
15826
a9111321 15827static const struct hda_input_mux alc861_capture_source = {
df694daa
KY
15828 .num_items = 5,
15829 .items = {
15830 { "Mic", 0x0 },
15831 { "Front Mic", 0x3 },
15832 { "Line", 0x1 },
15833 { "CD", 0x4 },
15834 { "Mixer", 0x5 },
15835 },
15836};
15837
1c20930a
TI
15838static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15839{
15840 struct alc_spec *spec = codec->spec;
15841 hda_nid_t mix, srcs[5];
3af9ee6b 15842 int i, num;
1c20930a
TI
15843
15844 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15845 return 0;
15846 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15847 if (num < 0)
15848 return 0;
15849 for (i = 0; i < num; i++) {
15850 unsigned int type;
a22d543a 15851 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15852 if (type != AC_WID_AUD_OUT)
15853 continue;
3af9ee6b
TI
15854 if (!found_in_nid_list(srcs[i], spec->multiout.dac_nids,
15855 spec->multiout.num_dacs))
1c20930a
TI
15856 return srcs[i];
15857 }
15858 return 0;
15859}
15860
df694daa 15861/* fill in the dac_nids table from the parsed pin configuration */
cb053a82 15862static int alc861_auto_fill_dac_nids(struct hda_codec *codec)
df694daa 15863{
1c20930a 15864 struct alc_spec *spec = codec->spec;
cb053a82 15865 const struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa 15866 int i;
1c20930a 15867 hda_nid_t nid, dac;
df694daa
KY
15868
15869 spec->multiout.dac_nids = spec->private_dac_nids;
15870 for (i = 0; i < cfg->line_outs; i++) {
15871 nid = cfg->line_out_pins[i];
1c20930a
TI
15872 dac = alc861_look_for_dac(codec, nid);
15873 if (!dac)
15874 continue;
dda14410 15875 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15876 }
df694daa
KY
15877 return 0;
15878}
15879
bcb2f0f5
TI
15880static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15881 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15882{
bcb2f0f5 15883 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15884 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15885}
15886
bcb2f0f5
TI
15887#define alc861_create_out_sw(codec, pfx, nid, chs) \
15888 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15889
df694daa 15890/* add playback controls from the parsed DAC table */
1c20930a 15891static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15892 const struct auto_pin_cfg *cfg)
15893{
1c20930a 15894 struct alc_spec *spec = codec->spec;
df694daa 15895 hda_nid_t nid;
ce764ab2 15896 int i, err, noutputs;
1c20930a 15897
ce764ab2
TI
15898 noutputs = cfg->line_outs;
15899 if (spec->multi_ios > 0)
15900 noutputs += spec->multi_ios;
15901
15902 for (i = 0; i < noutputs; i++) {
6843ca16
TI
15903 const char *name;
15904 int index;
df694daa 15905 nid = spec->multiout.dac_nids[i];
f12ab1e0 15906 if (!nid)
df694daa 15907 continue;
6843ca16
TI
15908 name = alc_get_line_out_pfx(spec, i, true, &index);
15909 if (!name) {
df694daa 15910 /* Center/LFE */
1c20930a 15911 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15912 if (err < 0)
df694daa 15913 return err;
1c20930a 15914 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15915 if (err < 0)
df694daa
KY
15916 return err;
15917 } else {
5a882646 15918 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 15919 if (err < 0)
df694daa
KY
15920 return err;
15921 }
15922 }
15923 return 0;
15924}
15925
1c20930a 15926static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15927{
1c20930a 15928 struct alc_spec *spec = codec->spec;
df694daa
KY
15929 int err;
15930 hda_nid_t nid;
15931
f12ab1e0 15932 if (!pin)
df694daa
KY
15933 return 0;
15934
15935 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15936 nid = alc861_look_for_dac(codec, pin);
15937 if (nid) {
15938 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15939 if (err < 0)
15940 return err;
15941 spec->multiout.hp_nid = nid;
15942 }
df694daa
KY
15943 }
15944 return 0;
15945}
15946
15947/* create playback/capture controls for input pins */
05f5f477 15948static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15949 const struct auto_pin_cfg *cfg)
df694daa 15950{
05f5f477 15951 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15952}
15953
f12ab1e0
TI
15954static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15955 hda_nid_t nid,
1c20930a 15956 int pin_type, hda_nid_t dac)
df694daa 15957{
1c20930a
TI
15958 hda_nid_t mix, srcs[5];
15959 int i, num;
15960
564c5bea
JL
15961 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15962 pin_type);
1c20930a 15963 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15964 AMP_OUT_UNMUTE);
1c20930a
TI
15965 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15966 return;
15967 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15968 if (num < 0)
15969 return;
15970 for (i = 0; i < num; i++) {
15971 unsigned int mute;
15972 if (srcs[i] == dac || srcs[i] == 0x15)
15973 mute = AMP_IN_UNMUTE(i);
15974 else
15975 mute = AMP_IN_MUTE(i);
15976 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15977 mute);
15978 }
df694daa
KY
15979}
15980
15981static void alc861_auto_init_multi_out(struct hda_codec *codec)
15982{
15983 struct alc_spec *spec = codec->spec;
15984 int i;
15985
1f0f4b80 15986 for (i = 0; i < spec->autocfg.line_outs + spec->multi_ios; i++) {
df694daa 15987 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15988 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15989 if (nid)
baba8ee9 15990 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15991 spec->multiout.dac_nids[i]);
df694daa
KY
15992 }
15993}
15994
15995static void alc861_auto_init_hp_out(struct hda_codec *codec)
15996{
15997 struct alc_spec *spec = codec->spec;
df694daa 15998
15870f05
TI
15999 if (spec->autocfg.hp_outs)
16000 alc861_auto_set_output_and_unmute(codec,
16001 spec->autocfg.hp_pins[0],
16002 PIN_HP,
1c20930a 16003 spec->multiout.hp_nid);
15870f05
TI
16004 if (spec->autocfg.speaker_outs)
16005 alc861_auto_set_output_and_unmute(codec,
16006 spec->autocfg.speaker_pins[0],
16007 PIN_OUT,
1c20930a 16008 spec->multiout.dac_nids[0]);
df694daa
KY
16009}
16010
1f0f4b80 16011#define alc861_auto_init_analog_input alc880_auto_init_analog_input
df694daa
KY
16012
16013/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16014/* return 1 if successful, 0 if the proper config is not found,
16015 * or a negative error code
16016 */
df694daa
KY
16017static int alc861_parse_auto_config(struct hda_codec *codec)
16018{
16019 struct alc_spec *spec = codec->spec;
16020 int err;
4c6d72d1 16021 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
df694daa 16022
f12ab1e0
TI
16023 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16024 alc861_ignore);
16025 if (err < 0)
df694daa 16026 return err;
f12ab1e0 16027 if (!spec->autocfg.line_outs)
df694daa
KY
16028 return 0; /* can't find valid BIOS pin config */
16029
cb053a82 16030 err = alc861_auto_fill_dac_nids(codec);
ce764ab2
TI
16031 if (err < 0)
16032 return err;
cb053a82 16033 err = alc_auto_add_multi_channel_mode(codec, alc861_auto_fill_dac_nids);
f12ab1e0
TI
16034 if (err < 0)
16035 return err;
1c20930a 16036 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16037 if (err < 0)
16038 return err;
1c20930a 16039 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16040 if (err < 0)
16041 return err;
05f5f477 16042 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16043 if (err < 0)
df694daa
KY
16044 return err;
16045
16046 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16047
757899ac 16048 alc_auto_parse_digital(codec);
df694daa 16049
603c4019 16050 if (spec->kctls.list)
d88897ea 16051 add_mixer(spec, spec->kctls.list);
df694daa 16052
a1e8d2da 16053 spec->num_mux_defs = 1;
61b9b9b1 16054 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16055
16056 spec->adc_nids = alc861_adc_nids;
16057 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16058 set_capture_mixer(codec);
df694daa 16059
6227cdce 16060 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16061
df694daa
KY
16062 return 1;
16063}
16064
ae6b813a
TI
16065/* additional initialization for auto-configuration model */
16066static void alc861_auto_init(struct hda_codec *codec)
df694daa 16067{
f6c7e546 16068 struct alc_spec *spec = codec->spec;
df694daa
KY
16069 alc861_auto_init_multi_out(codec);
16070 alc861_auto_init_hp_out(codec);
16071 alc861_auto_init_analog_input(codec);
757899ac 16072 alc_auto_init_digital(codec);
f6c7e546 16073 if (spec->unsol_event)
7fb0d78f 16074 alc_inithook(codec);
df694daa
KY
16075}
16076
cb53c626 16077#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 16078static const struct hda_amp_list alc861_loopbacks[] = {
cb53c626
TI
16079 { 0x15, HDA_INPUT, 0 },
16080 { 0x15, HDA_INPUT, 1 },
16081 { 0x15, HDA_INPUT, 2 },
16082 { 0x15, HDA_INPUT, 3 },
16083 { } /* end */
16084};
16085#endif
16086
df694daa
KY
16087
16088/*
16089 * configuration and preset
16090 */
ea734963 16091static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16092 [ALC861_3ST] = "3stack",
16093 [ALC660_3ST] = "3stack-660",
16094 [ALC861_3ST_DIG] = "3stack-dig",
16095 [ALC861_6ST_DIG] = "6stack-dig",
16096 [ALC861_UNIWILL_M31] = "uniwill-m31",
16097 [ALC861_TOSHIBA] = "toshiba",
16098 [ALC861_ASUS] = "asus",
16099 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16100 [ALC861_AUTO] = "auto",
16101};
16102
a9111321 16103static const struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16104 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16105 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16106 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16107 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16108 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16109 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16110 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16111 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16112 * Any other models that need this preset?
16113 */
16114 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16115 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16116 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16117 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16118 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16119 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16120 /* FIXME: the below seems conflict */
16121 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16122 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16123 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16124 {}
16125};
16126
a9111321 16127static const struct alc_config_preset alc861_presets[] = {
df694daa
KY
16128 [ALC861_3ST] = {
16129 .mixers = { alc861_3ST_mixer },
16130 .init_verbs = { alc861_threestack_init_verbs },
16131 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16132 .dac_nids = alc861_dac_nids,
16133 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16134 .channel_mode = alc861_threestack_modes,
4e195a7b 16135 .need_dac_fix = 1,
df694daa
KY
16136 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16137 .adc_nids = alc861_adc_nids,
16138 .input_mux = &alc861_capture_source,
16139 },
16140 [ALC861_3ST_DIG] = {
16141 .mixers = { alc861_base_mixer },
16142 .init_verbs = { alc861_threestack_init_verbs },
16143 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16144 .dac_nids = alc861_dac_nids,
16145 .dig_out_nid = ALC861_DIGOUT_NID,
16146 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16147 .channel_mode = alc861_threestack_modes,
4e195a7b 16148 .need_dac_fix = 1,
df694daa
KY
16149 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16150 .adc_nids = alc861_adc_nids,
16151 .input_mux = &alc861_capture_source,
16152 },
16153 [ALC861_6ST_DIG] = {
16154 .mixers = { alc861_base_mixer },
16155 .init_verbs = { alc861_base_init_verbs },
16156 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16157 .dac_nids = alc861_dac_nids,
16158 .dig_out_nid = ALC861_DIGOUT_NID,
16159 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16160 .channel_mode = alc861_8ch_modes,
16161 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16162 .adc_nids = alc861_adc_nids,
16163 .input_mux = &alc861_capture_source,
16164 },
9c7f852e
TI
16165 [ALC660_3ST] = {
16166 .mixers = { alc861_3ST_mixer },
16167 .init_verbs = { alc861_threestack_init_verbs },
16168 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16169 .dac_nids = alc660_dac_nids,
16170 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16171 .channel_mode = alc861_threestack_modes,
4e195a7b 16172 .need_dac_fix = 1,
9c7f852e
TI
16173 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16174 .adc_nids = alc861_adc_nids,
16175 .input_mux = &alc861_capture_source,
16176 },
22309c3e
TI
16177 [ALC861_UNIWILL_M31] = {
16178 .mixers = { alc861_uniwill_m31_mixer },
16179 .init_verbs = { alc861_uniwill_m31_init_verbs },
16180 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16181 .dac_nids = alc861_dac_nids,
16182 .dig_out_nid = ALC861_DIGOUT_NID,
16183 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16184 .channel_mode = alc861_uniwill_m31_modes,
16185 .need_dac_fix = 1,
16186 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16187 .adc_nids = alc861_adc_nids,
16188 .input_mux = &alc861_capture_source,
16189 },
a53d1aec
TD
16190 [ALC861_TOSHIBA] = {
16191 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16192 .init_verbs = { alc861_base_init_verbs,
16193 alc861_toshiba_init_verbs },
a53d1aec
TD
16194 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16195 .dac_nids = alc861_dac_nids,
16196 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16197 .channel_mode = alc883_3ST_2ch_modes,
16198 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16199 .adc_nids = alc861_adc_nids,
16200 .input_mux = &alc861_capture_source,
16201 .unsol_event = alc861_toshiba_unsol_event,
16202 .init_hook = alc861_toshiba_automute,
16203 },
7cdbff94
MD
16204 [ALC861_ASUS] = {
16205 .mixers = { alc861_asus_mixer },
16206 .init_verbs = { alc861_asus_init_verbs },
16207 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16208 .dac_nids = alc861_dac_nids,
16209 .dig_out_nid = ALC861_DIGOUT_NID,
16210 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16211 .channel_mode = alc861_asus_modes,
16212 .need_dac_fix = 1,
16213 .hp_nid = 0x06,
16214 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16215 .adc_nids = alc861_adc_nids,
16216 .input_mux = &alc861_capture_source,
16217 },
56bb0cab
TI
16218 [ALC861_ASUS_LAPTOP] = {
16219 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16220 .init_verbs = { alc861_asus_init_verbs,
16221 alc861_asus_laptop_init_verbs },
16222 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16223 .dac_nids = alc861_dac_nids,
16224 .dig_out_nid = ALC861_DIGOUT_NID,
16225 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16226 .channel_mode = alc883_3ST_2ch_modes,
16227 .need_dac_fix = 1,
16228 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16229 .adc_nids = alc861_adc_nids,
16230 .input_mux = &alc861_capture_source,
16231 },
16232};
df694daa 16233
cfc9b06f
TI
16234/* Pin config fixes */
16235enum {
16236 PINFIX_FSC_AMILO_PI1505,
16237};
16238
cfc9b06f
TI
16239static const struct alc_fixup alc861_fixups[] = {
16240 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16241 .type = ALC_FIXUP_PINS,
16242 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16243 { 0x0b, 0x0221101f }, /* HP */
16244 { 0x0f, 0x90170310 }, /* speaker */
16245 { }
16246 }
cfc9b06f
TI
16247 },
16248};
16249
a9111321 16250static const struct snd_pci_quirk alc861_fixup_tbl[] = {
cfc9b06f
TI
16251 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16252 {}
16253};
df694daa
KY
16254
16255static int patch_alc861(struct hda_codec *codec)
16256{
16257 struct alc_spec *spec;
16258 int board_config;
16259 int err;
16260
dc041e0b 16261 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16262 if (spec == NULL)
16263 return -ENOMEM;
16264
f12ab1e0 16265 codec->spec = spec;
df694daa 16266
1f0f4b80
TI
16267 spec->mixer_nid = 0x15;
16268
f5fcc13c
TI
16269 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16270 alc861_models,
16271 alc861_cfg_tbl);
9c7f852e 16272
f5fcc13c 16273 if (board_config < 0) {
9a11f1aa
TI
16274 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16275 codec->chip_name);
df694daa
KY
16276 board_config = ALC861_AUTO;
16277 }
16278
b5bfbc67
TI
16279 if (board_config == ALC861_AUTO) {
16280 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16281 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16282 }
cfc9b06f 16283
df694daa
KY
16284 if (board_config == ALC861_AUTO) {
16285 /* automatic parse from the BIOS config */
16286 err = alc861_parse_auto_config(codec);
16287 if (err < 0) {
16288 alc_free(codec);
16289 return err;
f12ab1e0 16290 } else if (!err) {
9c7f852e
TI
16291 printk(KERN_INFO
16292 "hda_codec: Cannot set up configuration "
16293 "from BIOS. Using base mode...\n");
df694daa
KY
16294 board_config = ALC861_3ST_DIG;
16295 }
16296 }
16297
680cd536
KK
16298 err = snd_hda_attach_beep_device(codec, 0x23);
16299 if (err < 0) {
16300 alc_free(codec);
16301 return err;
16302 }
16303
df694daa 16304 if (board_config != ALC861_AUTO)
e9c364c0 16305 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16306
df694daa
KY
16307 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16308 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16309
df694daa
KY
16310 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16311 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16312
c7a8eb10
TI
16313 if (!spec->cap_mixer)
16314 set_capture_mixer(codec);
45bdd1c1
TI
16315 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16316
2134ea4f
TI
16317 spec->vmaster_nid = 0x03;
16318
b5bfbc67 16319 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16320
df694daa 16321 codec->patch_ops = alc_patch_ops;
c97259df 16322 if (board_config == ALC861_AUTO) {
ae6b813a 16323 spec->init_hook = alc861_auto_init;
c97259df
DC
16324#ifdef CONFIG_SND_HDA_POWER_SAVE
16325 spec->power_hook = alc_power_eapd;
16326#endif
16327 }
cb53c626
TI
16328#ifdef CONFIG_SND_HDA_POWER_SAVE
16329 if (!spec->loopback.amplist)
16330 spec->loopback.amplist = alc861_loopbacks;
16331#endif
ea1fb29a 16332
1da177e4
LT
16333 return 0;
16334}
16335
f32610ed
JS
16336/*
16337 * ALC861-VD support
16338 *
16339 * Based on ALC882
16340 *
16341 * In addition, an independent DAC
16342 */
16343#define ALC861VD_DIGOUT_NID 0x06
16344
4c6d72d1 16345static const hda_nid_t alc861vd_dac_nids[4] = {
f32610ed
JS
16346 /* front, surr, clfe, side surr */
16347 0x02, 0x03, 0x04, 0x05
16348};
16349
16350/* dac_nids for ALC660vd are in a different order - according to
16351 * Realtek's driver.
def319f9 16352 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16353 * of ALC660vd codecs, but for now there is only 3stack mixer
16354 * - and it is the same as in 861vd.
16355 * adc_nids in ALC660vd are (is) the same as in 861vd
16356 */
4c6d72d1 16357static const hda_nid_t alc660vd_dac_nids[3] = {
f32610ed
JS
16358 /* front, rear, clfe, rear_surr */
16359 0x02, 0x04, 0x03
16360};
16361
4c6d72d1 16362static const hda_nid_t alc861vd_adc_nids[1] = {
f32610ed
JS
16363 /* ADC0 */
16364 0x09,
16365};
16366
4c6d72d1 16367static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
e1406348 16368
f32610ed
JS
16369/* input MUX */
16370/* FIXME: should be a matrix-type input source selection */
a9111321 16371static const struct hda_input_mux alc861vd_capture_source = {
f32610ed
JS
16372 .num_items = 4,
16373 .items = {
16374 { "Mic", 0x0 },
16375 { "Front Mic", 0x1 },
16376 { "Line", 0x2 },
16377 { "CD", 0x4 },
16378 },
16379};
16380
a9111321 16381static const struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16382 .num_items = 2,
272a527c 16383 .items = {
8607f7c4 16384 { "Mic", 0x0 },
28c4edb7 16385 { "Internal Mic", 0x1 },
272a527c
KY
16386 },
16387};
16388
a9111321 16389static const struct hda_input_mux alc861vd_hp_capture_source = {
d1a991a6
KY
16390 .num_items = 2,
16391 .items = {
16392 { "Front Mic", 0x0 },
16393 { "ATAPI Mic", 0x1 },
16394 },
16395};
16396
f32610ed
JS
16397/*
16398 * 2ch mode
16399 */
a9111321 16400static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
f32610ed
JS
16401 { 2, NULL }
16402};
16403
16404/*
16405 * 6ch mode
16406 */
a9111321 16407static const struct hda_verb alc861vd_6stack_ch6_init[] = {
f32610ed
JS
16408 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16409 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16410 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16411 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16412 { } /* end */
16413};
16414
16415/*
16416 * 8ch mode
16417 */
a9111321 16418static const struct hda_verb alc861vd_6stack_ch8_init[] = {
f32610ed
JS
16419 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16420 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16421 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16422 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16423 { } /* end */
16424};
16425
a9111321 16426static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
f32610ed
JS
16427 { 6, alc861vd_6stack_ch6_init },
16428 { 8, alc861vd_6stack_ch8_init },
16429};
16430
a9111321 16431static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
f32610ed
JS
16432 {
16433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16434 .name = "Channel Mode",
16435 .info = alc_ch_mode_info,
16436 .get = alc_ch_mode_get,
16437 .put = alc_ch_mode_put,
16438 },
16439 { } /* end */
16440};
16441
f32610ed
JS
16442/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16443 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16444 */
a9111321 16445static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
f32610ed
JS
16446 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16447 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16448
16449 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16450 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16451
16452 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16453 HDA_OUTPUT),
16454 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16455 HDA_OUTPUT),
16456 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16457 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16458
16459 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16460 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16461
16462 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16463
5f99f86a 16464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16467
5f99f86a 16468 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16469 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16470 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16471
16472 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16473 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16474
16475 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16476 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16477
f32610ed
JS
16478 { } /* end */
16479};
16480
a9111321 16481static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
f32610ed
JS
16482 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16483 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16484
16485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16486
5f99f86a 16487 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16488 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16489 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16490
5f99f86a 16491 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16492 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16493 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16494
16495 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16496 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16497
16498 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16499 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16500
f32610ed
JS
16501 { } /* end */
16502};
16503
a9111321 16504static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
bdd148a3
KY
16505 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16506 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16507 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16508
16509 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16510
5f99f86a 16511 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16512 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16513 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16514
5f99f86a 16515 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16516 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16517 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16518
16519 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16520 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16521
16522 { } /* end */
16523};
16524
b419f346 16525/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16526 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c 16527 */
a9111321 16528static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16529 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16530 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16531 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16532 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16533 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16535 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16536 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16537 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16538 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16539 { } /* end */
16540};
16541
d1a991a6
KY
16542/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16543 * Front Mic=0x18, ATAPI Mic = 0x19,
16544 */
a9111321 16545static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
d1a991a6
KY
16546 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16547 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16548 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16549 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16550 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16551 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16552 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16553 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16554
d1a991a6
KY
16555 { } /* end */
16556};
16557
f32610ed
JS
16558/*
16559 * generic initialization of ADC, input mixers and output mixers
16560 */
a9111321 16561static const struct hda_verb alc861vd_volume_init_verbs[] = {
f32610ed
JS
16562 /*
16563 * Unmute ADC0 and set the default input to mic-in
16564 */
16565 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16566 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16567
16568 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16569 * the analog-loopback mixer widget
16570 */
16571 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16572 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16573 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16576 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16577
16578 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16579 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16580 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16581 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16582 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16583
16584 /*
16585 * Set up output mixers (0x02 - 0x05)
16586 */
16587 /* set vol=0 to output mixers */
16588 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16589 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16590 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16591 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16592
16593 /* set up input amps for analog loopback */
16594 /* Amp Indices: DAC = 0, mixer = 1 */
16595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16596 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16597 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16598 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16599 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16600 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16601 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16602 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16603
16604 { }
16605};
16606
16607/*
16608 * 3-stack pin configuration:
16609 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16610 */
a9111321 16611static const struct hda_verb alc861vd_3stack_init_verbs[] = {
f32610ed
JS
16612 /*
16613 * Set pin mode and muting
16614 */
16615 /* set front pin widgets 0x14 for output */
16616 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16617 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16618 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16619
16620 /* Mic (rear) pin: input vref at 80% */
16621 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16622 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16623 /* Front Mic pin: input vref at 80% */
16624 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16625 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16626 /* Line In pin: input */
16627 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16628 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16629 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16631 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16632 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16633 /* CD pin widget for input */
16634 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16635
16636 { }
16637};
16638
16639/*
16640 * 6-stack pin configuration:
16641 */
a9111321 16642static const struct hda_verb alc861vd_6stack_init_verbs[] = {
f32610ed
JS
16643 /*
16644 * Set pin mode and muting
16645 */
16646 /* set front pin widgets 0x14 for output */
16647 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16648 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16649 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16650
16651 /* Rear Pin: output 1 (0x0d) */
16652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16655 /* CLFE Pin: output 2 (0x0e) */
16656 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16657 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16658 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16659 /* Side Pin: output 3 (0x0f) */
16660 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16661 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16662 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16663
16664 /* Mic (rear) pin: input vref at 80% */
16665 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16666 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16667 /* Front Mic pin: input vref at 80% */
16668 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16669 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16670 /* Line In pin: input */
16671 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16672 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16673 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16674 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16675 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16676 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16677 /* CD pin widget for input */
16678 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16679
16680 { }
16681};
16682
a9111321 16683static const struct hda_verb alc861vd_eapd_verbs[] = {
bdd148a3
KY
16684 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16685 { }
16686};
16687
a9111321 16688static const struct hda_verb alc660vd_eapd_verbs[] = {
f9423e7a
KY
16689 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16690 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16691 { }
16692};
16693
a9111321 16694static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
bdd148a3
KY
16695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16698 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16699 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16700 {}
16701};
16702
4f5d1706 16703static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16704{
a9fd4f3f 16705 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16706 spec->autocfg.hp_pins[0] = 0x1b;
16707 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16708 spec->automute = 1;
16709 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
16710}
16711
16712static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16713{
d922b51d 16714 alc_hp_automute(codec);
eeb43387 16715 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16716}
16717
16718static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16719 unsigned int res)
16720{
16721 switch (res >> 26) {
bdd148a3 16722 case ALC880_MIC_EVENT:
eeb43387 16723 alc88x_simple_mic_automute(codec);
bdd148a3 16724 break;
a9fd4f3f 16725 default:
d922b51d 16726 alc_sku_unsol_event(codec, res);
a9fd4f3f 16727 break;
bdd148a3
KY
16728 }
16729}
16730
a9111321 16731static const struct hda_verb alc861vd_dallas_verbs[] = {
272a527c
KY
16732 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16733 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16734 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16735 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16736
16737 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16739 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16740 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16741 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16742 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16743 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16744 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16745
272a527c
KY
16746 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16747 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16750 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16751 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16752 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16753 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16754
16755 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16756 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16757 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16759 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16760 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16761 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16762 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16763
16764 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16765 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16766 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16767 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16768
16769 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16770 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16771 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16772
16773 { } /* end */
16774};
16775
16776/* toggle speaker-output according to the hp-jack state */
4f5d1706 16777static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16778{
a9fd4f3f 16779 struct alc_spec *spec = codec->spec;
272a527c 16780
a9fd4f3f
TI
16781 spec->autocfg.hp_pins[0] = 0x15;
16782 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16783 spec->automute = 1;
16784 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
16785}
16786
cb53c626
TI
16787#ifdef CONFIG_SND_HDA_POWER_SAVE
16788#define alc861vd_loopbacks alc880_loopbacks
16789#endif
16790
def319f9 16791/* pcm configuration: identical with ALC880 */
f32610ed
JS
16792#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16793#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16794#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16795#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16796
16797/*
16798 * configuration and preset
16799 */
ea734963 16800static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16801 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16802 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16803 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16804 [ALC861VD_3ST] = "3stack",
16805 [ALC861VD_3ST_DIG] = "3stack-digout",
16806 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16807 [ALC861VD_LENOVO] = "lenovo",
272a527c 16808 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16809 [ALC861VD_HP] = "hp",
f32610ed
JS
16810 [ALC861VD_AUTO] = "auto",
16811};
16812
a9111321 16813static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16814 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16815 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16816 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16817 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16818 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16819 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16820 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16821 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16822 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16823 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16824 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16825 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16826 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16827 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16828 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16829 {}
16830};
16831
a9111321 16832static const struct alc_config_preset alc861vd_presets[] = {
f32610ed
JS
16833 [ALC660VD_3ST] = {
16834 .mixers = { alc861vd_3st_mixer },
16835 .init_verbs = { alc861vd_volume_init_verbs,
16836 alc861vd_3stack_init_verbs },
16837 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16838 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16839 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16840 .channel_mode = alc861vd_3stack_2ch_modes,
16841 .input_mux = &alc861vd_capture_source,
16842 },
6963f84c
MC
16843 [ALC660VD_3ST_DIG] = {
16844 .mixers = { alc861vd_3st_mixer },
16845 .init_verbs = { alc861vd_volume_init_verbs,
16846 alc861vd_3stack_init_verbs },
16847 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16848 .dac_nids = alc660vd_dac_nids,
16849 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16850 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16851 .channel_mode = alc861vd_3stack_2ch_modes,
16852 .input_mux = &alc861vd_capture_source,
16853 },
f32610ed
JS
16854 [ALC861VD_3ST] = {
16855 .mixers = { alc861vd_3st_mixer },
16856 .init_verbs = { alc861vd_volume_init_verbs,
16857 alc861vd_3stack_init_verbs },
16858 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16859 .dac_nids = alc861vd_dac_nids,
16860 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16861 .channel_mode = alc861vd_3stack_2ch_modes,
16862 .input_mux = &alc861vd_capture_source,
16863 },
16864 [ALC861VD_3ST_DIG] = {
16865 .mixers = { alc861vd_3st_mixer },
16866 .init_verbs = { alc861vd_volume_init_verbs,
16867 alc861vd_3stack_init_verbs },
16868 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16869 .dac_nids = alc861vd_dac_nids,
16870 .dig_out_nid = ALC861VD_DIGOUT_NID,
16871 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16872 .channel_mode = alc861vd_3stack_2ch_modes,
16873 .input_mux = &alc861vd_capture_source,
16874 },
16875 [ALC861VD_6ST_DIG] = {
16876 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16877 .init_verbs = { alc861vd_volume_init_verbs,
16878 alc861vd_6stack_init_verbs },
16879 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16880 .dac_nids = alc861vd_dac_nids,
16881 .dig_out_nid = ALC861VD_DIGOUT_NID,
16882 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16883 .channel_mode = alc861vd_6stack_modes,
16884 .input_mux = &alc861vd_capture_source,
16885 },
bdd148a3
KY
16886 [ALC861VD_LENOVO] = {
16887 .mixers = { alc861vd_lenovo_mixer },
16888 .init_verbs = { alc861vd_volume_init_verbs,
16889 alc861vd_3stack_init_verbs,
16890 alc861vd_eapd_verbs,
16891 alc861vd_lenovo_unsol_verbs },
16892 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16893 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16894 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16895 .channel_mode = alc861vd_3stack_2ch_modes,
16896 .input_mux = &alc861vd_capture_source,
16897 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16898 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16899 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16900 },
272a527c
KY
16901 [ALC861VD_DALLAS] = {
16902 .mixers = { alc861vd_dallas_mixer },
16903 .init_verbs = { alc861vd_dallas_verbs },
16904 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16905 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16906 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16907 .channel_mode = alc861vd_3stack_2ch_modes,
16908 .input_mux = &alc861vd_dallas_capture_source,
d922b51d 16909 .unsol_event = alc_sku_unsol_event,
4f5d1706 16910 .setup = alc861vd_dallas_setup,
d922b51d 16911 .init_hook = alc_hp_automute,
d1a991a6
KY
16912 },
16913 [ALC861VD_HP] = {
16914 .mixers = { alc861vd_hp_mixer },
16915 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16916 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16917 .dac_nids = alc861vd_dac_nids,
d1a991a6 16918 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16919 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16920 .channel_mode = alc861vd_3stack_2ch_modes,
16921 .input_mux = &alc861vd_hp_capture_source,
d922b51d 16922 .unsol_event = alc_sku_unsol_event,
4f5d1706 16923 .setup = alc861vd_dallas_setup,
d922b51d 16924 .init_hook = alc_hp_automute,
ea1fb29a 16925 },
13c94744
TI
16926 [ALC660VD_ASUS_V1S] = {
16927 .mixers = { alc861vd_lenovo_mixer },
16928 .init_verbs = { alc861vd_volume_init_verbs,
16929 alc861vd_3stack_init_verbs,
16930 alc861vd_eapd_verbs,
16931 alc861vd_lenovo_unsol_verbs },
16932 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16933 .dac_nids = alc660vd_dac_nids,
16934 .dig_out_nid = ALC861VD_DIGOUT_NID,
16935 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16936 .channel_mode = alc861vd_3stack_2ch_modes,
16937 .input_mux = &alc861vd_capture_source,
16938 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16939 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16940 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16941 },
f32610ed
JS
16942};
16943
16944/*
16945 * BIOS auto configuration
16946 */
05f5f477
TI
16947static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16948 const struct auto_pin_cfg *cfg)
16949{
7167594a 16950 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
16951}
16952
16953
1f0f4b80
TI
16954#define alc861vd_auto_init_multi_out alc882_auto_init_multi_out
16955#define alc861vd_auto_init_hp_out alc882_auto_init_hp_out
16956#define alc861vd_auto_init_analog_input alc882_auto_init_analog_input
f511b01c
TI
16957#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16958
f32610ed
JS
16959#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16960#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16961
16962/* add playback controls from the parsed DAC table */
569ed348 16963/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
16964 * different NIDs for mute/unmute switch and volume control */
16965static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16966 const struct auto_pin_cfg *cfg)
16967{
f32610ed 16968 hda_nid_t nid_v, nid_s;
ce764ab2 16969 int i, err, noutputs;
f32610ed 16970
ce764ab2
TI
16971 noutputs = cfg->line_outs;
16972 if (spec->multi_ios > 0)
16973 noutputs += spec->multi_ios;
16974
16975 for (i = 0; i < noutputs; i++) {
6843ca16
TI
16976 const char *name;
16977 int index;
f12ab1e0 16978 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16979 continue;
16980 nid_v = alc861vd_idx_to_mixer_vol(
16981 alc880_dac_to_idx(
16982 spec->multiout.dac_nids[i]));
16983 nid_s = alc861vd_idx_to_mixer_switch(
16984 alc880_dac_to_idx(
16985 spec->multiout.dac_nids[i]));
16986
6843ca16
TI
16987 name = alc_get_line_out_pfx(spec, i, true, &index);
16988 if (!name) {
f32610ed 16989 /* Center/LFE */
0afe5f89
TI
16990 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16991 "Center",
f12ab1e0
TI
16992 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16993 HDA_OUTPUT));
16994 if (err < 0)
f32610ed 16995 return err;
0afe5f89
TI
16996 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16997 "LFE",
f12ab1e0
TI
16998 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16999 HDA_OUTPUT));
17000 if (err < 0)
f32610ed 17001 return err;
0afe5f89
TI
17002 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17003 "Center",
f12ab1e0
TI
17004 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17005 HDA_INPUT));
17006 if (err < 0)
f32610ed 17007 return err;
0afe5f89
TI
17008 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17009 "LFE",
f12ab1e0
TI
17010 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17011 HDA_INPUT));
17012 if (err < 0)
f32610ed
JS
17013 return err;
17014 } else {
bcb2f0f5 17015 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 17016 name, index,
f12ab1e0
TI
17017 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17018 HDA_OUTPUT));
17019 if (err < 0)
f32610ed 17020 return err;
bcb2f0f5 17021 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 17022 name, index,
bdd148a3 17023 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17024 HDA_INPUT));
17025 if (err < 0)
f32610ed
JS
17026 return err;
17027 }
17028 }
17029 return 0;
17030}
17031
17032/* add playback controls for speaker and HP outputs */
17033/* Based on ALC880 version. But ALC861VD has separate,
17034 * different NIDs for mute/unmute switch and volume control */
17035static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17036 hda_nid_t pin, const char *pfx)
17037{
17038 hda_nid_t nid_v, nid_s;
17039 int err;
f32610ed 17040
f12ab1e0 17041 if (!pin)
f32610ed
JS
17042 return 0;
17043
17044 if (alc880_is_fixed_pin(pin)) {
17045 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17046 /* specify the DAC as the extra output */
f12ab1e0 17047 if (!spec->multiout.hp_nid)
f32610ed
JS
17048 spec->multiout.hp_nid = nid_v;
17049 else
17050 spec->multiout.extra_out_nid[0] = nid_v;
17051 /* control HP volume/switch on the output mixer amp */
17052 nid_v = alc861vd_idx_to_mixer_vol(
17053 alc880_fixed_pin_idx(pin));
17054 nid_s = alc861vd_idx_to_mixer_switch(
17055 alc880_fixed_pin_idx(pin));
17056
0afe5f89 17057 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17058 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17059 if (err < 0)
f32610ed 17060 return err;
0afe5f89 17061 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17062 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17063 if (err < 0)
f32610ed
JS
17064 return err;
17065 } else if (alc880_is_multi_pin(pin)) {
17066 /* set manual connection */
17067 /* we have only a switch on HP-out PIN */
0afe5f89 17068 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17069 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17070 if (err < 0)
f32610ed
JS
17071 return err;
17072 }
17073 return 0;
17074}
17075
17076/* parse the BIOS configuration and set up the alc_spec
17077 * return 1 if successful, 0 if the proper config is not found,
17078 * or a negative error code
17079 * Based on ALC880 version - had to change it to override
17080 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17081static int alc861vd_parse_auto_config(struct hda_codec *codec)
17082{
17083 struct alc_spec *spec = codec->spec;
17084 int err;
4c6d72d1 17085 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
f32610ed 17086
f12ab1e0
TI
17087 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17088 alc861vd_ignore);
17089 if (err < 0)
f32610ed 17090 return err;
f12ab1e0 17091 if (!spec->autocfg.line_outs)
f32610ed
JS
17092 return 0; /* can't find valid BIOS pin config */
17093
cb053a82 17094 err = alc880_auto_fill_dac_nids(codec);
ce764ab2
TI
17095 if (err < 0)
17096 return err;
cb053a82 17097 err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
f12ab1e0
TI
17098 if (err < 0)
17099 return err;
17100 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17101 if (err < 0)
17102 return err;
17103 err = alc861vd_auto_create_extra_out(spec,
17104 spec->autocfg.speaker_pins[0],
17105 "Speaker");
17106 if (err < 0)
17107 return err;
17108 err = alc861vd_auto_create_extra_out(spec,
17109 spec->autocfg.hp_pins[0],
17110 "Headphone");
17111 if (err < 0)
17112 return err;
05f5f477 17113 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17114 if (err < 0)
f32610ed
JS
17115 return err;
17116
17117 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17118
757899ac 17119 alc_auto_parse_digital(codec);
f32610ed 17120
603c4019 17121 if (spec->kctls.list)
d88897ea 17122 add_mixer(spec, spec->kctls.list);
f32610ed 17123
f32610ed 17124 spec->num_mux_defs = 1;
61b9b9b1 17125 spec->input_mux = &spec->private_imux[0];
f32610ed 17126
776e184e
TI
17127 err = alc_auto_add_mic_boost(codec);
17128 if (err < 0)
17129 return err;
17130
6227cdce 17131 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17132
f32610ed
JS
17133 return 1;
17134}
17135
17136/* additional initialization for auto-configuration model */
17137static void alc861vd_auto_init(struct hda_codec *codec)
17138{
f6c7e546 17139 struct alc_spec *spec = codec->spec;
f32610ed
JS
17140 alc861vd_auto_init_multi_out(codec);
17141 alc861vd_auto_init_hp_out(codec);
17142 alc861vd_auto_init_analog_input(codec);
f511b01c 17143 alc861vd_auto_init_input_src(codec);
757899ac 17144 alc_auto_init_digital(codec);
f6c7e546 17145 if (spec->unsol_event)
7fb0d78f 17146 alc_inithook(codec);
f32610ed
JS
17147}
17148
f8f25ba3
TI
17149enum {
17150 ALC660VD_FIX_ASUS_GPIO1
17151};
17152
17153/* reset GPIO1 */
f8f25ba3
TI
17154static const struct alc_fixup alc861vd_fixups[] = {
17155 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17156 .type = ALC_FIXUP_VERBS,
17157 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17158 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17159 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17160 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17161 { }
17162 }
f8f25ba3
TI
17163 },
17164};
17165
a9111321 17166static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
f8f25ba3
TI
17167 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17168 {}
17169};
17170
f32610ed
JS
17171static int patch_alc861vd(struct hda_codec *codec)
17172{
17173 struct alc_spec *spec;
17174 int err, board_config;
17175
17176 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17177 if (spec == NULL)
17178 return -ENOMEM;
17179
17180 codec->spec = spec;
17181
1f0f4b80
TI
17182 spec->mixer_nid = 0x0b;
17183
f32610ed
JS
17184 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17185 alc861vd_models,
17186 alc861vd_cfg_tbl);
17187
17188 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17189 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17190 codec->chip_name);
f32610ed
JS
17191 board_config = ALC861VD_AUTO;
17192 }
17193
b5bfbc67
TI
17194 if (board_config == ALC861VD_AUTO) {
17195 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17196 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17197 }
f8f25ba3 17198
f32610ed
JS
17199 if (board_config == ALC861VD_AUTO) {
17200 /* automatic parse from the BIOS config */
17201 err = alc861vd_parse_auto_config(codec);
17202 if (err < 0) {
17203 alc_free(codec);
17204 return err;
f12ab1e0 17205 } else if (!err) {
f32610ed
JS
17206 printk(KERN_INFO
17207 "hda_codec: Cannot set up configuration "
17208 "from BIOS. Using base mode...\n");
17209 board_config = ALC861VD_3ST;
17210 }
17211 }
17212
680cd536
KK
17213 err = snd_hda_attach_beep_device(codec, 0x23);
17214 if (err < 0) {
17215 alc_free(codec);
17216 return err;
17217 }
17218
f32610ed 17219 if (board_config != ALC861VD_AUTO)
e9c364c0 17220 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17221
2f893286 17222 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17223 /* always turn on EAPD */
d88897ea 17224 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17225 }
17226
f32610ed
JS
17227 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17228 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17229
f32610ed
JS
17230 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17231 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17232
dd704698
TI
17233 if (!spec->adc_nids) {
17234 spec->adc_nids = alc861vd_adc_nids;
17235 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17236 }
17237 if (!spec->capsrc_nids)
17238 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17239
b59bdf3b 17240 set_capture_mixer(codec);
45bdd1c1 17241 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17242
2134ea4f
TI
17243 spec->vmaster_nid = 0x02;
17244
b5bfbc67 17245 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17246
f32610ed
JS
17247 codec->patch_ops = alc_patch_ops;
17248
17249 if (board_config == ALC861VD_AUTO)
17250 spec->init_hook = alc861vd_auto_init;
1c716153 17251 spec->shutup = alc_eapd_shutup;
cb53c626
TI
17252#ifdef CONFIG_SND_HDA_POWER_SAVE
17253 if (!spec->loopback.amplist)
17254 spec->loopback.amplist = alc861vd_loopbacks;
17255#endif
f32610ed
JS
17256
17257 return 0;
17258}
17259
bc9f98a9
KY
17260/*
17261 * ALC662 support
17262 *
17263 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17264 * configuration. Each pin widget can choose any input DACs and a mixer.
17265 * Each ADC is connected from a mixer of all inputs. This makes possible
17266 * 6-channel independent captures.
17267 *
17268 * In addition, an independent DAC for the multi-playback (not used in this
17269 * driver yet).
17270 */
17271#define ALC662_DIGOUT_NID 0x06
17272#define ALC662_DIGIN_NID 0x0a
17273
4c6d72d1 17274static const hda_nid_t alc662_dac_nids[3] = {
4bf4a6c5 17275 /* front, rear, clfe */
bc9f98a9
KY
17276 0x02, 0x03, 0x04
17277};
17278
4c6d72d1 17279static const hda_nid_t alc272_dac_nids[2] = {
622e84cd
KY
17280 0x02, 0x03
17281};
17282
4c6d72d1 17283static const hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17284 /* ADC1-2 */
b59bdf3b 17285 0x09, 0x08
bc9f98a9 17286};
e1406348 17287
4c6d72d1 17288static const hda_nid_t alc272_adc_nids[1] = {
622e84cd
KY
17289 /* ADC1-2 */
17290 0x08,
17291};
17292
4c6d72d1
TI
17293static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17294static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
622e84cd 17295
e1406348 17296
bc9f98a9
KY
17297/* input MUX */
17298/* FIXME: should be a matrix-type input source selection */
a9111321 17299static const struct hda_input_mux alc662_capture_source = {
bc9f98a9
KY
17300 .num_items = 4,
17301 .items = {
17302 { "Mic", 0x0 },
17303 { "Front Mic", 0x1 },
17304 { "Line", 0x2 },
17305 { "CD", 0x4 },
17306 },
17307};
17308
a9111321 17309static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
bc9f98a9
KY
17310 .num_items = 2,
17311 .items = {
17312 { "Mic", 0x1 },
17313 { "Line", 0x2 },
17314 },
17315};
291702f0 17316
a9111321 17317static const struct hda_input_mux alc663_capture_source = {
6dda9f4a
KY
17318 .num_items = 3,
17319 .items = {
17320 { "Mic", 0x0 },
17321 { "Front Mic", 0x1 },
17322 { "Line", 0x2 },
17323 },
17324};
17325
4f5d1706 17326#if 0 /* set to 1 for testing other input sources below */
a9111321 17327static const struct hda_input_mux alc272_nc10_capture_source = {
9541ba1d
CP
17328 .num_items = 16,
17329 .items = {
17330 { "Autoselect Mic", 0x0 },
17331 { "Internal Mic", 0x1 },
17332 { "In-0x02", 0x2 },
17333 { "In-0x03", 0x3 },
17334 { "In-0x04", 0x4 },
17335 { "In-0x05", 0x5 },
17336 { "In-0x06", 0x6 },
17337 { "In-0x07", 0x7 },
17338 { "In-0x08", 0x8 },
17339 { "In-0x09", 0x9 },
17340 { "In-0x0a", 0x0a },
17341 { "In-0x0b", 0x0b },
17342 { "In-0x0c", 0x0c },
17343 { "In-0x0d", 0x0d },
17344 { "In-0x0e", 0x0e },
17345 { "In-0x0f", 0x0f },
17346 },
17347};
17348#endif
17349
bc9f98a9
KY
17350/*
17351 * 2ch mode
17352 */
a9111321 17353static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
bc9f98a9
KY
17354 { 2, NULL }
17355};
17356
17357/*
17358 * 2ch mode
17359 */
a9111321 17360static const struct hda_verb alc662_3ST_ch2_init[] = {
bc9f98a9
KY
17361 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17362 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17363 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17364 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17365 { } /* end */
17366};
17367
17368/*
17369 * 6ch mode
17370 */
a9111321 17371static const struct hda_verb alc662_3ST_ch6_init[] = {
bc9f98a9
KY
17372 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17373 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17374 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17375 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17376 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17377 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17378 { } /* end */
17379};
17380
a9111321 17381static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
bc9f98a9
KY
17382 { 2, alc662_3ST_ch2_init },
17383 { 6, alc662_3ST_ch6_init },
17384};
17385
17386/*
17387 * 2ch mode
17388 */
a9111321 17389static const struct hda_verb alc662_sixstack_ch6_init[] = {
bc9f98a9
KY
17390 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17391 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17392 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17393 { } /* end */
17394};
17395
17396/*
17397 * 6ch mode
17398 */
a9111321 17399static const struct hda_verb alc662_sixstack_ch8_init[] = {
bc9f98a9
KY
17400 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17401 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17402 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17403 { } /* end */
17404};
17405
a9111321 17406static const struct hda_channel_mode alc662_5stack_modes[2] = {
bc9f98a9
KY
17407 { 2, alc662_sixstack_ch6_init },
17408 { 6, alc662_sixstack_ch8_init },
17409};
17410
17411/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17412 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17413 */
17414
a9111321 17415static const struct snd_kcontrol_new alc662_base_mixer[] = {
bc9f98a9
KY
17416 /* output mixer control */
17417 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17418 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17419 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17420 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17421 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17422 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17423 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17424 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17425 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17426
17427 /*Input mixer control */
17428 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17429 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17430 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17431 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17432 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17433 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17434 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17436 { } /* end */
17437};
17438
a9111321 17439static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
bc9f98a9 17440 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17441 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17442 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17443 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17444 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17445 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17446 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17447 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17448 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17451 { } /* end */
17452};
17453
a9111321 17454static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
bc9f98a9 17455 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17456 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17457 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17458 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17459 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17460 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17461 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17462 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17463 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17464 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17465 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17466 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17467 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17470 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17471 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17472 { } /* end */
17473};
17474
a9111321 17475static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
bc9f98a9
KY
17476 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17477 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17478 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17479 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17485 { } /* end */
17486};
17487
a9111321 17488static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17489 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17490 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17491
5f99f86a 17492 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17494 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17495
5f99f86a 17496 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17497 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17498 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17499 { } /* end */
17500};
17501
a9111321 17502static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17503 ALC262_HIPPO_MASTER_SWITCH,
17504 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17505 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17506 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17507 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17508 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17509 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17510 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17511 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17512 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17513 { } /* end */
17514};
17515
a9111321 17516static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
f1d4e28b
KY
17517 .ops = &snd_hda_bind_vol,
17518 .values = {
17519 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17520 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17521 0
17522 },
17523};
17524
a9111321 17525static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
f1d4e28b
KY
17526 .ops = &snd_hda_bind_sw,
17527 .values = {
17528 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17529 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17530 0
17531 },
17532};
17533
a9111321 17534static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17535 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17536 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17538 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17539 { } /* end */
17540};
17541
a9111321 17542static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
f1d4e28b
KY
17543 .ops = &snd_hda_bind_sw,
17544 .values = {
17545 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17546 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17547 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17548 0
17549 },
17550};
17551
a9111321 17552static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
f1d4e28b
KY
17553 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17554 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17555 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17556 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17557 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17558 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17559
17560 { } /* end */
17561};
17562
a9111321 17563static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
f1d4e28b
KY
17564 .ops = &snd_hda_bind_sw,
17565 .values = {
17566 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17567 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17568 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17569 0
17570 },
17571};
17572
a9111321 17573static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
f1d4e28b
KY
17574 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17575 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17576 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17578 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17579 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17580 { } /* end */
17581};
17582
a9111321 17583static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17584 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17585 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17589 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17590 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17591 { } /* end */
17592};
17593
a9111321 17594static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
f1d4e28b
KY
17595 .ops = &snd_hda_bind_vol,
17596 .values = {
17597 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17598 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17599 0
17600 },
17601};
17602
a9111321 17603static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
f1d4e28b
KY
17604 .ops = &snd_hda_bind_sw,
17605 .values = {
17606 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17607 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17608 0
17609 },
17610};
17611
a9111321 17612static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
f1d4e28b
KY
17613 HDA_BIND_VOL("Master Playback Volume",
17614 &alc663_asus_two_bind_master_vol),
17615 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17616 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17617 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17618 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17619 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17620 { } /* end */
17621};
17622
a9111321 17623static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
f1d4e28b
KY
17624 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17625 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17626 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17627 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17630 { } /* end */
17631};
17632
a9111321 17633static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
6dda9f4a
KY
17634 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17635 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17636 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17637 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17638 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17639
17640 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17641 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17642 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17643 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17644 { } /* end */
17645};
17646
a9111321 17647static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
6dda9f4a
KY
17648 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17649 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17651
17652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17654 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17655 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17656 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17657 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17658 { } /* end */
17659};
17660
a9111321 17661static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
ebb83eeb
KY
17662 .ops = &snd_hda_bind_sw,
17663 .values = {
17664 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17665 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17666 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17667 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17668 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17669 0
17670 },
17671};
17672
a9111321 17673static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
ebb83eeb
KY
17674 .ops = &snd_hda_bind_sw,
17675 .values = {
17676 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17677 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17678 0
17679 },
17680};
17681
a9111321 17682static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
ebb83eeb
KY
17683 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17684 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17685 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17686 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17687 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17688 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17689 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17691 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17692 { } /* end */
17693};
17694
a9111321 17695static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
ebb83eeb
KY
17696 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17697 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17698 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17699 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17700 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17702 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17703 { } /* end */
17704};
17705
17706
a9111321 17707static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
bc9f98a9
KY
17708 {
17709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17710 .name = "Channel Mode",
17711 .info = alc_ch_mode_info,
17712 .get = alc_ch_mode_get,
17713 .put = alc_ch_mode_put,
17714 },
17715 { } /* end */
17716};
17717
a9111321 17718static const struct hda_verb alc662_init_verbs[] = {
bc9f98a9
KY
17719 /* ADC: mute amp left and right */
17720 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17721 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17722
b60dd394
KY
17723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17725 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17726 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17727 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17728 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17729
17730 /* Front Pin: output 0 (0x0c) */
17731 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17732 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17733
17734 /* Rear Pin: output 1 (0x0d) */
17735 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17737
17738 /* CLFE Pin: output 2 (0x0e) */
17739 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17740 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17741
17742 /* Mic (rear) pin: input vref at 80% */
17743 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17744 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17745 /* Front Mic pin: input vref at 80% */
17746 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17747 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17748 /* Line In pin: input */
17749 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17750 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17751 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17752 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17753 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17754 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17755 /* CD pin widget for input */
17756 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17757
17758 /* FIXME: use matrix-type input source selection */
17759 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17760 /* Input mixer */
17761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17762 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a 17763
a7f2371f
TI
17764 { }
17765};
17766
a9111321 17767static const struct hda_verb alc662_eapd_init_verbs[] = {
6dda9f4a
KY
17768 /* always trun on EAPD */
17769 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17770 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
bc9f98a9
KY
17771 { }
17772};
17773
a9111321 17774static const struct hda_verb alc662_sue_init_verbs[] = {
bc9f98a9
KY
17775 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17776 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17777 {}
17778};
17779
a9111321 17780static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
291702f0
KY
17781 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17782 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17783 {}
bc9f98a9
KY
17784};
17785
8c427226 17786/* Set Unsolicited Event*/
a9111321 17787static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
8c427226
KY
17788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17789 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17790 {}
17791};
17792
a9111321 17793static const struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17794 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17795 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17796 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17797 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17798 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17799 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17800 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17801 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17802 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17803 {}
17804};
17805
a9111321 17806static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
f1d4e28b
KY
17807 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17808 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17809 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17810 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17811 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17812 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17813 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17814 {}
17815};
17816
a9111321 17817static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
f1d4e28b
KY
17818 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17819 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17820 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17821 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17822 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17823 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17824 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17825 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17826 {}
17827};
6dda9f4a 17828
a9111321 17829static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
f1d4e28b
KY
17830 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17831 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17832 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17833 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17834 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17835 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17836 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17837 {}
17838};
6dda9f4a 17839
a9111321 17840static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
f1d4e28b
KY
17841 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17842 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17843 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17844 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17845 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17847 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17848 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17849 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17850 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17851 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17852 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17853 {}
17854};
17855
a9111321 17856static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
f1d4e28b
KY
17857 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17858 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17859 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17860 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17863 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17864 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17865 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17866 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17867 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17868 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17869 {}
17870};
17871
a9111321 17872static const struct hda_verb alc663_g71v_init_verbs[] = {
6dda9f4a
KY
17873 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17874 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17875 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17876
17877 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17878 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17879 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17880
17881 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17882 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17883 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17884 {}
17885};
17886
a9111321 17887static const struct hda_verb alc663_g50v_init_verbs[] = {
6dda9f4a
KY
17888 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17889 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17890 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17891
17892 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17893 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17894 {}
17895};
17896
a9111321 17897static const struct hda_verb alc662_ecs_init_verbs[] = {
f1d4e28b
KY
17898 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17899 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17900 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17901 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17902 {}
17903};
17904
a9111321 17905static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
622e84cd
KY
17906 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17907 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17908 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17909 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17910 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17911 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17912 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17915 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17916 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17917 {}
17918};
17919
a9111321 17920static const struct hda_verb alc272_dell_init_verbs[] = {
622e84cd
KY
17921 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17922 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17923 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17924 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17925 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17926 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17927 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17929 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17930 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17931 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17932 {}
17933};
17934
a9111321 17935static const struct hda_verb alc663_mode7_init_verbs[] = {
ebb83eeb
KY
17936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17937 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17938 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17939 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17940 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17941 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17942 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17943 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17944 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17945 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17946 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17947 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17948 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17949 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17950 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17951 {}
17952};
17953
a9111321 17954static const struct hda_verb alc663_mode8_init_verbs[] = {
ebb83eeb
KY
17955 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17956 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17958 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17959 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17960 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17961 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17962 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
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(9)},
17968 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17969 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17970 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17971 {}
17972};
17973
a9111321 17974static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
f1d4e28b
KY
17975 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17976 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17977 { } /* end */
17978};
17979
a9111321 17980static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
622e84cd
KY
17981 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17982 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17983 { } /* end */
17984};
17985
e6a5e1b7 17986static void alc662_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 17987{
e6a5e1b7 17988 struct alc_spec *spec = codec->spec;
bc9f98a9 17989
e6a5e1b7
TI
17990 spec->autocfg.hp_pins[0] = 0x1b;
17991 spec->autocfg.line_out_pins[0] = 0x14;
17992 spec->autocfg.speaker_pins[0] = 0x15;
17993 spec->automute = 1;
17994 spec->detect_line = 1;
17995 spec->automute_lines = 1;
17996 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
17997}
17998
4f5d1706
TI
17999static void alc662_eeepc_setup(struct hda_codec *codec)
18000{
18001 struct alc_spec *spec = codec->spec;
18002
18003 alc262_hippo1_setup(codec);
18004 spec->ext_mic.pin = 0x18;
18005 spec->ext_mic.mux_idx = 0;
18006 spec->int_mic.pin = 0x19;
18007 spec->int_mic.mux_idx = 1;
18008 spec->auto_mic = 1;
18009}
18010
4f5d1706 18011static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18012{
42171c17
TI
18013 struct alc_spec *spec = codec->spec;
18014
18015 spec->autocfg.hp_pins[0] = 0x14;
18016 spec->autocfg.speaker_pins[0] = 0x1b;
e9427969
TI
18017 spec->automute = 1;
18018 spec->automute_mode = ALC_AUTOMUTE_AMP;
8c427226
KY
18019}
18020
4f5d1706
TI
18021static void alc663_m51va_setup(struct hda_codec *codec)
18022{
18023 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18024 spec->autocfg.hp_pins[0] = 0x21;
18025 spec->autocfg.speaker_pins[0] = 0x14;
18026 spec->automute_mixer_nid[0] = 0x0c;
18027 spec->automute = 1;
18028 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
18029 spec->ext_mic.pin = 0x18;
18030 spec->ext_mic.mux_idx = 0;
18031 spec->int_mic.pin = 0x12;
ebb83eeb 18032 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18033 spec->auto_mic = 1;
18034}
18035
f1d4e28b 18036/* ***************** Mode1 ******************************/
ebb83eeb
KY
18037static void alc663_mode1_setup(struct hda_codec *codec)
18038{
18039 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18040 spec->autocfg.hp_pins[0] = 0x21;
18041 spec->autocfg.speaker_pins[0] = 0x14;
18042 spec->automute_mixer_nid[0] = 0x0c;
18043 spec->automute = 1;
18044 spec->automute_mode = ALC_AUTOMUTE_MIXER;
ebb83eeb
KY
18045 spec->ext_mic.pin = 0x18;
18046 spec->ext_mic.mux_idx = 0;
18047 spec->int_mic.pin = 0x19;
18048 spec->int_mic.mux_idx = 1;
18049 spec->auto_mic = 1;
18050}
18051
f1d4e28b 18052/* ***************** Mode2 ******************************/
3b8510ce 18053static void alc662_mode2_setup(struct hda_codec *codec)
f1d4e28b 18054{
3b8510ce
TI
18055 struct alc_spec *spec = codec->spec;
18056 spec->autocfg.hp_pins[0] = 0x1b;
18057 spec->autocfg.speaker_pins[0] = 0x14;
18058 spec->automute = 1;
18059 spec->automute_mode = ALC_AUTOMUTE_PIN;
18060 spec->ext_mic.pin = 0x18;
18061 spec->ext_mic.mux_idx = 0;
18062 spec->int_mic.pin = 0x19;
18063 spec->int_mic.mux_idx = 1;
18064 spec->auto_mic = 1;
f1d4e28b
KY
18065}
18066
f1d4e28b 18067/* ***************** Mode3 ******************************/
3b8510ce 18068static void alc663_mode3_setup(struct hda_codec *codec)
f1d4e28b 18069{
3b8510ce
TI
18070 struct alc_spec *spec = codec->spec;
18071 spec->autocfg.hp_pins[0] = 0x21;
18072 spec->autocfg.hp_pins[0] = 0x15;
18073 spec->autocfg.speaker_pins[0] = 0x14;
18074 spec->automute = 1;
18075 spec->automute_mode = ALC_AUTOMUTE_PIN;
18076 spec->ext_mic.pin = 0x18;
18077 spec->ext_mic.mux_idx = 0;
18078 spec->int_mic.pin = 0x19;
18079 spec->int_mic.mux_idx = 1;
18080 spec->auto_mic = 1;
f1d4e28b
KY
18081}
18082
f1d4e28b 18083/* ***************** Mode4 ******************************/
3b8510ce 18084static void alc663_mode4_setup(struct hda_codec *codec)
f1d4e28b 18085{
3b8510ce
TI
18086 struct alc_spec *spec = codec->spec;
18087 spec->autocfg.hp_pins[0] = 0x21;
18088 spec->autocfg.speaker_pins[0] = 0x14;
18089 spec->autocfg.speaker_pins[1] = 0x16;
18090 spec->automute_mixer_nid[0] = 0x0c;
18091 spec->automute_mixer_nid[1] = 0x0e;
18092 spec->automute = 1;
18093 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18094 spec->ext_mic.pin = 0x18;
18095 spec->ext_mic.mux_idx = 0;
18096 spec->int_mic.pin = 0x19;
18097 spec->int_mic.mux_idx = 1;
18098 spec->auto_mic = 1;
f1d4e28b
KY
18099}
18100
f1d4e28b 18101/* ***************** Mode5 ******************************/
3b8510ce 18102static void alc663_mode5_setup(struct hda_codec *codec)
f1d4e28b 18103{
3b8510ce
TI
18104 struct alc_spec *spec = codec->spec;
18105 spec->autocfg.hp_pins[0] = 0x15;
18106 spec->autocfg.speaker_pins[0] = 0x14;
18107 spec->autocfg.speaker_pins[1] = 0x16;
18108 spec->automute_mixer_nid[0] = 0x0c;
18109 spec->automute_mixer_nid[1] = 0x0e;
18110 spec->automute = 1;
18111 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18112 spec->ext_mic.pin = 0x18;
18113 spec->ext_mic.mux_idx = 0;
18114 spec->int_mic.pin = 0x19;
18115 spec->int_mic.mux_idx = 1;
18116 spec->auto_mic = 1;
f1d4e28b
KY
18117}
18118
f1d4e28b 18119/* ***************** Mode6 ******************************/
3b8510ce 18120static void alc663_mode6_setup(struct hda_codec *codec)
f1d4e28b 18121{
3b8510ce
TI
18122 struct alc_spec *spec = codec->spec;
18123 spec->autocfg.hp_pins[0] = 0x1b;
18124 spec->autocfg.hp_pins[0] = 0x15;
18125 spec->autocfg.speaker_pins[0] = 0x14;
18126 spec->automute_mixer_nid[0] = 0x0c;
18127 spec->automute = 1;
18128 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18129 spec->ext_mic.pin = 0x18;
18130 spec->ext_mic.mux_idx = 0;
18131 spec->int_mic.pin = 0x19;
18132 spec->int_mic.mux_idx = 1;
18133 spec->auto_mic = 1;
f1d4e28b
KY
18134}
18135
ebb83eeb 18136/* ***************** Mode7 ******************************/
3b8510ce 18137static void alc663_mode7_setup(struct hda_codec *codec)
ebb83eeb 18138{
3b8510ce
TI
18139 struct alc_spec *spec = codec->spec;
18140 spec->autocfg.hp_pins[0] = 0x1b;
18141 spec->autocfg.hp_pins[0] = 0x21;
18142 spec->autocfg.speaker_pins[0] = 0x14;
18143 spec->autocfg.speaker_pins[0] = 0x17;
18144 spec->automute = 1;
18145 spec->automute_mode = ALC_AUTOMUTE_PIN;
18146 spec->ext_mic.pin = 0x18;
18147 spec->ext_mic.mux_idx = 0;
18148 spec->int_mic.pin = 0x19;
18149 spec->int_mic.mux_idx = 1;
18150 spec->auto_mic = 1;
ebb83eeb
KY
18151}
18152
18153/* ***************** Mode8 ******************************/
3b8510ce 18154static void alc663_mode8_setup(struct hda_codec *codec)
ebb83eeb 18155{
3b8510ce
TI
18156 struct alc_spec *spec = codec->spec;
18157 spec->autocfg.hp_pins[0] = 0x21;
18158 spec->autocfg.hp_pins[1] = 0x15;
18159 spec->autocfg.speaker_pins[0] = 0x14;
18160 spec->autocfg.speaker_pins[0] = 0x17;
18161 spec->automute = 1;
18162 spec->automute_mode = ALC_AUTOMUTE_PIN;
18163 spec->ext_mic.pin = 0x18;
18164 spec->ext_mic.mux_idx = 0;
18165 spec->int_mic.pin = 0x12;
18166 spec->int_mic.mux_idx = 9;
18167 spec->auto_mic = 1;
ebb83eeb
KY
18168}
18169
e6a5e1b7 18170static void alc663_g71v_setup(struct hda_codec *codec)
6dda9f4a 18171{
e6a5e1b7
TI
18172 struct alc_spec *spec = codec->spec;
18173 spec->autocfg.hp_pins[0] = 0x21;
18174 spec->autocfg.line_out_pins[0] = 0x15;
18175 spec->autocfg.speaker_pins[0] = 0x14;
18176 spec->automute = 1;
18177 spec->automute_mode = ALC_AUTOMUTE_AMP;
18178 spec->detect_line = 1;
18179 spec->automute_lines = 1;
18180 spec->ext_mic.pin = 0x18;
18181 spec->ext_mic.mux_idx = 0;
18182 spec->int_mic.pin = 0x12;
18183 spec->int_mic.mux_idx = 9;
18184 spec->auto_mic = 1;
6dda9f4a
KY
18185}
18186
4f5d1706
TI
18187#define alc663_g50v_setup alc663_m51va_setup
18188
a9111321 18189static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
f1d4e28b 18190 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18191 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18192
5f99f86a 18193 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18194 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18195 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18196
5f99f86a 18197 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18198 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18199 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18200 { } /* end */
18201};
18202
a9111321 18203static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
9541ba1d
CP
18204 /* Master Playback automatically created from Speaker and Headphone */
18205 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18206 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18207 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18208 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18209
8607f7c4
DH
18210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18212 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18213
28c4edb7
DH
18214 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18215 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18216 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18217 { } /* end */
18218};
18219
cb53c626
TI
18220#ifdef CONFIG_SND_HDA_POWER_SAVE
18221#define alc662_loopbacks alc880_loopbacks
18222#endif
18223
bc9f98a9 18224
def319f9 18225/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18226#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18227#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18228#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18229#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18230
18231/*
18232 * configuration and preset
18233 */
ea734963 18234static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18235 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18236 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18237 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 18238 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 18239 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18240 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18241 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18242 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18243 [ALC663_ASUS_M51VA] = "m51va",
18244 [ALC663_ASUS_G71V] = "g71v",
18245 [ALC663_ASUS_H13] = "h13",
18246 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18247 [ALC663_ASUS_MODE1] = "asus-mode1",
18248 [ALC662_ASUS_MODE2] = "asus-mode2",
18249 [ALC663_ASUS_MODE3] = "asus-mode3",
18250 [ALC663_ASUS_MODE4] = "asus-mode4",
18251 [ALC663_ASUS_MODE5] = "asus-mode5",
18252 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18253 [ALC663_ASUS_MODE7] = "asus-mode7",
18254 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18255 [ALC272_DELL] = "dell",
18256 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18257 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18258 [ALC662_AUTO] = "auto",
18259};
18260
a9111321 18261static const struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18262 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18263 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18264 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18265 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18266 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18267 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18268 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18269 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18270 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18271 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18272 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18273 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18274 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18275 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18276 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18277 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18278 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18279 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18280 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18281 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18282 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18283 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18284 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18285 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18286 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18287 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18288 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18289 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18290 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18291 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18292 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18293 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18294 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18295 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18296 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18297 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18298 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18299 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18300 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18301 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18302 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18303 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18304 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18305 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18306 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18307 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18308 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18309 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18310 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18311 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18312 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18313 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18314 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18315 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18316 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18317 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18318 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18319 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18320 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18321 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18322 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18323 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18324 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18325 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18326 ALC662_3ST_6ch_DIG),
4dee8baa 18327 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18328 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
ebb47241
TI
18329 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18330 ALC662_3ST_6ch_DIG),
6227cdce 18331 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18332 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18333 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18334 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18335 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18336 ALC662_3ST_6ch_DIG),
dea0a509
TI
18337 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18338 ALC663_ASUS_H13),
965b76d2 18339 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18340 {}
18341};
18342
a9111321 18343static const struct alc_config_preset alc662_presets[] = {
bc9f98a9 18344 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18345 .mixers = { alc662_3ST_2ch_mixer },
a7f2371f 18346 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18347 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18348 .dac_nids = alc662_dac_nids,
18349 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18350 .dig_in_nid = ALC662_DIGIN_NID,
18351 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18352 .channel_mode = alc662_3ST_2ch_modes,
18353 .input_mux = &alc662_capture_source,
18354 },
18355 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18356 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18357 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18358 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18359 .dac_nids = alc662_dac_nids,
18360 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18361 .dig_in_nid = ALC662_DIGIN_NID,
18362 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18363 .channel_mode = alc662_3ST_6ch_modes,
18364 .need_dac_fix = 1,
18365 .input_mux = &alc662_capture_source,
f12ab1e0 18366 },
bc9f98a9 18367 [ALC662_3ST_6ch] = {
f9e336f6 18368 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18369 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18370 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18371 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18372 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18373 .channel_mode = alc662_3ST_6ch_modes,
18374 .need_dac_fix = 1,
18375 .input_mux = &alc662_capture_source,
f12ab1e0 18376 },
bc9f98a9 18377 [ALC662_5ST_DIG] = {
f9e336f6 18378 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
a7f2371f 18379 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18380 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18381 .dac_nids = alc662_dac_nids,
18382 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18383 .dig_in_nid = ALC662_DIGIN_NID,
18384 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18385 .channel_mode = alc662_5stack_modes,
18386 .input_mux = &alc662_capture_source,
18387 },
18388 [ALC662_LENOVO_101E] = {
f9e336f6 18389 .mixers = { alc662_lenovo_101e_mixer },
a7f2371f
TI
18390 .init_verbs = { alc662_init_verbs,
18391 alc662_eapd_init_verbs,
18392 alc662_sue_init_verbs },
bc9f98a9
KY
18393 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18394 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18395 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18396 .channel_mode = alc662_3ST_2ch_modes,
18397 .input_mux = &alc662_lenovo_101e_capture_source,
e6a5e1b7
TI
18398 .unsol_event = alc_sku_unsol_event,
18399 .setup = alc662_lenovo_101e_setup,
18400 .init_hook = alc_inithook,
bc9f98a9 18401 },
291702f0 18402 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18403 .mixers = { alc662_eeepc_p701_mixer },
291702f0 18404 .init_verbs = { alc662_init_verbs,
a7f2371f 18405 alc662_eapd_init_verbs,
291702f0
KY
18406 alc662_eeepc_sue_init_verbs },
18407 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18408 .dac_nids = alc662_dac_nids,
291702f0
KY
18409 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18410 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18411 .unsol_event = alc_sku_unsol_event,
4f5d1706 18412 .setup = alc662_eeepc_setup,
e9427969 18413 .init_hook = alc_inithook,
291702f0 18414 },
8c427226 18415 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18416 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18417 alc662_chmode_mixer },
18418 .init_verbs = { alc662_init_verbs,
a7f2371f 18419 alc662_eapd_init_verbs,
8c427226
KY
18420 alc662_eeepc_ep20_sue_init_verbs },
18421 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18422 .dac_nids = alc662_dac_nids,
8c427226
KY
18423 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18424 .channel_mode = alc662_3ST_6ch_modes,
18425 .input_mux = &alc662_lenovo_101e_capture_source,
e9427969 18426 .unsol_event = alc_sku_unsol_event,
4f5d1706 18427 .setup = alc662_eeepc_ep20_setup,
e9427969 18428 .init_hook = alc_inithook,
8c427226 18429 },
f1d4e28b 18430 [ALC662_ECS] = {
f9e336f6 18431 .mixers = { alc662_ecs_mixer },
f1d4e28b 18432 .init_verbs = { alc662_init_verbs,
a7f2371f 18433 alc662_eapd_init_verbs,
f1d4e28b
KY
18434 alc662_ecs_init_verbs },
18435 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18436 .dac_nids = alc662_dac_nids,
18437 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18438 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18439 .unsol_event = alc_sku_unsol_event,
4f5d1706 18440 .setup = alc662_eeepc_setup,
e9427969 18441 .init_hook = alc_inithook,
f1d4e28b 18442 },
6dda9f4a 18443 [ALC663_ASUS_M51VA] = {
f9e336f6 18444 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18445 .init_verbs = { alc662_init_verbs,
18446 alc662_eapd_init_verbs,
18447 alc663_m51va_init_verbs },
6dda9f4a
KY
18448 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18449 .dac_nids = alc662_dac_nids,
18450 .dig_out_nid = ALC662_DIGOUT_NID,
18451 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18452 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18453 .unsol_event = alc_sku_unsol_event,
4f5d1706 18454 .setup = alc663_m51va_setup,
3b8510ce 18455 .init_hook = alc_inithook,
6dda9f4a
KY
18456 },
18457 [ALC663_ASUS_G71V] = {
f9e336f6 18458 .mixers = { alc663_g71v_mixer },
a7f2371f
TI
18459 .init_verbs = { alc662_init_verbs,
18460 alc662_eapd_init_verbs,
18461 alc663_g71v_init_verbs },
6dda9f4a
KY
18462 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18463 .dac_nids = alc662_dac_nids,
18464 .dig_out_nid = ALC662_DIGOUT_NID,
18465 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18466 .channel_mode = alc662_3ST_2ch_modes,
e6a5e1b7 18467 .unsol_event = alc_sku_unsol_event,
4f5d1706 18468 .setup = alc663_g71v_setup,
e6a5e1b7 18469 .init_hook = alc_inithook,
6dda9f4a
KY
18470 },
18471 [ALC663_ASUS_H13] = {
f9e336f6 18472 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18473 .init_verbs = { alc662_init_verbs,
18474 alc662_eapd_init_verbs,
18475 alc663_m51va_init_verbs },
6dda9f4a
KY
18476 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18477 .dac_nids = alc662_dac_nids,
18478 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18479 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce
TI
18480 .setup = alc663_m51va_setup,
18481 .unsol_event = alc_sku_unsol_event,
18482 .init_hook = alc_inithook,
6dda9f4a
KY
18483 },
18484 [ALC663_ASUS_G50V] = {
f9e336f6 18485 .mixers = { alc663_g50v_mixer },
a7f2371f
TI
18486 .init_verbs = { alc662_init_verbs,
18487 alc662_eapd_init_verbs,
18488 alc663_g50v_init_verbs },
6dda9f4a
KY
18489 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18490 .dac_nids = alc662_dac_nids,
18491 .dig_out_nid = ALC662_DIGOUT_NID,
18492 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18493 .channel_mode = alc662_3ST_6ch_modes,
18494 .input_mux = &alc663_capture_source,
3b8510ce 18495 .unsol_event = alc_sku_unsol_event,
4f5d1706 18496 .setup = alc663_g50v_setup,
3b8510ce 18497 .init_hook = alc_inithook,
6dda9f4a 18498 },
f1d4e28b 18499 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18500 .mixers = { alc663_m51va_mixer },
18501 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18502 .init_verbs = { alc662_init_verbs,
a7f2371f 18503 alc662_eapd_init_verbs,
f1d4e28b
KY
18504 alc663_21jd_amic_init_verbs },
18505 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18506 .hp_nid = 0x03,
18507 .dac_nids = alc662_dac_nids,
18508 .dig_out_nid = ALC662_DIGOUT_NID,
18509 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18510 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18511 .unsol_event = alc_sku_unsol_event,
4f5d1706 18512 .setup = alc663_mode1_setup,
3b8510ce 18513 .init_hook = alc_inithook,
f1d4e28b
KY
18514 },
18515 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18516 .mixers = { alc662_1bjd_mixer },
18517 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18518 .init_verbs = { alc662_init_verbs,
a7f2371f 18519 alc662_eapd_init_verbs,
f1d4e28b
KY
18520 alc662_1bjd_amic_init_verbs },
18521 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18522 .dac_nids = alc662_dac_nids,
18523 .dig_out_nid = ALC662_DIGOUT_NID,
18524 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18525 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18526 .unsol_event = alc_sku_unsol_event,
4f5d1706 18527 .setup = alc662_mode2_setup,
3b8510ce 18528 .init_hook = alc_inithook,
f1d4e28b
KY
18529 },
18530 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18531 .mixers = { alc663_two_hp_m1_mixer },
18532 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18533 .init_verbs = { alc662_init_verbs,
a7f2371f 18534 alc662_eapd_init_verbs,
f1d4e28b
KY
18535 alc663_two_hp_amic_m1_init_verbs },
18536 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18537 .hp_nid = 0x03,
18538 .dac_nids = alc662_dac_nids,
18539 .dig_out_nid = ALC662_DIGOUT_NID,
18540 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18541 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18542 .unsol_event = alc_sku_unsol_event,
4f5d1706 18543 .setup = alc663_mode3_setup,
3b8510ce 18544 .init_hook = alc_inithook,
f1d4e28b
KY
18545 },
18546 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18547 .mixers = { alc663_asus_21jd_clfe_mixer },
18548 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18549 .init_verbs = { alc662_init_verbs,
a7f2371f 18550 alc662_eapd_init_verbs,
f1d4e28b
KY
18551 alc663_21jd_amic_init_verbs},
18552 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18553 .hp_nid = 0x03,
18554 .dac_nids = alc662_dac_nids,
18555 .dig_out_nid = ALC662_DIGOUT_NID,
18556 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18557 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18558 .unsol_event = alc_sku_unsol_event,
4f5d1706 18559 .setup = alc663_mode4_setup,
3b8510ce 18560 .init_hook = alc_inithook,
f1d4e28b
KY
18561 },
18562 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18563 .mixers = { alc663_asus_15jd_clfe_mixer },
18564 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18565 .init_verbs = { alc662_init_verbs,
a7f2371f 18566 alc662_eapd_init_verbs,
f1d4e28b
KY
18567 alc663_15jd_amic_init_verbs },
18568 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18569 .hp_nid = 0x03,
18570 .dac_nids = alc662_dac_nids,
18571 .dig_out_nid = ALC662_DIGOUT_NID,
18572 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18573 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18574 .unsol_event = alc_sku_unsol_event,
4f5d1706 18575 .setup = alc663_mode5_setup,
3b8510ce 18576 .init_hook = alc_inithook,
f1d4e28b
KY
18577 },
18578 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18579 .mixers = { alc663_two_hp_m2_mixer },
18580 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18581 .init_verbs = { alc662_init_verbs,
a7f2371f 18582 alc662_eapd_init_verbs,
f1d4e28b
KY
18583 alc663_two_hp_amic_m2_init_verbs },
18584 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18585 .hp_nid = 0x03,
18586 .dac_nids = alc662_dac_nids,
18587 .dig_out_nid = ALC662_DIGOUT_NID,
18588 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18589 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18590 .unsol_event = alc_sku_unsol_event,
4f5d1706 18591 .setup = alc663_mode6_setup,
3b8510ce 18592 .init_hook = alc_inithook,
f1d4e28b 18593 },
ebb83eeb
KY
18594 [ALC663_ASUS_MODE7] = {
18595 .mixers = { alc663_mode7_mixer },
18596 .cap_mixer = alc662_auto_capture_mixer,
18597 .init_verbs = { alc662_init_verbs,
a7f2371f 18598 alc662_eapd_init_verbs,
ebb83eeb
KY
18599 alc663_mode7_init_verbs },
18600 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18601 .hp_nid = 0x03,
18602 .dac_nids = alc662_dac_nids,
18603 .dig_out_nid = ALC662_DIGOUT_NID,
18604 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18605 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18606 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18607 .setup = alc663_mode7_setup,
3b8510ce 18608 .init_hook = alc_inithook,
ebb83eeb
KY
18609 },
18610 [ALC663_ASUS_MODE8] = {
18611 .mixers = { alc663_mode8_mixer },
18612 .cap_mixer = alc662_auto_capture_mixer,
18613 .init_verbs = { alc662_init_verbs,
a7f2371f 18614 alc662_eapd_init_verbs,
ebb83eeb
KY
18615 alc663_mode8_init_verbs },
18616 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18617 .hp_nid = 0x03,
18618 .dac_nids = alc662_dac_nids,
18619 .dig_out_nid = ALC662_DIGOUT_NID,
18620 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18621 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18622 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18623 .setup = alc663_mode8_setup,
3b8510ce 18624 .init_hook = alc_inithook,
ebb83eeb 18625 },
622e84cd
KY
18626 [ALC272_DELL] = {
18627 .mixers = { alc663_m51va_mixer },
18628 .cap_mixer = alc272_auto_capture_mixer,
a7f2371f
TI
18629 .init_verbs = { alc662_init_verbs,
18630 alc662_eapd_init_verbs,
18631 alc272_dell_init_verbs },
622e84cd 18632 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18633 .dac_nids = alc272_dac_nids,
622e84cd
KY
18634 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18635 .adc_nids = alc272_adc_nids,
18636 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18637 .capsrc_nids = alc272_capsrc_nids,
18638 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18639 .unsol_event = alc_sku_unsol_event,
4f5d1706 18640 .setup = alc663_m51va_setup,
3b8510ce 18641 .init_hook = alc_inithook,
622e84cd
KY
18642 },
18643 [ALC272_DELL_ZM1] = {
18644 .mixers = { alc663_m51va_mixer },
18645 .cap_mixer = alc662_auto_capture_mixer,
a7f2371f
TI
18646 .init_verbs = { alc662_init_verbs,
18647 alc662_eapd_init_verbs,
18648 alc272_dell_zm1_init_verbs },
622e84cd 18649 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18650 .dac_nids = alc272_dac_nids,
622e84cd
KY
18651 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18652 .adc_nids = alc662_adc_nids,
b59bdf3b 18653 .num_adc_nids = 1,
622e84cd
KY
18654 .capsrc_nids = alc662_capsrc_nids,
18655 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18656 .unsol_event = alc_sku_unsol_event,
4f5d1706 18657 .setup = alc663_m51va_setup,
3b8510ce 18658 .init_hook = alc_inithook,
622e84cd 18659 },
9541ba1d
CP
18660 [ALC272_SAMSUNG_NC10] = {
18661 .mixers = { alc272_nc10_mixer },
18662 .init_verbs = { alc662_init_verbs,
a7f2371f 18663 alc662_eapd_init_verbs,
9541ba1d
CP
18664 alc663_21jd_amic_init_verbs },
18665 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18666 .dac_nids = alc272_dac_nids,
18667 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18668 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18669 /*.input_mux = &alc272_nc10_capture_source,*/
3b8510ce 18670 .unsol_event = alc_sku_unsol_event,
4f5d1706 18671 .setup = alc663_mode4_setup,
3b8510ce 18672 .init_hook = alc_inithook,
9541ba1d 18673 },
bc9f98a9
KY
18674};
18675
18676
18677/*
18678 * BIOS auto configuration
18679 */
18680
7085ec12 18681/* convert from MIX nid to DAC */
604401a9 18682static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
1304ac89 18683{
604401a9 18684 hda_nid_t list[5];
1304ac89
TI
18685 int i, num;
18686
18687 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18688 for (i = 0; i < num; i++) {
18689 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18690 return list[i];
18691 }
18692 return 0;
7085ec12
TI
18693}
18694
604401a9
TI
18695/* go down to the selector widget before the mixer */
18696static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18697{
18698 hda_nid_t srcs[5];
18699 int num = snd_hda_get_connections(codec, pin, srcs,
18700 ARRAY_SIZE(srcs));
18701 if (num != 1 ||
18702 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18703 return pin;
18704 return srcs[0];
18705}
18706
7085ec12 18707/* get MIX nid connected to the given pin targeted to DAC */
604401a9 18708static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
7085ec12
TI
18709 hda_nid_t dac)
18710{
cc1c452e 18711 hda_nid_t mix[5];
7085ec12
TI
18712 int i, num;
18713
604401a9 18714 pin = alc_go_down_to_selector(codec, pin);
7085ec12
TI
18715 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18716 for (i = 0; i < num; i++) {
604401a9 18717 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
18718 return mix[i];
18719 }
18720 return 0;
18721}
18722
ce764ab2
TI
18723/* select the connection from pin to DAC if needed */
18724static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18725 hda_nid_t dac)
18726{
18727 hda_nid_t mix[5];
18728 int i, num;
18729
18730 pin = alc_go_down_to_selector(codec, pin);
18731 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18732 if (num < 2)
18733 return 0;
18734 for (i = 0; i < num; i++) {
18735 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18736 snd_hda_codec_update_cache(codec, pin, 0,
18737 AC_VERB_SET_CONNECT_SEL, i);
18738 return 0;
18739 }
18740 }
18741 return 0;
18742}
18743
7085ec12 18744/* look for an empty DAC slot */
604401a9 18745static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
7085ec12
TI
18746{
18747 struct alc_spec *spec = codec->spec;
18748 hda_nid_t srcs[5];
3af9ee6b 18749 int i, num;
7085ec12 18750
604401a9 18751 pin = alc_go_down_to_selector(codec, pin);
7085ec12 18752 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
7085ec12 18753 for (i = 0; i < num; i++) {
604401a9 18754 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
7085ec12
TI
18755 if (!nid)
18756 continue;
3af9ee6b
TI
18757 if (found_in_nid_list(nid, spec->multiout.dac_nids,
18758 spec->multiout.num_dacs))
18759 continue;
18760 if (spec->multiout.hp_nid == nid)
18761 continue;
18762 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
18763 ARRAY_SIZE(spec->multiout.extra_out_nid)))
18764 continue;
18765 return nid;
7085ec12
TI
18766 }
18767 return 0;
18768}
18769
3af9ee6b
TI
18770static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
18771{
18772 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
18773 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
18774 return alc_auto_look_for_dac(codec, pin);
18775 return 0;
18776}
18777
7085ec12 18778/* fill in the dac_nids table from the parsed pin configuration */
cb053a82 18779static int alc662_auto_fill_dac_nids(struct hda_codec *codec)
7085ec12
TI
18780{
18781 struct alc_spec *spec = codec->spec;
cb053a82 18782 const struct auto_pin_cfg *cfg = &spec->autocfg;
3af9ee6b 18783 bool redone;
7085ec12 18784 int i;
7085ec12 18785
3af9ee6b 18786 again:
3fccdfd8 18787 spec->multiout.num_dacs = 0;
3af9ee6b
TI
18788 spec->multiout.hp_nid = 0;
18789 spec->multiout.extra_out_nid[0] = 0;
18790 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
18791 spec->multiout.dac_nids = spec->private_dac_nids;
18792
18793 /* fill hard-wired DACs first */
18794 if (!redone) {
18795 for (i = 0; i < cfg->line_outs; i++)
18796 spec->private_dac_nids[i] =
18797 get_dac_if_single(codec, cfg->line_out_pins[i]);
18798 if (cfg->hp_outs)
18799 spec->multiout.hp_nid =
18800 get_dac_if_single(codec, cfg->hp_pins[0]);
18801 if (cfg->speaker_outs)
18802 spec->multiout.extra_out_nid[0] =
18803 get_dac_if_single(codec, cfg->speaker_pins[0]);
18804 }
18805
7085ec12 18806 for (i = 0; i < cfg->line_outs; i++) {
3af9ee6b
TI
18807 hda_nid_t pin = cfg->line_out_pins[i];
18808 if (spec->private_dac_nids[i])
7085ec12 18809 continue;
3af9ee6b
TI
18810 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
18811 if (!spec->private_dac_nids[i] && !redone) {
18812 /* if we can't find primary DACs, re-probe without
18813 * checking the hard-wired DACs
18814 */
18815 redone = true;
18816 goto again;
18817 }
18818 }
18819
18820 for (i = 0; i < cfg->line_outs; i++) {
18821 if (spec->private_dac_nids[i])
18822 spec->multiout.num_dacs++;
18823 else
18824 memmove(spec->private_dac_nids + i,
18825 spec->private_dac_nids + i + 1,
18826 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
7085ec12 18827 }
3af9ee6b 18828
7085ec12
TI
18829 return 0;
18830}
18831
bcb2f0f5
TI
18832static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18833 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18834{
bcb2f0f5 18835 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
18836 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18837}
18838
bcb2f0f5
TI
18839static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18840 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18841{
bcb2f0f5 18842 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
18843 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18844}
18845
bcb2f0f5
TI
18846#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
18847 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
18848#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
18849 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
18850#define alc662_add_stereo_vol(spec, pfx, nid) \
18851 alc662_add_vol_ctl(spec, pfx, nid, 3)
18852#define alc662_add_stereo_sw(spec, pfx, nid) \
18853 alc662_add_sw_ctl(spec, pfx, nid, 3)
18854
bc9f98a9 18855/* add playback controls from the parsed DAC table */
7085ec12 18856static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18857 const struct auto_pin_cfg *cfg)
18858{
7085ec12 18859 struct alc_spec *spec = codec->spec;
ce764ab2
TI
18860 hda_nid_t nid, mix, pin;
18861 int i, err, noutputs;
bc9f98a9 18862
ce764ab2
TI
18863 noutputs = cfg->line_outs;
18864 if (spec->multi_ios > 0)
18865 noutputs += spec->multi_ios;
18866
18867 for (i = 0; i < noutputs; i++) {
6843ca16
TI
18868 const char *name;
18869 int index;
7085ec12
TI
18870 nid = spec->multiout.dac_nids[i];
18871 if (!nid)
18872 continue;
ce764ab2
TI
18873 if (i >= cfg->line_outs)
18874 pin = spec->multi_io[i - 1].pin;
18875 else
18876 pin = cfg->line_out_pins[i];
18877 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12 18878 if (!mix)
bc9f98a9 18879 continue;
6843ca16
TI
18880 name = alc_get_line_out_pfx(spec, i, true, &index);
18881 if (!name) {
bc9f98a9 18882 /* Center/LFE */
7085ec12 18883 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18884 if (err < 0)
18885 return err;
7085ec12 18886 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18887 if (err < 0)
18888 return err;
7085ec12 18889 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18890 if (err < 0)
18891 return err;
7085ec12 18892 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18893 if (err < 0)
18894 return err;
18895 } else {
5a882646 18896 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
bc9f98a9
KY
18897 if (err < 0)
18898 return err;
5a882646 18899 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
bc9f98a9
KY
18900 if (err < 0)
18901 return err;
18902 }
18903 }
18904 return 0;
18905}
18906
18907/* add playback controls for speaker and HP outputs */
7085ec12 18908static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3af9ee6b 18909 hda_nid_t dac, const char *pfx)
bc9f98a9 18910{
7085ec12 18911 struct alc_spec *spec = codec->spec;
3af9ee6b 18912 hda_nid_t mix;
bc9f98a9 18913 int err;
bc9f98a9
KY
18914
18915 if (!pin)
18916 return 0;
3af9ee6b 18917 if (!dac) {
7085ec12
TI
18918 /* the corresponding DAC is already occupied */
18919 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18920 return 0; /* no way */
18921 /* create a switch only */
0afe5f89 18922 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18923 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18924 }
18925
3af9ee6b 18926 mix = alc_auto_dac_to_mix(codec, pin, dac);
7085ec12
TI
18927 if (!mix)
18928 return 0;
3af9ee6b 18929 err = alc662_add_vol_ctl(spec, pfx, dac, 3);
7085ec12
TI
18930 if (err < 0)
18931 return err;
18932 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18933 if (err < 0)
18934 return err;
3af9ee6b 18935 return 0;
bc9f98a9
KY
18936}
18937
18938/* create playback/capture controls for input pins */
05f5f477 18939#define alc662_auto_create_input_ctls \
4b7348a1 18940 alc882_auto_create_input_ctls
bc9f98a9
KY
18941
18942static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18943 hda_nid_t nid, int pin_type,
7085ec12 18944 hda_nid_t dac)
bc9f98a9 18945{
7085ec12 18946 int i, num;
ce503f38 18947 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 18948
f6c7e546 18949 alc_set_pin_output(codec, nid, pin_type);
7085ec12 18950 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
7085ec12 18951 for (i = 0; i < num; i++) {
604401a9 18952 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
7085ec12 18953 continue;
0e53f344
TI
18954 /* need the manual connection? */
18955 if (num > 1)
18956 snd_hda_codec_write(codec, nid, 0,
18957 AC_VERB_SET_CONNECT_SEL, i);
18958 /* unmute mixer widget inputs */
18959 snd_hda_codec_write(codec, srcs[i], 0,
18960 AC_VERB_SET_AMP_GAIN_MUTE,
18961 AMP_IN_UNMUTE(0));
18962 snd_hda_codec_write(codec, srcs[i], 0,
18963 AC_VERB_SET_AMP_GAIN_MUTE,
18964 AMP_IN_UNMUTE(1));
7085ec12 18965 return;
bc9f98a9
KY
18966 }
18967}
18968
18969static void alc662_auto_init_multi_out(struct hda_codec *codec)
18970{
18971 struct alc_spec *spec = codec->spec;
7085ec12 18972 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18973 int i;
18974
18975 for (i = 0; i <= HDA_SIDE; i++) {
18976 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18977 if (nid)
baba8ee9 18978 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18979 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18980 }
18981}
18982
18983static void alc662_auto_init_hp_out(struct hda_codec *codec)
18984{
18985 struct alc_spec *spec = codec->spec;
18986 hda_nid_t pin;
18987
18988 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18989 if (pin)
18990 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18991 spec->multiout.hp_nid);
f6c7e546
TI
18992 pin = spec->autocfg.speaker_pins[0];
18993 if (pin)
7085ec12
TI
18994 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18995 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18996}
18997
1f0f4b80 18998#define alc662_auto_init_analog_input alc882_auto_init_analog_input
f511b01c
TI
18999#define alc662_auto_init_input_src alc882_auto_init_input_src
19000
ce764ab2
TI
19001/*
19002 * multi-io helper
19003 */
19004static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19005 unsigned int location)
19006{
19007 struct alc_spec *spec = codec->spec;
19008 struct auto_pin_cfg *cfg = &spec->autocfg;
19009 int type, i, num_pins = 0;
19010
19011 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19012 for (i = 0; i < cfg->num_inputs; i++) {
19013 hda_nid_t nid = cfg->inputs[i].pin;
19014 hda_nid_t dac;
19015 unsigned int defcfg, caps;
19016 if (cfg->inputs[i].type != type)
19017 continue;
19018 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19019 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19020 continue;
19021 if (location && get_defcfg_location(defcfg) != location)
19022 continue;
19023 caps = snd_hda_query_pin_caps(codec, nid);
19024 if (!(caps & AC_PINCAP_OUT))
19025 continue;
19026 dac = alc_auto_look_for_dac(codec, nid);
19027 if (!dac)
19028 continue;
19029 spec->multi_io[num_pins].pin = nid;
19030 spec->multi_io[num_pins].dac = dac;
19031 num_pins++;
dda14410 19032 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
ce764ab2
TI
19033 }
19034 }
19035 spec->multiout.num_dacs = 1;
19036 if (num_pins < 2)
19037 return 0;
19038 return num_pins;
19039}
19040
19041static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19042 struct snd_ctl_elem_info *uinfo)
19043{
19044 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19045 struct alc_spec *spec = codec->spec;
19046
19047 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19048 uinfo->count = 1;
19049 uinfo->value.enumerated.items = spec->multi_ios + 1;
19050 if (uinfo->value.enumerated.item > spec->multi_ios)
19051 uinfo->value.enumerated.item = spec->multi_ios;
19052 sprintf(uinfo->value.enumerated.name, "%dch",
19053 (uinfo->value.enumerated.item + 1) * 2);
19054 return 0;
19055}
19056
19057static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19058 struct snd_ctl_elem_value *ucontrol)
19059{
19060 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19061 struct alc_spec *spec = codec->spec;
19062 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19063 return 0;
19064}
19065
19066static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19067{
19068 struct alc_spec *spec = codec->spec;
19069 hda_nid_t nid = spec->multi_io[idx].pin;
19070
19071 if (!spec->multi_io[idx].ctl_in)
19072 spec->multi_io[idx].ctl_in =
19073 snd_hda_codec_read(codec, nid, 0,
19074 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19075 if (output) {
19076 snd_hda_codec_update_cache(codec, nid, 0,
19077 AC_VERB_SET_PIN_WIDGET_CONTROL,
19078 PIN_OUT);
19079 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19080 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19081 HDA_AMP_MUTE, 0);
19082 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19083 } else {
19084 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19085 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19086 HDA_AMP_MUTE, HDA_AMP_MUTE);
19087 snd_hda_codec_update_cache(codec, nid, 0,
19088 AC_VERB_SET_PIN_WIDGET_CONTROL,
19089 spec->multi_io[idx].ctl_in);
19090 }
19091 return 0;
19092}
19093
19094static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19095 struct snd_ctl_elem_value *ucontrol)
19096{
19097 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19098 struct alc_spec *spec = codec->spec;
19099 int i, ch;
19100
19101 ch = ucontrol->value.enumerated.item[0];
19102 if (ch < 0 || ch > spec->multi_ios)
19103 return -EINVAL;
19104 if (ch == (spec->ext_channel_count - 1) / 2)
19105 return 0;
19106 spec->ext_channel_count = (ch + 1) * 2;
19107 for (i = 0; i < spec->multi_ios; i++)
19108 alc_set_multi_io(codec, i, i < ch);
19109 spec->multiout.max_channels = spec->ext_channel_count;
19110 return 1;
19111}
19112
a9111321 19113static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
ce764ab2
TI
19114 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19115 .name = "Channel Mode",
19116 .info = alc_auto_ch_mode_info,
19117 .get = alc_auto_ch_mode_get,
19118 .put = alc_auto_ch_mode_put,
19119};
19120
cb053a82
TI
19121static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
19122 int (*fill_dac)(struct hda_codec *))
ce764ab2
TI
19123{
19124 struct alc_spec *spec = codec->spec;
19125 struct auto_pin_cfg *cfg = &spec->autocfg;
19126 unsigned int location, defcfg;
19127 int num_pins;
19128
3fccdfd8
TI
19129 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
19130 /* use HP as primary out */
19131 cfg->speaker_outs = cfg->line_outs;
19132 memcpy(cfg->speaker_pins, cfg->line_out_pins,
19133 sizeof(cfg->speaker_pins));
19134 cfg->line_outs = cfg->hp_outs;
19135 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
19136 cfg->hp_outs = 0;
19137 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
19138 cfg->line_out_type = AUTO_PIN_HP_OUT;
cb053a82
TI
19139 if (fill_dac)
19140 fill_dac(codec);
3fccdfd8 19141 }
ce764ab2 19142 if (cfg->line_outs != 1 ||
3fccdfd8 19143 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
ce764ab2
TI
19144 return 0;
19145
19146 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19147 location = get_defcfg_location(defcfg);
19148
19149 num_pins = alc_auto_fill_multi_ios(codec, location);
19150 if (num_pins > 0) {
19151 struct snd_kcontrol_new *knew;
19152
19153 knew = alc_kcontrol_new(spec);
19154 if (!knew)
19155 return -ENOMEM;
19156 *knew = alc_auto_channel_mode_enum;
19157 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19158 if (!knew->name)
19159 return -ENOMEM;
19160
19161 spec->multi_ios = num_pins;
19162 spec->ext_channel_count = 2;
19163 spec->multiout.num_dacs = num_pins + 1;
19164 }
19165 return 0;
19166}
19167
bc9f98a9
KY
19168static int alc662_parse_auto_config(struct hda_codec *codec)
19169{
19170 struct alc_spec *spec = codec->spec;
19171 int err;
4c6d72d1 19172 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
bc9f98a9
KY
19173
19174 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19175 alc662_ignore);
19176 if (err < 0)
19177 return err;
19178 if (!spec->autocfg.line_outs)
19179 return 0; /* can't find valid BIOS pin config */
19180
cb053a82 19181 err = alc662_auto_fill_dac_nids(codec);
ce764ab2
TI
19182 if (err < 0)
19183 return err;
cb053a82 19184 err = alc_auto_add_multi_channel_mode(codec, alc662_auto_fill_dac_nids);
f12ab1e0
TI
19185 if (err < 0)
19186 return err;
7085ec12 19187 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19188 if (err < 0)
19189 return err;
7085ec12 19190 err = alc662_auto_create_extra_out(codec,
f12ab1e0 19191 spec->autocfg.speaker_pins[0],
3af9ee6b 19192 spec->multiout.extra_out_nid[0],
f12ab1e0
TI
19193 "Speaker");
19194 if (err < 0)
19195 return err;
7085ec12 19196 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3af9ee6b 19197 spec->multiout.hp_nid,
f12ab1e0
TI
19198 "Headphone");
19199 if (err < 0)
19200 return err;
05f5f477 19201 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19202 if (err < 0)
bc9f98a9
KY
19203 return err;
19204
19205 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19206
757899ac 19207 alc_auto_parse_digital(codec);
bc9f98a9 19208
603c4019 19209 if (spec->kctls.list)
d88897ea 19210 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19211
19212 spec->num_mux_defs = 1;
61b9b9b1 19213 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19214
ee979a14
TI
19215 err = alc_auto_add_mic_boost(codec);
19216 if (err < 0)
19217 return err;
19218
6227cdce
KY
19219 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19220 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19221 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19222 else
19223 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19224
8c87286f 19225 return 1;
bc9f98a9
KY
19226}
19227
19228/* additional initialization for auto-configuration model */
19229static void alc662_auto_init(struct hda_codec *codec)
19230{
f6c7e546 19231 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19232 alc662_auto_init_multi_out(codec);
19233 alc662_auto_init_hp_out(codec);
19234 alc662_auto_init_analog_input(codec);
f511b01c 19235 alc662_auto_init_input_src(codec);
757899ac 19236 alc_auto_init_digital(codec);
f6c7e546 19237 if (spec->unsol_event)
7fb0d78f 19238 alc_inithook(codec);
bc9f98a9
KY
19239}
19240
6be7948f 19241static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19242 const struct alc_fixup *fix, int action)
6fc398cb 19243{
b5bfbc67 19244 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19245 return;
6be7948f
TB
19246 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19247 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19248 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19249 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19250 (0 << AC_AMPCAP_MUTE_SHIFT)))
19251 printk(KERN_WARNING
19252 "hda_codec: failed to override amp caps for NID 0x2\n");
19253}
19254
6cb3b707 19255enum {
2df03514 19256 ALC662_FIXUP_ASPIRE,
6cb3b707 19257 ALC662_FIXUP_IDEAPAD,
6be7948f 19258 ALC272_FIXUP_MARIO,
d2ebd479 19259 ALC662_FIXUP_CZC_P10T,
94024cd1 19260 ALC662_FIXUP_SKU_IGNORE,
6cb3b707
DH
19261};
19262
19263static const struct alc_fixup alc662_fixups[] = {
2df03514 19264 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19265 .type = ALC_FIXUP_PINS,
19266 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19267 { 0x15, 0x99130112 }, /* subwoofer */
19268 { }
19269 }
19270 },
6cb3b707 19271 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19272 .type = ALC_FIXUP_PINS,
19273 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19274 { 0x17, 0x99130112 }, /* subwoofer */
19275 { }
19276 }
19277 },
6be7948f 19278 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19279 .type = ALC_FIXUP_FUNC,
19280 .v.func = alc272_fixup_mario,
d2ebd479
AA
19281 },
19282 [ALC662_FIXUP_CZC_P10T] = {
19283 .type = ALC_FIXUP_VERBS,
19284 .v.verbs = (const struct hda_verb[]) {
19285 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19286 {}
19287 }
19288 },
94024cd1
DH
19289 [ALC662_FIXUP_SKU_IGNORE] = {
19290 .type = ALC_FIXUP_SKU,
19291 .v.sku = ALC_FIXUP_SKU_IGNORE,
c6b35874 19292 },
6cb3b707
DH
19293};
19294
a9111321 19295static const struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19296 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 19297 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
2df03514 19298 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19299 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19300 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19301 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19302 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19303 {}
19304};
19305
6be7948f
TB
19306static const struct alc_model_fixup alc662_fixup_models[] = {
19307 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19308 {}
19309};
6cb3b707
DH
19310
19311
bc9f98a9
KY
19312static int patch_alc662(struct hda_codec *codec)
19313{
19314 struct alc_spec *spec;
19315 int err, board_config;
693194f3 19316 int coef;
bc9f98a9
KY
19317
19318 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19319 if (!spec)
19320 return -ENOMEM;
19321
19322 codec->spec = spec;
19323
1f0f4b80
TI
19324 spec->mixer_nid = 0x0b;
19325
da00c244
KY
19326 alc_auto_parse_customize_define(codec);
19327
2c3bf9ab
TI
19328 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19329
693194f3
KY
19330 coef = alc_read_coef_idx(codec, 0);
19331 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19332 alc_codec_rename(codec, "ALC661");
693194f3
KY
19333 else if (coef & (1 << 14) &&
19334 codec->bus->pci->subsystem_vendor == 0x1025 &&
19335 spec->cdefine.platform_type == 1)
c027ddcd 19336 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19337 else if (coef == 0x4011)
19338 alc_codec_rename(codec, "ALC656");
274693f3 19339
bc9f98a9
KY
19340 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19341 alc662_models,
19342 alc662_cfg_tbl);
19343 if (board_config < 0) {
9a11f1aa
TI
19344 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19345 codec->chip_name);
bc9f98a9
KY
19346 board_config = ALC662_AUTO;
19347 }
19348
19349 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19350 alc_pick_fixup(codec, alc662_fixup_models,
19351 alc662_fixup_tbl, alc662_fixups);
19352 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19353 /* automatic parse from the BIOS config */
19354 err = alc662_parse_auto_config(codec);
19355 if (err < 0) {
19356 alc_free(codec);
19357 return err;
8c87286f 19358 } else if (!err) {
bc9f98a9
KY
19359 printk(KERN_INFO
19360 "hda_codec: Cannot set up configuration "
19361 "from BIOS. Using base mode...\n");
19362 board_config = ALC662_3ST_2ch_DIG;
19363 }
19364 }
19365
dc1eae25 19366 if (has_cdefine_beep(codec)) {
8af2591d
TI
19367 err = snd_hda_attach_beep_device(codec, 0x1);
19368 if (err < 0) {
19369 alc_free(codec);
19370 return err;
19371 }
680cd536
KK
19372 }
19373
bc9f98a9 19374 if (board_config != ALC662_AUTO)
e9c364c0 19375 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19376
bc9f98a9
KY
19377 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19378 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19379
bc9f98a9
KY
19380 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19381 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19382
dd704698
TI
19383 if (!spec->adc_nids) {
19384 spec->adc_nids = alc662_adc_nids;
19385 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19386 }
19387 if (!spec->capsrc_nids)
19388 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19389
f9e336f6 19390 if (!spec->cap_mixer)
b59bdf3b 19391 set_capture_mixer(codec);
cec27c89 19392
dc1eae25 19393 if (has_cdefine_beep(codec)) {
da00c244
KY
19394 switch (codec->vendor_id) {
19395 case 0x10ec0662:
19396 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19397 break;
19398 case 0x10ec0272:
19399 case 0x10ec0663:
19400 case 0x10ec0665:
19401 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19402 break;
19403 case 0x10ec0273:
19404 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19405 break;
19406 }
cec27c89 19407 }
2134ea4f
TI
19408 spec->vmaster_nid = 0x02;
19409
b5bfbc67
TI
19410 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19411
bc9f98a9 19412 codec->patch_ops = alc_patch_ops;
b5bfbc67 19413 if (board_config == ALC662_AUTO)
bc9f98a9 19414 spec->init_hook = alc662_auto_init;
1c716153 19415 spec->shutup = alc_eapd_shutup;
6cb3b707 19416
bf1b0225
KY
19417 alc_init_jacks(codec);
19418
cb53c626
TI
19419#ifdef CONFIG_SND_HDA_POWER_SAVE
19420 if (!spec->loopback.amplist)
19421 spec->loopback.amplist = alc662_loopbacks;
19422#endif
bc9f98a9
KY
19423
19424 return 0;
19425}
19426
274693f3
KY
19427static int patch_alc888(struct hda_codec *codec)
19428{
19429 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19430 kfree(codec->chip_name);
01e0f137
KY
19431 if (codec->vendor_id == 0x10ec0887)
19432 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19433 else
19434 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19435 if (!codec->chip_name) {
19436 alc_free(codec);
274693f3 19437 return -ENOMEM;
ac2c92e0
TI
19438 }
19439 return patch_alc662(codec);
274693f3 19440 }
ac2c92e0 19441 return patch_alc882(codec);
274693f3
KY
19442}
19443
b478b998
KY
19444static int patch_alc899(struct hda_codec *codec)
19445{
19446 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19447 kfree(codec->chip_name);
19448 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19449 }
19450 return patch_alc882(codec);
19451}
19452
d1eb57f4
KY
19453/*
19454 * ALC680 support
19455 */
c69aefab 19456#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19457#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19458#define alc680_modes alc260_modes
19459
4c6d72d1 19460static const hda_nid_t alc680_dac_nids[3] = {
d1eb57f4
KY
19461 /* Lout1, Lout2, hp */
19462 0x02, 0x03, 0x04
19463};
19464
4c6d72d1 19465static const hda_nid_t alc680_adc_nids[3] = {
d1eb57f4
KY
19466 /* ADC0-2 */
19467 /* DMIC, MIC, Line-in*/
19468 0x07, 0x08, 0x09
19469};
19470
c69aefab
KY
19471/*
19472 * Analog capture ADC cgange
19473 */
66ceeb6b
TI
19474static void alc680_rec_autoswitch(struct hda_codec *codec)
19475{
19476 struct alc_spec *spec = codec->spec;
19477 struct auto_pin_cfg *cfg = &spec->autocfg;
19478 int pin_found = 0;
19479 int type_found = AUTO_PIN_LAST;
19480 hda_nid_t nid;
19481 int i;
19482
19483 for (i = 0; i < cfg->num_inputs; i++) {
19484 nid = cfg->inputs[i].pin;
06dec228 19485 if (!is_jack_detectable(codec, nid))
66ceeb6b
TI
19486 continue;
19487 if (snd_hda_jack_detect(codec, nid)) {
19488 if (cfg->inputs[i].type < type_found) {
19489 type_found = cfg->inputs[i].type;
19490 pin_found = nid;
19491 }
19492 }
19493 }
19494
19495 nid = 0x07;
19496 if (pin_found)
19497 snd_hda_get_connections(codec, pin_found, &nid, 1);
19498
19499 if (nid != spec->cur_adc)
19500 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19501 spec->cur_adc = nid;
19502 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19503 spec->cur_adc_format);
19504}
19505
c69aefab
KY
19506static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19507 struct hda_codec *codec,
19508 unsigned int stream_tag,
19509 unsigned int format,
19510 struct snd_pcm_substream *substream)
19511{
19512 struct alc_spec *spec = codec->spec;
c69aefab 19513
66ceeb6b 19514 spec->cur_adc = 0x07;
c69aefab
KY
19515 spec->cur_adc_stream_tag = stream_tag;
19516 spec->cur_adc_format = format;
19517
66ceeb6b 19518 alc680_rec_autoswitch(codec);
c69aefab
KY
19519 return 0;
19520}
19521
19522static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19523 struct hda_codec *codec,
19524 struct snd_pcm_substream *substream)
19525{
19526 snd_hda_codec_cleanup_stream(codec, 0x07);
19527 snd_hda_codec_cleanup_stream(codec, 0x08);
19528 snd_hda_codec_cleanup_stream(codec, 0x09);
19529 return 0;
19530}
19531
a9111321 19532static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
c69aefab
KY
19533 .substreams = 1, /* can be overridden */
19534 .channels_min = 2,
19535 .channels_max = 2,
19536 /* NID is set in alc_build_pcms */
19537 .ops = {
19538 .prepare = alc680_capture_pcm_prepare,
19539 .cleanup = alc680_capture_pcm_cleanup
19540 },
19541};
19542
a9111321 19543static const struct snd_kcontrol_new alc680_base_mixer[] = {
d1eb57f4
KY
19544 /* output mixer control */
19545 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19546 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19547 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19548 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19549 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19550 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19551 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19552 { }
19553};
19554
a9111321 19555static const struct hda_bind_ctls alc680_bind_cap_vol = {
c69aefab
KY
19556 .ops = &snd_hda_bind_vol,
19557 .values = {
19558 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19559 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19560 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19561 0
19562 },
19563};
19564
a9111321 19565static const struct hda_bind_ctls alc680_bind_cap_switch = {
c69aefab
KY
19566 .ops = &snd_hda_bind_sw,
19567 .values = {
19568 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19569 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19570 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19571 0
19572 },
19573};
19574
a9111321 19575static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
c69aefab
KY
19576 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19577 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19578 { } /* end */
19579};
19580
19581/*
19582 * generic initialization of ADC, input mixers and output mixers
19583 */
a9111321 19584static const struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19585 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19586 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19587 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19588
c69aefab
KY
19589 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19590 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19591 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19592 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19593 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19594 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19595
19596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19597 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19599 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19600 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19601
19602 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19603 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19604 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19605
d1eb57f4
KY
19606 { }
19607};
19608
c69aefab
KY
19609/* toggle speaker-output according to the hp-jack state */
19610static void alc680_base_setup(struct hda_codec *codec)
19611{
19612 struct alc_spec *spec = codec->spec;
19613
19614 spec->autocfg.hp_pins[0] = 0x16;
19615 spec->autocfg.speaker_pins[0] = 0x14;
19616 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19617 spec->autocfg.num_inputs = 2;
19618 spec->autocfg.inputs[0].pin = 0x18;
19619 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19620 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19621 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
d922b51d
TI
19622 spec->automute = 1;
19623 spec->automute_mode = ALC_AUTOMUTE_AMP;
c69aefab
KY
19624}
19625
19626static void alc680_unsol_event(struct hda_codec *codec,
19627 unsigned int res)
19628{
19629 if ((res >> 26) == ALC880_HP_EVENT)
d922b51d 19630 alc_hp_automute(codec);
c69aefab
KY
19631 if ((res >> 26) == ALC880_MIC_EVENT)
19632 alc680_rec_autoswitch(codec);
19633}
19634
19635static void alc680_inithook(struct hda_codec *codec)
19636{
d922b51d 19637 alc_hp_automute(codec);
c69aefab
KY
19638 alc680_rec_autoswitch(codec);
19639}
19640
d1eb57f4
KY
19641/* create input playback/capture controls for the given pin */
19642static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19643 const char *ctlname, int idx)
19644{
19645 hda_nid_t dac;
19646 int err;
19647
19648 switch (nid) {
19649 case 0x14:
19650 dac = 0x02;
19651 break;
19652 case 0x15:
19653 dac = 0x03;
19654 break;
19655 case 0x16:
19656 dac = 0x04;
19657 break;
19658 default:
19659 return 0;
19660 }
19661 if (spec->multiout.dac_nids[0] != dac &&
19662 spec->multiout.dac_nids[1] != dac) {
19663 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19664 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19665 HDA_OUTPUT));
19666 if (err < 0)
19667 return err;
19668
19669 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19670 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19671
19672 if (err < 0)
19673 return err;
dda14410 19674 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
d1eb57f4
KY
19675 }
19676
19677 return 0;
19678}
19679
19680/* add playback controls from the parsed DAC table */
19681static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19682 const struct auto_pin_cfg *cfg)
19683{
19684 hda_nid_t nid;
19685 int err;
19686
19687 spec->multiout.dac_nids = spec->private_dac_nids;
19688
19689 nid = cfg->line_out_pins[0];
19690 if (nid) {
19691 const char *name;
2e925dde
TI
19692 int index;
19693 name = alc_get_line_out_pfx(spec, 0, true, &index);
d1eb57f4
KY
19694 err = alc680_new_analog_output(spec, nid, name, 0);
19695 if (err < 0)
19696 return err;
19697 }
19698
19699 nid = cfg->speaker_pins[0];
19700 if (nid) {
19701 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19702 if (err < 0)
19703 return err;
19704 }
19705 nid = cfg->hp_pins[0];
19706 if (nid) {
19707 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19708 if (err < 0)
19709 return err;
19710 }
19711
19712 return 0;
19713}
19714
19715static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19716 hda_nid_t nid, int pin_type)
19717{
19718 alc_set_pin_output(codec, nid, pin_type);
19719}
19720
19721static void alc680_auto_init_multi_out(struct hda_codec *codec)
19722{
19723 struct alc_spec *spec = codec->spec;
19724 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19725 if (nid) {
19726 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19727 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19728 }
19729}
19730
19731static void alc680_auto_init_hp_out(struct hda_codec *codec)
19732{
19733 struct alc_spec *spec = codec->spec;
19734 hda_nid_t pin;
19735
19736 pin = spec->autocfg.hp_pins[0];
19737 if (pin)
19738 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19739 pin = spec->autocfg.speaker_pins[0];
19740 if (pin)
19741 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19742}
19743
19744/* pcm configuration: identical with ALC880 */
19745#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19746#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19747#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19748#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19749#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19750
19751/*
19752 * BIOS auto configuration
19753 */
19754static int alc680_parse_auto_config(struct hda_codec *codec)
19755{
19756 struct alc_spec *spec = codec->spec;
19757 int err;
4c6d72d1 19758 static const hda_nid_t alc680_ignore[] = { 0 };
d1eb57f4
KY
19759
19760 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19761 alc680_ignore);
19762 if (err < 0)
19763 return err;
c69aefab 19764
d1eb57f4
KY
19765 if (!spec->autocfg.line_outs) {
19766 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19767 spec->multiout.max_channels = 2;
19768 spec->no_analog = 1;
19769 goto dig_only;
19770 }
19771 return 0; /* can't find valid BIOS pin config */
19772 }
19773 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19774 if (err < 0)
19775 return err;
19776
19777 spec->multiout.max_channels = 2;
19778
19779 dig_only:
19780 /* digital only support output */
757899ac 19781 alc_auto_parse_digital(codec);
d1eb57f4
KY
19782 if (spec->kctls.list)
19783 add_mixer(spec, spec->kctls.list);
19784
d1eb57f4
KY
19785 err = alc_auto_add_mic_boost(codec);
19786 if (err < 0)
19787 return err;
19788
19789 return 1;
19790}
19791
19792#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19793
19794/* init callback for auto-configuration model -- overriding the default init */
19795static void alc680_auto_init(struct hda_codec *codec)
19796{
19797 struct alc_spec *spec = codec->spec;
19798 alc680_auto_init_multi_out(codec);
19799 alc680_auto_init_hp_out(codec);
19800 alc680_auto_init_analog_input(codec);
757899ac 19801 alc_auto_init_digital(codec);
d1eb57f4
KY
19802 if (spec->unsol_event)
19803 alc_inithook(codec);
19804}
19805
19806/*
19807 * configuration and preset
19808 */
ea734963 19809static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19810 [ALC680_BASE] = "base",
19811 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19812};
19813
a9111321 19814static const struct snd_pci_quirk alc680_cfg_tbl[] = {
d1eb57f4
KY
19815 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19816 {}
19817};
19818
a9111321 19819static const struct alc_config_preset alc680_presets[] = {
d1eb57f4
KY
19820 [ALC680_BASE] = {
19821 .mixers = { alc680_base_mixer },
c69aefab 19822 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19823 .init_verbs = { alc680_init_verbs },
19824 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19825 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19826 .dig_out_nid = ALC680_DIGOUT_NID,
19827 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19828 .channel_mode = alc680_modes,
c69aefab
KY
19829 .unsol_event = alc680_unsol_event,
19830 .setup = alc680_base_setup,
19831 .init_hook = alc680_inithook,
19832
d1eb57f4
KY
19833 },
19834};
19835
19836static int patch_alc680(struct hda_codec *codec)
19837{
19838 struct alc_spec *spec;
19839 int board_config;
19840 int err;
19841
19842 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19843 if (spec == NULL)
19844 return -ENOMEM;
19845
19846 codec->spec = spec;
19847
1f0f4b80
TI
19848 /* ALC680 has no aa-loopback mixer */
19849
d1eb57f4
KY
19850 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19851 alc680_models,
19852 alc680_cfg_tbl);
19853
19854 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19855 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19856 codec->chip_name);
19857 board_config = ALC680_AUTO;
19858 }
19859
19860 if (board_config == ALC680_AUTO) {
19861 /* automatic parse from the BIOS config */
19862 err = alc680_parse_auto_config(codec);
19863 if (err < 0) {
19864 alc_free(codec);
19865 return err;
19866 } else if (!err) {
19867 printk(KERN_INFO
19868 "hda_codec: Cannot set up configuration "
19869 "from BIOS. Using base mode...\n");
19870 board_config = ALC680_BASE;
19871 }
19872 }
19873
19874 if (board_config != ALC680_AUTO)
19875 setup_preset(codec, &alc680_presets[board_config]);
19876
19877 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19878 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19879 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19880 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19881
19882 if (!spec->adc_nids) {
19883 spec->adc_nids = alc680_adc_nids;
19884 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19885 }
19886
19887 if (!spec->cap_mixer)
19888 set_capture_mixer(codec);
19889
19890 spec->vmaster_nid = 0x02;
19891
19892 codec->patch_ops = alc_patch_ops;
19893 if (board_config == ALC680_AUTO)
19894 spec->init_hook = alc680_auto_init;
19895
19896 return 0;
19897}
19898
1da177e4
LT
19899/*
19900 * patch entries
19901 */
a9111321 19902static const struct hda_codec_preset snd_hda_preset_realtek[] = {
296f0338 19903 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
1da177e4 19904 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19905 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19906 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19907 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19908 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19909 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19910 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19911 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
296f0338 19912 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
f32610ed 19913 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19914 .patch = patch_alc861 },
f32610ed
JS
19915 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19916 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19917 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19918 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19919 .patch = patch_alc882 },
bc9f98a9
KY
19920 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19921 .patch = patch_alc662 },
6dda9f4a 19922 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19923 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19924 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19925 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19926 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19927 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19928 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19929 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19930 .patch = patch_alc882 },
cb308f97 19931 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19932 .patch = patch_alc882 },
df694daa 19933 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 19934 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 19935 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19936 .patch = patch_alc882 },
274693f3 19937 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19938 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19939 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
b478b998 19940 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
1da177e4
LT
19941 {} /* terminator */
19942};
1289e9e8
TI
19943
19944MODULE_ALIAS("snd-hda-codec-id:10ec*");
19945
19946MODULE_LICENSE("GPL");
19947MODULE_DESCRIPTION("Realtek HD-audio codec");
19948
19949static struct hda_codec_preset_list realtek_list = {
19950 .preset = snd_hda_preset_realtek,
19951 .owner = THIS_MODULE,
19952};
19953
19954static int __init patch_realtek_init(void)
19955{
19956 return snd_hda_add_codec_preset(&realtek_list);
19957}
19958
19959static void __exit patch_realtek_exit(void)
19960{
19961 snd_hda_delete_codec_preset(&realtek_list);
19962}
19963
19964module_init(patch_realtek_init)
19965module_exit(patch_realtek_exit)