]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Add support for Line-Out automute to Realtek auto-parser
[mirror_ubuntu-bionic-kernel.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
ce764ab2
TI
302struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306};
307
d922b51d 308enum {
3b8510ce
TI
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
d922b51d
TI
312};
313
1da177e4
LT
314struct alc_spec {
315 /* codec parameterization */
df694daa 316 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 317 unsigned int num_mixers;
f9e336f6 318 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 */
1da177e4
LT
328 struct hda_pcm_stream *stream_analog_playback;
329 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
330 struct hda_pcm_stream *stream_analog_alt_playback;
331 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 332
aa563af7 333 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
334 struct hda_pcm_stream *stream_digital_playback;
335 struct hda_pcm_stream *stream_digital_capture;
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;
348 hda_nid_t *adc_nids;
e1406348 349 hda_nid_t *capsrc_nids;
16ded525 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 351
840b64c0
TI
352 /* capture setup for dynamic dual-adc switch */
353 unsigned int cur_adc_idx;
354 hda_nid_t cur_adc;
355 unsigned int cur_adc_stream_tag;
356 unsigned int cur_adc_format;
357
1da177e4 358 /* capture source */
a1e8d2da 359 unsigned int num_mux_defs;
1da177e4
LT
360 const struct hda_input_mux *input_mux;
361 unsigned int cur_mux[3];
6c819492
TI
362 struct alc_mic_route ext_mic;
363 struct alc_mic_route int_mic;
1da177e4
LT
364
365 /* channel model */
d2a6d7dc 366 const struct hda_channel_mode *channel_mode;
1da177e4 367 int num_channel_mode;
4e195a7b 368 int need_dac_fix;
3b315d70
HM
369 int const_channel_count;
370 int ext_channel_count;
1da177e4
LT
371
372 /* PCM information */
4c5186ed 373 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 374
e9edcee0
TI
375 /* dynamic controls, init_verbs and input_mux */
376 struct auto_pin_cfg autocfg;
da00c244 377 struct alc_customize_define cdefine;
603c4019 378 struct snd_array kctls;
61b9b9b1 379 struct hda_input_mux private_imux[3];
41923e44 380 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
381 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
382 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 383
ae6b813a
TI
384 /* hooks */
385 void (*init_hook)(struct hda_codec *codec);
386 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 387#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 388 void (*power_hook)(struct hda_codec *codec);
f5de24b0 389#endif
1c716153 390 void (*shutup)(struct hda_codec *codec);
ae6b813a 391
834be88d 392 /* for pin sensing */
834be88d 393 unsigned int jack_present: 1;
e6a5e1b7 394 unsigned int line_jack_present:1;
e9427969 395 unsigned int master_mute:1;
6c819492 396 unsigned int auto_mic:1;
d922b51d 397 unsigned int automute:1; /* HP automute enabled */
e6a5e1b7
TI
398 unsigned int detect_line:1; /* Line-out detection enabled */
399 unsigned int automute_lines:1; /* automute line-out as well */
cb53c626 400
e64f14f4
TI
401 /* other flags */
402 unsigned int no_analog :1; /* digital I/O only */
840b64c0 403 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
584c0c4c 404 unsigned int single_input_src:1;
d922b51d
TI
405
406 /* auto-mute control */
407 int automute_mode;
3b8510ce 408 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
d922b51d 409
4a79ba34 410 int init_amp;
d433a678 411 int codec_variant; /* flag for other variants */
e64f14f4 412
2134ea4f
TI
413 /* for virtual master */
414 hda_nid_t vmaster_nid;
cb53c626
TI
415#ifdef CONFIG_SND_HDA_POWER_SAVE
416 struct hda_loopback_check loopback;
417#endif
2c3bf9ab
TI
418
419 /* for PLL fix */
420 hda_nid_t pll_nid;
421 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
422
423 /* fix-up list */
424 int fixup_id;
425 const struct alc_fixup *fixup_list;
426 const char *fixup_name;
ce764ab2
TI
427
428 /* multi-io */
429 int multi_ios;
430 struct alc_multi_io multi_io[4];
df694daa
KY
431};
432
433/*
434 * configuration template - to be copied to the spec instance
435 */
436struct alc_config_preset {
9c7f852e
TI
437 struct snd_kcontrol_new *mixers[5]; /* should be identical size
438 * with spec
439 */
f9e336f6 440 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
441 const struct hda_verb *init_verbs[5];
442 unsigned int num_dacs;
443 hda_nid_t *dac_nids;
444 hda_nid_t dig_out_nid; /* optional */
445 hda_nid_t hp_nid; /* optional */
b25c9da1 446 hda_nid_t *slave_dig_outs;
df694daa
KY
447 unsigned int num_adc_nids;
448 hda_nid_t *adc_nids;
e1406348 449 hda_nid_t *capsrc_nids;
df694daa
KY
450 hda_nid_t dig_in_nid;
451 unsigned int num_channel_mode;
452 const struct hda_channel_mode *channel_mode;
4e195a7b 453 int need_dac_fix;
3b315d70 454 int const_channel_count;
a1e8d2da 455 unsigned int num_mux_defs;
df694daa 456 const struct hda_input_mux *input_mux;
ae6b813a 457 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 458 void (*setup)(struct hda_codec *);
ae6b813a 459 void (*init_hook)(struct hda_codec *);
cb53c626
TI
460#ifdef CONFIG_SND_HDA_POWER_SAVE
461 struct hda_amp_list *loopbacks;
c97259df 462 void (*power_hook)(struct hda_codec *codec);
cb53c626 463#endif
1da177e4
LT
464};
465
1da177e4
LT
466
467/*
468 * input MUX handling
469 */
9c7f852e
TI
470static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
471 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
472{
473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
474 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
475 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
476 if (mux_idx >= spec->num_mux_defs)
477 mux_idx = 0;
5311114d
TI
478 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
479 mux_idx = 0;
a1e8d2da 480 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
481}
482
9c7f852e
TI
483static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
484 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
485{
486 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
487 struct alc_spec *spec = codec->spec;
488 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
489
490 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
491 return 0;
492}
493
9c7f852e
TI
494static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
495 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
496{
497 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
498 struct alc_spec *spec = codec->spec;
cd896c33 499 const struct hda_input_mux *imux;
1da177e4 500 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 501 unsigned int mux_idx;
e1406348
TI
502 hda_nid_t nid = spec->capsrc_nids ?
503 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 504 unsigned int type;
1da177e4 505
cd896c33
TI
506 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
507 imux = &spec->input_mux[mux_idx];
5311114d
TI
508 if (!imux->num_items && mux_idx > 0)
509 imux = &spec->input_mux[0];
cd896c33 510
a22d543a 511 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 512 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
513 /* Matrix-mixer style (e.g. ALC882) */
514 unsigned int *cur_val = &spec->cur_mux[adc_idx];
515 unsigned int i, idx;
516
517 idx = ucontrol->value.enumerated.item[0];
518 if (idx >= imux->num_items)
519 idx = imux->num_items - 1;
520 if (*cur_val == idx)
521 return 0;
522 for (i = 0; i < imux->num_items; i++) {
523 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
524 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
525 imux->items[i].index,
526 HDA_AMP_MUTE, v);
527 }
528 *cur_val = idx;
529 return 1;
530 } else {
531 /* MUX style (e.g. ALC880) */
cd896c33 532 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
533 &spec->cur_mux[adc_idx]);
534 }
535}
e9edcee0 536
1da177e4
LT
537/*
538 * channel mode setting
539 */
9c7f852e
TI
540static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
541 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
542{
543 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
544 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
545 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
546 spec->num_channel_mode);
1da177e4
LT
547}
548
9c7f852e
TI
549static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
550 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
551{
552 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
553 struct alc_spec *spec = codec->spec;
d2a6d7dc 554 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 555 spec->num_channel_mode,
3b315d70 556 spec->ext_channel_count);
1da177e4
LT
557}
558
9c7f852e
TI
559static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
560 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
561{
562 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
563 struct alc_spec *spec = codec->spec;
4e195a7b
TI
564 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
565 spec->num_channel_mode,
3b315d70
HM
566 &spec->ext_channel_count);
567 if (err >= 0 && !spec->const_channel_count) {
568 spec->multiout.max_channels = spec->ext_channel_count;
569 if (spec->need_dac_fix)
570 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
571 }
4e195a7b 572 return err;
1da177e4
LT
573}
574
a9430dd8 575/*
4c5186ed 576 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 577 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
578 * being part of a format specifier. Maximum allowed length of a value is
579 * 63 characters plus NULL terminator.
7cf51e48
JW
580 *
581 * Note: some retasking pin complexes seem to ignore requests for input
582 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
583 * are requested. Therefore order this list so that this behaviour will not
584 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
585 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
586 * March 2006.
4c5186ed
JW
587 */
588static char *alc_pin_mode_names[] = {
7cf51e48
JW
589 "Mic 50pc bias", "Mic 80pc bias",
590 "Line in", "Line out", "Headphone out",
4c5186ed
JW
591};
592static unsigned char alc_pin_mode_values[] = {
7cf51e48 593 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
594};
595/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
596 * in the pin being assumed to be exclusively an input or an output pin. In
597 * addition, "input" pins may or may not process the mic bias option
598 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
599 * accept requests for bias as of chip versions up to March 2006) and/or
600 * wiring in the computer.
a9430dd8 601 */
a1e8d2da
JW
602#define ALC_PIN_DIR_IN 0x00
603#define ALC_PIN_DIR_OUT 0x01
604#define ALC_PIN_DIR_INOUT 0x02
605#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
606#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 607
ea1fb29a 608/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
609 * For each direction the minimum and maximum values are given.
610 */
a1e8d2da 611static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
612 { 0, 2 }, /* ALC_PIN_DIR_IN */
613 { 3, 4 }, /* ALC_PIN_DIR_OUT */
614 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
615 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
616 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
617};
618#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
619#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
620#define alc_pin_mode_n_items(_dir) \
621 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
622
9c7f852e
TI
623static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
624 struct snd_ctl_elem_info *uinfo)
a9430dd8 625{
4c5186ed
JW
626 unsigned int item_num = uinfo->value.enumerated.item;
627 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
628
629 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 630 uinfo->count = 1;
4c5186ed
JW
631 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
632
633 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
634 item_num = alc_pin_mode_min(dir);
635 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
636 return 0;
637}
638
9c7f852e
TI
639static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_value *ucontrol)
a9430dd8 641{
4c5186ed 642 unsigned int i;
a9430dd8
JW
643 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
644 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 645 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 646 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
647 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
648 AC_VERB_GET_PIN_WIDGET_CONTROL,
649 0x00);
a9430dd8 650
4c5186ed
JW
651 /* Find enumerated value for current pinctl setting */
652 i = alc_pin_mode_min(dir);
4b35d2ca 653 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 654 i++;
9c7f852e 655 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
656 return 0;
657}
658
9c7f852e
TI
659static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
660 struct snd_ctl_elem_value *ucontrol)
a9430dd8 661{
4c5186ed 662 signed int change;
a9430dd8
JW
663 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
664 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
665 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
666 long val = *ucontrol->value.integer.value;
9c7f852e
TI
667 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
668 AC_VERB_GET_PIN_WIDGET_CONTROL,
669 0x00);
a9430dd8 670
f12ab1e0 671 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
672 val = alc_pin_mode_min(dir);
673
674 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
675 if (change) {
676 /* Set pin mode to that requested */
82beb8fd
TI
677 snd_hda_codec_write_cache(codec, nid, 0,
678 AC_VERB_SET_PIN_WIDGET_CONTROL,
679 alc_pin_mode_values[val]);
cdcd9268 680
ea1fb29a 681 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
682 * for the requested pin mode. Enum values of 2 or less are
683 * input modes.
684 *
685 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
686 * reduces noise slightly (particularly on input) so we'll
687 * do it. However, having both input and output buffers
688 * enabled simultaneously doesn't seem to be problematic if
689 * this turns out to be necessary in the future.
cdcd9268
JW
690 */
691 if (val <= 2) {
47fd830a
TI
692 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
693 HDA_AMP_MUTE, HDA_AMP_MUTE);
694 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
695 HDA_AMP_MUTE, 0);
cdcd9268 696 } else {
47fd830a
TI
697 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
698 HDA_AMP_MUTE, HDA_AMP_MUTE);
699 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
700 HDA_AMP_MUTE, 0);
cdcd9268
JW
701 }
702 }
a9430dd8
JW
703 return change;
704}
705
4c5186ed 706#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 707 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 708 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
709 .info = alc_pin_mode_info, \
710 .get = alc_pin_mode_get, \
711 .put = alc_pin_mode_put, \
712 .private_value = nid | (dir<<16) }
df694daa 713
5c8f858d
JW
714/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
715 * together using a mask with more than one bit set. This control is
716 * currently used only by the ALC260 test model. At this stage they are not
717 * needed for any "production" models.
718 */
719#ifdef CONFIG_SND_DEBUG
a5ce8890 720#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 721
9c7f852e
TI
722static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
723 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
724{
725 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
726 hda_nid_t nid = kcontrol->private_value & 0xffff;
727 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
728 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
729 unsigned int val = snd_hda_codec_read(codec, nid, 0,
730 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
731
732 *valp = (val & mask) != 0;
733 return 0;
734}
9c7f852e
TI
735static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
736 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
737{
738 signed int change;
739 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
740 hda_nid_t nid = kcontrol->private_value & 0xffff;
741 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
742 long val = *ucontrol->value.integer.value;
9c7f852e
TI
743 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
744 AC_VERB_GET_GPIO_DATA,
745 0x00);
5c8f858d
JW
746
747 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
748 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
749 if (val == 0)
5c8f858d
JW
750 gpio_data &= ~mask;
751 else
752 gpio_data |= mask;
82beb8fd
TI
753 snd_hda_codec_write_cache(codec, nid, 0,
754 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
755
756 return change;
757}
758#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
759 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 760 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
761 .info = alc_gpio_data_info, \
762 .get = alc_gpio_data_get, \
763 .put = alc_gpio_data_put, \
764 .private_value = nid | (mask<<16) }
765#endif /* CONFIG_SND_DEBUG */
766
92621f13
JW
767/* A switch control to allow the enabling of the digital IO pins on the
768 * ALC260. This is incredibly simplistic; the intention of this control is
769 * to provide something in the test model allowing digital outputs to be
770 * identified if present. If models are found which can utilise these
771 * outputs a more complete mixer control can be devised for those models if
772 * necessary.
773 */
774#ifdef CONFIG_SND_DEBUG
a5ce8890 775#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 776
9c7f852e
TI
777static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
778 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
779{
780 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
781 hda_nid_t nid = kcontrol->private_value & 0xffff;
782 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
783 long *valp = ucontrol->value.integer.value;
9c7f852e 784 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 785 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
786
787 *valp = (val & mask) != 0;
788 return 0;
789}
9c7f852e
TI
790static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
791 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
792{
793 signed int change;
794 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
795 hda_nid_t nid = kcontrol->private_value & 0xffff;
796 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
797 long val = *ucontrol->value.integer.value;
9c7f852e 798 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 799 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 800 0x00);
92621f13
JW
801
802 /* Set/unset the masked control bit(s) as needed */
9c7f852e 803 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
804 if (val==0)
805 ctrl_data &= ~mask;
806 else
807 ctrl_data |= mask;
82beb8fd
TI
808 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
809 ctrl_data);
92621f13
JW
810
811 return change;
812}
813#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
814 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 815 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
816 .info = alc_spdif_ctrl_info, \
817 .get = alc_spdif_ctrl_get, \
818 .put = alc_spdif_ctrl_put, \
819 .private_value = nid | (mask<<16) }
820#endif /* CONFIG_SND_DEBUG */
821
f8225f6d
JW
822/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
823 * Again, this is only used in the ALC26x test models to help identify when
824 * the EAPD line must be asserted for features to work.
825 */
826#ifdef CONFIG_SND_DEBUG
827#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
828
829static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
830 struct snd_ctl_elem_value *ucontrol)
831{
832 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
833 hda_nid_t nid = kcontrol->private_value & 0xffff;
834 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
835 long *valp = ucontrol->value.integer.value;
836 unsigned int val = snd_hda_codec_read(codec, nid, 0,
837 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
838
839 *valp = (val & mask) != 0;
840 return 0;
841}
842
843static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
844 struct snd_ctl_elem_value *ucontrol)
845{
846 int change;
847 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
848 hda_nid_t nid = kcontrol->private_value & 0xffff;
849 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
850 long val = *ucontrol->value.integer.value;
851 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
852 AC_VERB_GET_EAPD_BTLENABLE,
853 0x00);
854
855 /* Set/unset the masked control bit(s) as needed */
856 change = (!val ? 0 : mask) != (ctrl_data & mask);
857 if (!val)
858 ctrl_data &= ~mask;
859 else
860 ctrl_data |= mask;
861 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
862 ctrl_data);
863
864 return change;
865}
866
867#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
868 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 869 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
870 .info = alc_eapd_ctrl_info, \
871 .get = alc_eapd_ctrl_get, \
872 .put = alc_eapd_ctrl_put, \
873 .private_value = nid | (mask<<16) }
874#endif /* CONFIG_SND_DEBUG */
875
23f0c048
TI
876/*
877 * set up the input pin config (depending on the given auto-pin type)
878 */
879static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
880 int auto_pin_type)
881{
882 unsigned int val = PIN_IN;
883
86e2959a 884 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 885 unsigned int pincap;
954a29c8
TI
886 unsigned int oldval;
887 oldval = snd_hda_codec_read(codec, nid, 0,
888 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 889 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 890 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
891 /* if the default pin setup is vref50, we give it priority */
892 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 893 val = PIN_VREF80;
461c6c3a
TI
894 else if (pincap & AC_PINCAP_VREF_50)
895 val = PIN_VREF50;
896 else if (pincap & AC_PINCAP_VREF_100)
897 val = PIN_VREF100;
898 else if (pincap & AC_PINCAP_VREF_GRD)
899 val = PIN_VREFGRD;
23f0c048
TI
900 }
901 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
902}
903
f6837bbd
TI
904static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
905{
906 struct alc_spec *spec = codec->spec;
907 struct auto_pin_cfg *cfg = &spec->autocfg;
908
909 if (!cfg->line_outs) {
910 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
911 cfg->line_out_pins[cfg->line_outs])
912 cfg->line_outs++;
913 }
914 if (!cfg->speaker_outs) {
915 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
916 cfg->speaker_pins[cfg->speaker_outs])
917 cfg->speaker_outs++;
918 }
919 if (!cfg->hp_outs) {
920 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
921 cfg->hp_pins[cfg->hp_outs])
922 cfg->hp_outs++;
923 }
924}
925
d88897ea
TI
926/*
927 */
928static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
929{
930 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
931 return;
932 spec->mixers[spec->num_mixers++] = mix;
933}
934
935static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
936{
937 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
938 return;
939 spec->init_verbs[spec->num_init_verbs++] = verb;
940}
941
df694daa
KY
942/*
943 * set up from the preset table
944 */
e9c364c0 945static void setup_preset(struct hda_codec *codec,
9c7f852e 946 const struct alc_config_preset *preset)
df694daa 947{
e9c364c0 948 struct alc_spec *spec = codec->spec;
df694daa
KY
949 int i;
950
951 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 952 add_mixer(spec, preset->mixers[i]);
f9e336f6 953 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
954 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
955 i++)
d88897ea 956 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 957
df694daa
KY
958 spec->channel_mode = preset->channel_mode;
959 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 960 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 961 spec->const_channel_count = preset->const_channel_count;
df694daa 962
3b315d70
HM
963 if (preset->const_channel_count)
964 spec->multiout.max_channels = preset->const_channel_count;
965 else
966 spec->multiout.max_channels = spec->channel_mode[0].channels;
967 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
968
969 spec->multiout.num_dacs = preset->num_dacs;
970 spec->multiout.dac_nids = preset->dac_nids;
971 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 972 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 973 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 974
a1e8d2da 975 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 976 if (!spec->num_mux_defs)
a1e8d2da 977 spec->num_mux_defs = 1;
df694daa
KY
978 spec->input_mux = preset->input_mux;
979
980 spec->num_adc_nids = preset->num_adc_nids;
981 spec->adc_nids = preset->adc_nids;
e1406348 982 spec->capsrc_nids = preset->capsrc_nids;
df694daa 983 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
984
985 spec->unsol_event = preset->unsol_event;
986 spec->init_hook = preset->init_hook;
cb53c626 987#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 988 spec->power_hook = preset->power_hook;
cb53c626
TI
989 spec->loopback.amplist = preset->loopbacks;
990#endif
e9c364c0
TI
991
992 if (preset->setup)
993 preset->setup(codec);
f6837bbd
TI
994
995 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
996}
997
bc9f98a9
KY
998/* Enable GPIO mask and set output */
999static struct hda_verb alc_gpio1_init_verbs[] = {
1000 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1001 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1002 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1003 { }
1004};
1005
1006static struct hda_verb alc_gpio2_init_verbs[] = {
1007 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1008 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1009 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1010 { }
1011};
1012
bdd148a3
KY
1013static struct hda_verb alc_gpio3_init_verbs[] = {
1014 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1015 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1016 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1017 { }
1018};
1019
2c3bf9ab
TI
1020/*
1021 * Fix hardware PLL issue
1022 * On some codecs, the analog PLL gating control must be off while
1023 * the default value is 1.
1024 */
1025static void alc_fix_pll(struct hda_codec *codec)
1026{
1027 struct alc_spec *spec = codec->spec;
1028 unsigned int val;
1029
1030 if (!spec->pll_nid)
1031 return;
1032 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1033 spec->pll_coef_idx);
1034 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1035 AC_VERB_GET_PROC_COEF, 0);
1036 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1037 spec->pll_coef_idx);
1038 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1039 val & ~(1 << spec->pll_coef_bit));
1040}
1041
1042static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1043 unsigned int coef_idx, unsigned int coef_bit)
1044{
1045 struct alc_spec *spec = codec->spec;
1046 spec->pll_nid = nid;
1047 spec->pll_coef_idx = coef_idx;
1048 spec->pll_coef_bit = coef_bit;
1049 alc_fix_pll(codec);
1050}
1051
9ad0e496
KY
1052static int alc_init_jacks(struct hda_codec *codec)
1053{
cd372fb3 1054#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1055 struct alc_spec *spec = codec->spec;
1056 int err;
1057 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1058 unsigned int mic_nid = spec->ext_mic.pin;
1059
265a0247 1060 if (hp_nid) {
cd372fb3
TI
1061 err = snd_hda_input_jack_add(codec, hp_nid,
1062 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1063 if (err < 0)
1064 return err;
cd372fb3 1065 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1066 }
9ad0e496 1067
265a0247 1068 if (mic_nid) {
cd372fb3
TI
1069 err = snd_hda_input_jack_add(codec, mic_nid,
1070 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1071 if (err < 0)
1072 return err;
cd372fb3 1073 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1074 }
cd372fb3 1075#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1076 return 0;
1077}
9ad0e496 1078
e6a5e1b7 1079static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
c9b58006 1080{
e6a5e1b7 1081 int i, present = 0;
c9b58006 1082
e6a5e1b7
TI
1083 for (i = 0; i < num_pins; i++) {
1084 hda_nid_t nid = pins[i];
bb35febd
TI
1085 if (!nid)
1086 break;
cd372fb3 1087 snd_hda_input_jack_report(codec, nid);
e6a5e1b7 1088 present |= snd_hda_jack_detect(codec, nid);
bb35febd 1089 }
e6a5e1b7
TI
1090 return present;
1091}
bb35febd 1092
e6a5e1b7 1093static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
e9427969 1094 bool mute, bool hp_out)
e6a5e1b7
TI
1095{
1096 struct alc_spec *spec = codec->spec;
1097 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
e9427969 1098 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
e6a5e1b7
TI
1099 int i;
1100
1101 for (i = 0; i < num_pins; i++) {
1102 hda_nid_t nid = pins[i];
a9fd4f3f
TI
1103 if (!nid)
1104 break;
3b8510ce
TI
1105 switch (spec->automute_mode) {
1106 case ALC_AUTOMUTE_PIN:
bb35febd 1107 snd_hda_codec_write(codec, nid, 0,
e6a5e1b7
TI
1108 AC_VERB_SET_PIN_WIDGET_CONTROL,
1109 pin_bits);
3b8510ce
TI
1110 break;
1111 case ALC_AUTOMUTE_AMP:
bb35febd 1112 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
e6a5e1b7 1113 HDA_AMP_MUTE, mute_bits);
3b8510ce
TI
1114 break;
1115 case ALC_AUTOMUTE_MIXER:
1116 nid = spec->automute_mixer_nid[i];
1117 if (!nid)
1118 break;
1119 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
e6a5e1b7 1120 HDA_AMP_MUTE, mute_bits);
3b8510ce 1121 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
e6a5e1b7 1122 HDA_AMP_MUTE, mute_bits);
3b8510ce 1123 break;
bb35febd 1124 }
a9fd4f3f 1125 }
c9b58006
KY
1126}
1127
e6a5e1b7
TI
1128/* Toggle internal speakers muting */
1129static void update_speakers(struct hda_codec *codec)
1130{
1131 struct alc_spec *spec = codec->spec;
1a1455de 1132 int on;
e6a5e1b7 1133
1a1455de
TI
1134 if (!spec->automute)
1135 on = 0;
1136 else
1137 on = spec->jack_present | spec->line_jack_present;
1138 on |= spec->master_mute;
e6a5e1b7 1139 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1a1455de 1140 spec->autocfg.speaker_pins, on, false);
e6a5e1b7
TI
1141
1142 /* toggle line-out mutes if needed, too */
1a1455de
TI
1143 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1144 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1145 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
e6a5e1b7 1146 return;
1a1455de
TI
1147 if (!spec->automute_lines || !spec->automute)
1148 on = 0;
1149 else
1150 on = spec->jack_present;
1151 on |= spec->master_mute;
e6a5e1b7 1152 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1a1455de 1153 spec->autocfg.line_out_pins, on, false);
e6a5e1b7
TI
1154}
1155
1156static void alc_hp_automute(struct hda_codec *codec)
1157{
1158 struct alc_spec *spec = codec->spec;
1159
1160 if (!spec->automute)
1161 return;
1162 spec->jack_present =
1163 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1164 spec->autocfg.hp_pins);
1165 update_speakers(codec);
1166}
1167
1168static void alc_line_automute(struct hda_codec *codec)
1169{
1170 struct alc_spec *spec = codec->spec;
1171
1172 if (!spec->automute || !spec->detect_line)
1173 return;
1174 spec->line_jack_present =
1175 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1176 spec->autocfg.line_out_pins);
1177 update_speakers(codec);
1178}
1179
6c819492
TI
1180static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1181 hda_nid_t nid)
1182{
1183 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1184 int i, nums;
1185
1186 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1187 for (i = 0; i < nums; i++)
1188 if (conn[i] == nid)
1189 return i;
1190 return -1;
1191}
1192
840b64c0
TI
1193/* switch the current ADC according to the jack state */
1194static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1195{
1196 struct alc_spec *spec = codec->spec;
1197 unsigned int present;
1198 hda_nid_t new_adc;
1199
1200 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1201 if (present)
1202 spec->cur_adc_idx = 1;
1203 else
1204 spec->cur_adc_idx = 0;
1205 new_adc = spec->adc_nids[spec->cur_adc_idx];
1206 if (spec->cur_adc && spec->cur_adc != new_adc) {
1207 /* stream is running, let's swap the current ADC */
f0cea797 1208 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1209 spec->cur_adc = new_adc;
1210 snd_hda_codec_setup_stream(codec, new_adc,
1211 spec->cur_adc_stream_tag, 0,
1212 spec->cur_adc_format);
1213 }
1214}
1215
7fb0d78f
KY
1216static void alc_mic_automute(struct hda_codec *codec)
1217{
1218 struct alc_spec *spec = codec->spec;
6c819492
TI
1219 struct alc_mic_route *dead, *alive;
1220 unsigned int present, type;
1221 hda_nid_t cap_nid;
1222
b59bdf3b
TI
1223 if (!spec->auto_mic)
1224 return;
6c819492
TI
1225 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1226 return;
1227 if (snd_BUG_ON(!spec->adc_nids))
1228 return;
1229
840b64c0
TI
1230 if (spec->dual_adc_switch) {
1231 alc_dual_mic_adc_auto_switch(codec);
1232 return;
1233 }
1234
6c819492
TI
1235 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1236
864f92be 1237 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1238 if (present) {
1239 alive = &spec->ext_mic;
1240 dead = &spec->int_mic;
1241 } else {
1242 alive = &spec->int_mic;
1243 dead = &spec->ext_mic;
1244 }
1245
6c819492
TI
1246 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1247 if (type == AC_WID_AUD_MIX) {
1248 /* Matrix-mixer style (e.g. ALC882) */
1249 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1250 alive->mux_idx,
1251 HDA_AMP_MUTE, 0);
1252 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1253 dead->mux_idx,
1254 HDA_AMP_MUTE, HDA_AMP_MUTE);
1255 } else {
1256 /* MUX style (e.g. ALC880) */
1257 snd_hda_codec_write_cache(codec, cap_nid, 0,
1258 AC_VERB_SET_CONNECT_SEL,
1259 alive->mux_idx);
1260 }
cd372fb3 1261 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1262
1263 /* FIXME: analog mixer */
7fb0d78f
KY
1264}
1265
c9b58006
KY
1266/* unsolicited event for HP jack sensing */
1267static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1268{
1269 if (codec->vendor_id == 0x10ec0880)
1270 res >>= 28;
1271 else
1272 res >>= 26;
a9fd4f3f
TI
1273 switch (res) {
1274 case ALC880_HP_EVENT:
d922b51d 1275 alc_hp_automute(codec);
a9fd4f3f 1276 break;
e6a5e1b7
TI
1277 case ALC880_FRONT_EVENT:
1278 alc_line_automute(codec);
1279 break;
a9fd4f3f 1280 case ALC880_MIC_EVENT:
7fb0d78f 1281 alc_mic_automute(codec);
a9fd4f3f
TI
1282 break;
1283 }
7fb0d78f
KY
1284}
1285
1286static void alc_inithook(struct hda_codec *codec)
1287{
d922b51d 1288 alc_hp_automute(codec);
e6a5e1b7 1289 alc_line_automute(codec);
7fb0d78f 1290 alc_mic_automute(codec);
c9b58006
KY
1291}
1292
f9423e7a
KY
1293/* additional initialization for ALC888 variants */
1294static void alc888_coef_init(struct hda_codec *codec)
1295{
1296 unsigned int tmp;
1297
1298 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1299 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1300 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1301 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1302 /* alc888S-VC */
1303 snd_hda_codec_read(codec, 0x20, 0,
1304 AC_VERB_SET_PROC_COEF, 0x830);
1305 else
1306 /* alc888-VB */
1307 snd_hda_codec_read(codec, 0x20, 0,
1308 AC_VERB_SET_PROC_COEF, 0x3030);
1309}
1310
87a8c370
JK
1311static void alc889_coef_init(struct hda_codec *codec)
1312{
1313 unsigned int tmp;
1314
1315 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1316 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1317 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1318 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1319}
1320
3fb4a508
TI
1321/* turn on/off EAPD control (only if available) */
1322static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1323{
1324 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1325 return;
1326 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1327 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1328 on ? 2 : 0);
1329}
1330
691f1fcc
TI
1331/* turn on/off EAPD controls of the codec */
1332static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1333{
1334 /* We currently only handle front, HP */
1335 switch (codec->vendor_id) {
1336 case 0x10ec0260:
1337 set_eapd(codec, 0x0f, on);
1338 set_eapd(codec, 0x10, on);
1339 break;
1340 case 0x10ec0262:
1341 case 0x10ec0267:
1342 case 0x10ec0268:
1343 case 0x10ec0269:
1344 case 0x10ec0270:
1345 case 0x10ec0272:
1346 case 0x10ec0660:
1347 case 0x10ec0662:
1348 case 0x10ec0663:
1349 case 0x10ec0665:
1350 case 0x10ec0862:
1351 case 0x10ec0889:
1352 case 0x10ec0892:
1353 set_eapd(codec, 0x14, on);
1354 set_eapd(codec, 0x15, on);
1355 break;
1356 }
1357}
1358
1c716153
TI
1359/* generic shutup callback;
1360 * just turning off EPAD and a little pause for avoiding pop-noise
1361 */
1362static void alc_eapd_shutup(struct hda_codec *codec)
1363{
1364 alc_auto_setup_eapd(codec, false);
1365 msleep(200);
1366}
1367
4a79ba34 1368static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1369{
4a79ba34 1370 unsigned int tmp;
bc9f98a9 1371
4a79ba34
TI
1372 switch (type) {
1373 case ALC_INIT_GPIO1:
bc9f98a9
KY
1374 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1375 break;
4a79ba34 1376 case ALC_INIT_GPIO2:
bc9f98a9
KY
1377 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1378 break;
4a79ba34 1379 case ALC_INIT_GPIO3:
bdd148a3
KY
1380 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1381 break;
4a79ba34 1382 case ALC_INIT_DEFAULT:
691f1fcc 1383 alc_auto_setup_eapd(codec, true);
c9b58006
KY
1384 switch (codec->vendor_id) {
1385 case 0x10ec0260:
1386 snd_hda_codec_write(codec, 0x1a, 0,
1387 AC_VERB_SET_COEF_INDEX, 7);
1388 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1389 AC_VERB_GET_PROC_COEF, 0);
1390 snd_hda_codec_write(codec, 0x1a, 0,
1391 AC_VERB_SET_COEF_INDEX, 7);
1392 snd_hda_codec_write(codec, 0x1a, 0,
1393 AC_VERB_SET_PROC_COEF,
1394 tmp | 0x2010);
1395 break;
1396 case 0x10ec0262:
1397 case 0x10ec0880:
1398 case 0x10ec0882:
1399 case 0x10ec0883:
1400 case 0x10ec0885:
4a5a4c56 1401 case 0x10ec0887:
20b67ddd 1402 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1403 alc889_coef_init(codec);
c9b58006 1404 break;
f9423e7a 1405 case 0x10ec0888:
4a79ba34 1406 alc888_coef_init(codec);
f9423e7a 1407 break;
0aea778e 1408#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1409 case 0x10ec0267:
1410 case 0x10ec0268:
1411 snd_hda_codec_write(codec, 0x20, 0,
1412 AC_VERB_SET_COEF_INDEX, 7);
1413 tmp = snd_hda_codec_read(codec, 0x20, 0,
1414 AC_VERB_GET_PROC_COEF, 0);
1415 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1416 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1417 snd_hda_codec_write(codec, 0x20, 0,
1418 AC_VERB_SET_PROC_COEF,
1419 tmp | 0x3000);
1420 break;
0aea778e 1421#endif /* XXX */
bc9f98a9 1422 }
4a79ba34
TI
1423 break;
1424 }
1425}
1426
1a1455de
TI
1427static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1428 struct snd_ctl_elem_info *uinfo)
1429{
1430 static const char * const texts[] = {
1431 "Disabled", "Speaker Only", "Line-Out+Speaker"
1432 };
1433
1434 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1435 uinfo->count = 1;
1436 uinfo->value.enumerated.items = 3;
1437 if (uinfo->value.enumerated.item >= 3)
1438 uinfo->value.enumerated.item = 2;
1439 strcpy(uinfo->value.enumerated.name,
1440 texts[uinfo->value.enumerated.item]);
1441 return 0;
1442}
1443
1444static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1445 struct snd_ctl_elem_value *ucontrol)
1446{
1447 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1448 struct alc_spec *spec = codec->spec;
1449 unsigned int val;
1450 if (!spec->automute)
1451 val = 0;
1452 else if (!spec->automute_lines)
1453 val = 1;
1454 else
1455 val = 2;
1456 ucontrol->value.enumerated.item[0] = val;
1457 return 0;
1458}
1459
1460static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1461 struct snd_ctl_elem_value *ucontrol)
1462{
1463 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1464 struct alc_spec *spec = codec->spec;
1465
1466 switch (ucontrol->value.enumerated.item[0]) {
1467 case 0:
1468 if (!spec->automute)
1469 return 0;
1470 spec->automute = 0;
1471 break;
1472 case 1:
1473 if (spec->automute && !spec->automute_lines)
1474 return 0;
1475 spec->automute = 1;
1476 spec->automute_lines = 0;
1477 break;
1478 case 2:
1479 if (spec->automute && spec->automute_lines)
1480 return 0;
1481 spec->automute = 1;
1482 spec->automute_lines = 1;
1483 break;
1484 default:
1485 return -EINVAL;
1486 }
1487 update_speakers(codec);
1488 return 1;
1489}
1490
1491static struct snd_kcontrol_new alc_automute_mode_enum = {
1492 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1493 .name = "Auto-Mute Mode",
1494 .info = alc_automute_mode_info,
1495 .get = alc_automute_mode_get,
1496 .put = alc_automute_mode_put,
1497};
1498
1499static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1500
1501static int alc_add_automute_mode_enum(struct hda_codec *codec)
1502{
1503 struct alc_spec *spec = codec->spec;
1504 struct snd_kcontrol_new *knew;
1505
1506 knew = alc_kcontrol_new(spec);
1507 if (!knew)
1508 return -ENOMEM;
1509 *knew = alc_automute_mode_enum;
1510 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1511 if (!knew->name)
1512 return -ENOMEM;
1513 return 0;
1514}
1515
4a79ba34
TI
1516static void alc_init_auto_hp(struct hda_codec *codec)
1517{
1518 struct alc_spec *spec = codec->spec;
bb35febd
TI
1519 struct auto_pin_cfg *cfg = &spec->autocfg;
1520 int i;
4a79ba34 1521
bb35febd
TI
1522 if (!cfg->hp_pins[0]) {
1523 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1524 return;
1525 }
4a79ba34 1526
bb35febd
TI
1527 if (!cfg->speaker_pins[0]) {
1528 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4a79ba34 1529 return;
bb35febd
TI
1530 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1531 sizeof(cfg->speaker_pins));
1532 cfg->speaker_outs = cfg->line_outs;
1533 }
1534
1535 if (!cfg->hp_pins[0]) {
1536 memcpy(cfg->hp_pins, cfg->line_out_pins,
1537 sizeof(cfg->hp_pins));
1538 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1539 }
1540
bb35febd 1541 for (i = 0; i < cfg->hp_outs; i++) {
1a1455de
TI
1542 hda_nid_t nid = cfg->hp_pins[i];
1543 if (!(snd_hda_query_pin_caps(codec, nid) &
1544 AC_PINCAP_PRES_DETECT))
1545 continue;
bb35febd 1546 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1a1455de
TI
1547 nid);
1548 snd_hda_codec_write_cache(codec, nid, 0,
4a79ba34
TI
1549 AC_VERB_SET_UNSOLICITED_ENABLE,
1550 AC_USRSP_EN | ALC880_HP_EVENT);
d922b51d
TI
1551 spec->automute = 1;
1552 spec->automute_mode = ALC_AUTOMUTE_PIN;
bb35febd 1553 }
1a1455de
TI
1554 if (spec->automute && cfg->line_out_pins[0] &&
1555 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1556 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1557 for (i = 0; i < cfg->line_outs; i++) {
1558 hda_nid_t nid = cfg->line_out_pins[i];
1559 if (!(snd_hda_query_pin_caps(codec, nid) &
1560 AC_PINCAP_PRES_DETECT))
1561 continue;
1562 snd_printdd("realtek: Enable Line-Out auto-muting "
1563 "on NID 0x%x\n", nid);
1564 snd_hda_codec_write_cache(codec, nid, 0,
1565 AC_VERB_SET_UNSOLICITED_ENABLE,
1566 AC_USRSP_EN | ALC880_FRONT_EVENT);
1567 spec->detect_line = 1;
1568 }
1569 /* create a control for automute mode */
1570 alc_add_automute_mode_enum(codec);
1571 spec->automute_lines = 1;
1572 }
4a79ba34
TI
1573 spec->unsol_event = alc_sku_unsol_event;
1574}
1575
6c819492
TI
1576static void alc_init_auto_mic(struct hda_codec *codec)
1577{
1578 struct alc_spec *spec = codec->spec;
1579 struct auto_pin_cfg *cfg = &spec->autocfg;
1580 hda_nid_t fixed, ext;
1581 int i;
1582
1583 /* there must be only two mic inputs exclusively */
66ceeb6b 1584 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1585 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1586 return;
1587
1588 fixed = ext = 0;
66ceeb6b
TI
1589 for (i = 0; i < cfg->num_inputs; i++) {
1590 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1591 unsigned int defcfg;
6c819492 1592 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1593 switch (snd_hda_get_input_pin_attr(defcfg)) {
1594 case INPUT_PIN_ATTR_INT:
6c819492
TI
1595 if (fixed)
1596 return; /* already occupied */
1597 fixed = nid;
1598 break;
99ae28be
TI
1599 case INPUT_PIN_ATTR_UNUSED:
1600 return; /* invalid entry */
1601 default:
6c819492
TI
1602 if (ext)
1603 return; /* already occupied */
1604 ext = nid;
1605 break;
6c819492
TI
1606 }
1607 }
eaa9b3a7
TI
1608 if (!ext || !fixed)
1609 return;
6c819492
TI
1610 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1611 return; /* no unsol support */
1612 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1613 ext, fixed);
1614 spec->ext_mic.pin = ext;
1615 spec->int_mic.pin = fixed;
1616 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1617 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1618 spec->auto_mic = 1;
1619 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1620 AC_VERB_SET_UNSOLICITED_ENABLE,
1621 AC_USRSP_EN | ALC880_MIC_EVENT);
1622 spec->unsol_event = alc_sku_unsol_event;
1623}
1624
90622917
DH
1625/* Could be any non-zero and even value. When used as fixup, tells
1626 * the driver to ignore any present sku defines.
1627 */
1628#define ALC_FIXUP_SKU_IGNORE (2)
1629
da00c244
KY
1630static int alc_auto_parse_customize_define(struct hda_codec *codec)
1631{
1632 unsigned int ass, tmp, i;
7fb56223 1633 unsigned nid = 0;
da00c244
KY
1634 struct alc_spec *spec = codec->spec;
1635
b6cbe517
TI
1636 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1637
90622917
DH
1638 if (spec->cdefine.fixup) {
1639 ass = spec->cdefine.sku_cfg;
1640 if (ass == ALC_FIXUP_SKU_IGNORE)
1641 return -1;
1642 goto do_sku;
1643 }
1644
da00c244 1645 ass = codec->subsystem_id & 0xffff;
b6cbe517 1646 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1647 goto do_sku;
1648
1649 nid = 0x1d;
1650 if (codec->vendor_id == 0x10ec0260)
1651 nid = 0x17;
1652 ass = snd_hda_codec_get_pincfg(codec, nid);
1653
1654 if (!(ass & 1)) {
1655 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1656 codec->chip_name, ass);
1657 return -1;
1658 }
1659
1660 /* check sum */
1661 tmp = 0;
1662 for (i = 1; i < 16; i++) {
1663 if ((ass >> i) & 1)
1664 tmp++;
1665 }
1666 if (((ass >> 16) & 0xf) != tmp)
1667 return -1;
1668
1669 spec->cdefine.port_connectivity = ass >> 30;
1670 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1671 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1672 spec->cdefine.customization = ass >> 8;
1673do_sku:
1674 spec->cdefine.sku_cfg = ass;
1675 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1676 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1677 spec->cdefine.swap = (ass & 0x2) >> 1;
1678 spec->cdefine.override = ass & 0x1;
1679
1680 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1681 nid, spec->cdefine.sku_cfg);
1682 snd_printd("SKU: port_connectivity=0x%x\n",
1683 spec->cdefine.port_connectivity);
1684 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1685 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1686 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1687 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1688 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1689 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1690 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1691
1692 return 0;
1693}
1694
4a79ba34
TI
1695/* check subsystem ID and set up device-specific initialization;
1696 * return 1 if initialized, 0 if invalid SSID
1697 */
1698/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1699 * 31 ~ 16 : Manufacture ID
1700 * 15 ~ 8 : SKU ID
1701 * 7 ~ 0 : Assembly ID
1702 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1703 */
1704static int alc_subsystem_id(struct hda_codec *codec,
1705 hda_nid_t porta, hda_nid_t porte,
6227cdce 1706 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1707{
1708 unsigned int ass, tmp, i;
1709 unsigned nid;
1710 struct alc_spec *spec = codec->spec;
1711
90622917
DH
1712 if (spec->cdefine.fixup) {
1713 ass = spec->cdefine.sku_cfg;
1714 if (ass == ALC_FIXUP_SKU_IGNORE)
1715 return 0;
1716 goto do_sku;
1717 }
1718
4a79ba34
TI
1719 ass = codec->subsystem_id & 0xffff;
1720 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1721 goto do_sku;
1722
1723 /* invalid SSID, check the special NID pin defcfg instead */
1724 /*
def319f9 1725 * 31~30 : port connectivity
4a79ba34
TI
1726 * 29~21 : reserve
1727 * 20 : PCBEEP input
1728 * 19~16 : Check sum (15:1)
1729 * 15~1 : Custom
1730 * 0 : override
1731 */
1732 nid = 0x1d;
1733 if (codec->vendor_id == 0x10ec0260)
1734 nid = 0x17;
1735 ass = snd_hda_codec_get_pincfg(codec, nid);
1736 snd_printd("realtek: No valid SSID, "
1737 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1738 ass, nid);
6227cdce 1739 if (!(ass & 1))
4a79ba34
TI
1740 return 0;
1741 if ((ass >> 30) != 1) /* no physical connection */
1742 return 0;
1743
1744 /* check sum */
1745 tmp = 0;
1746 for (i = 1; i < 16; i++) {
1747 if ((ass >> i) & 1)
1748 tmp++;
1749 }
1750 if (((ass >> 16) & 0xf) != tmp)
1751 return 0;
1752do_sku:
1753 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1754 ass & 0xffff, codec->vendor_id);
1755 /*
1756 * 0 : override
1757 * 1 : Swap Jack
1758 * 2 : 0 --> Desktop, 1 --> Laptop
1759 * 3~5 : External Amplifier control
1760 * 7~6 : Reserved
1761 */
1762 tmp = (ass & 0x38) >> 3; /* external Amp control */
1763 switch (tmp) {
1764 case 1:
1765 spec->init_amp = ALC_INIT_GPIO1;
1766 break;
1767 case 3:
1768 spec->init_amp = ALC_INIT_GPIO2;
1769 break;
1770 case 7:
1771 spec->init_amp = ALC_INIT_GPIO3;
1772 break;
1773 case 5:
5a8cfb4e 1774 default:
4a79ba34 1775 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1776 break;
1777 }
ea1fb29a 1778
8c427226 1779 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1780 * when the external headphone out jack is plugged"
1781 */
8c427226 1782 if (!(ass & 0x8000))
4a79ba34 1783 return 1;
c9b58006
KY
1784 /*
1785 * 10~8 : Jack location
1786 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1787 * 14~13: Resvered
1788 * 15 : 1 --> enable the function "Mute internal speaker
1789 * when the external headphone out jack is plugged"
1790 */
c9b58006 1791 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1792 hda_nid_t nid;
c9b58006
KY
1793 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1794 if (tmp == 0)
01d4825d 1795 nid = porta;
c9b58006 1796 else if (tmp == 1)
01d4825d 1797 nid = porte;
c9b58006 1798 else if (tmp == 2)
01d4825d 1799 nid = portd;
6227cdce
KY
1800 else if (tmp == 3)
1801 nid = porti;
c9b58006 1802 else
4a79ba34 1803 return 1;
01d4825d
TI
1804 for (i = 0; i < spec->autocfg.line_outs; i++)
1805 if (spec->autocfg.line_out_pins[i] == nid)
1806 return 1;
1807 spec->autocfg.hp_pins[0] = nid;
c9b58006 1808 }
4a79ba34
TI
1809 return 1;
1810}
ea1fb29a 1811
4a79ba34 1812static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1813 hda_nid_t porta, hda_nid_t porte,
1814 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1815{
6227cdce 1816 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1817 struct alc_spec *spec = codec->spec;
1818 snd_printd("realtek: "
1819 "Enable default setup for auto mode as fallback\n");
1820 spec->init_amp = ALC_INIT_DEFAULT;
4a79ba34 1821 }
1a1455de
TI
1822
1823 alc_init_auto_hp(codec);
1824 alc_init_auto_mic(codec);
bc9f98a9
KY
1825}
1826
f95474ec 1827/*
f8f25ba3 1828 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1829 */
1830
1831struct alc_pincfg {
1832 hda_nid_t nid;
1833 u32 val;
1834};
1835
e1eb5f10
TB
1836struct alc_model_fixup {
1837 const int id;
1838 const char *name;
1839};
1840
f8f25ba3 1841struct alc_fixup {
b5bfbc67 1842 int type;
361fe6e9
TI
1843 bool chained;
1844 int chain_id;
b5bfbc67
TI
1845 union {
1846 unsigned int sku;
1847 const struct alc_pincfg *pins;
1848 const struct hda_verb *verbs;
1849 void (*func)(struct hda_codec *codec,
1850 const struct alc_fixup *fix,
1851 int action);
1852 } v;
f8f25ba3
TI
1853};
1854
b5bfbc67
TI
1855enum {
1856 ALC_FIXUP_INVALID,
1857 ALC_FIXUP_SKU,
1858 ALC_FIXUP_PINS,
1859 ALC_FIXUP_VERBS,
1860 ALC_FIXUP_FUNC,
1861};
1862
1863enum {
1864 ALC_FIXUP_ACT_PRE_PROBE,
1865 ALC_FIXUP_ACT_PROBE,
58701120 1866 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1867};
1868
1869static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1870{
b5bfbc67
TI
1871 struct alc_spec *spec = codec->spec;
1872 int id = spec->fixup_id;
aa1d0c52 1873#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1874 const char *modelname = spec->fixup_name;
aa1d0c52 1875#endif
b5bfbc67 1876 int depth = 0;
f95474ec 1877
b5bfbc67
TI
1878 if (!spec->fixup_list)
1879 return;
1880
1881 while (id >= 0) {
1882 const struct alc_fixup *fix = spec->fixup_list + id;
1883 const struct alc_pincfg *cfg;
1884
1885 switch (fix->type) {
1886 case ALC_FIXUP_SKU:
1887 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1888 break;;
1889 snd_printdd(KERN_INFO "hda_codec: %s: "
1890 "Apply sku override for %s\n",
1891 codec->chip_name, modelname);
1892 spec->cdefine.sku_cfg = fix->v.sku;
1893 spec->cdefine.fixup = 1;
1894 break;
1895 case ALC_FIXUP_PINS:
1896 cfg = fix->v.pins;
1897 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1898 break;
1899 snd_printdd(KERN_INFO "hda_codec: %s: "
1900 "Apply pincfg for %s\n",
1901 codec->chip_name, modelname);
1902 for (; cfg->nid; cfg++)
1903 snd_hda_codec_set_pincfg(codec, cfg->nid,
1904 cfg->val);
1905 break;
1906 case ALC_FIXUP_VERBS:
1907 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1908 break;
1909 snd_printdd(KERN_INFO "hda_codec: %s: "
1910 "Apply fix-verbs for %s\n",
1911 codec->chip_name, modelname);
1912 add_verb(codec->spec, fix->v.verbs);
1913 break;
1914 case ALC_FIXUP_FUNC:
1915 if (!fix->v.func)
1916 break;
1917 snd_printdd(KERN_INFO "hda_codec: %s: "
1918 "Apply fix-func for %s\n",
1919 codec->chip_name, modelname);
1920 fix->v.func(codec, fix, action);
1921 break;
1922 default:
1923 snd_printk(KERN_ERR "hda_codec: %s: "
1924 "Invalid fixup type %d\n",
1925 codec->chip_name, fix->type);
1926 break;
1927 }
1928 if (!fix[id].chained)
1929 break;
1930 if (++depth > 10)
1931 break;
1932 id = fix[id].chain_id;
9d57883f 1933 }
f95474ec
TI
1934}
1935
e1eb5f10 1936static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1937 const struct alc_model_fixup *models,
1938 const struct snd_pci_quirk *quirk,
1939 const struct alc_fixup *fixlist)
e1eb5f10 1940{
b5bfbc67
TI
1941 struct alc_spec *spec = codec->spec;
1942 int id = -1;
1943 const char *name = NULL;
e1eb5f10 1944
e1eb5f10
TB
1945 if (codec->modelname && models) {
1946 while (models->name) {
1947 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
1948 id = models->id;
1949 name = models->name;
e1eb5f10
TB
1950 break;
1951 }
1952 models++;
1953 }
b5bfbc67
TI
1954 }
1955 if (id < 0) {
1956 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1957 if (quirk) {
1958 id = quirk->value;
1959#ifdef CONFIG_SND_DEBUG_VERBOSE
1960 name = quirk->name;
1961#endif
1962 }
1963 }
1964
1965 spec->fixup_id = id;
1966 if (id >= 0) {
1967 spec->fixup_list = fixlist;
1968 spec->fixup_name = name;
e1eb5f10 1969 }
f95474ec
TI
1970}
1971
274693f3
KY
1972static int alc_read_coef_idx(struct hda_codec *codec,
1973 unsigned int coef_idx)
1974{
1975 unsigned int val;
1976 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1977 coef_idx);
1978 val = snd_hda_codec_read(codec, 0x20, 0,
1979 AC_VERB_GET_PROC_COEF, 0);
1980 return val;
1981}
1982
977ddd6b
KY
1983static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1984 unsigned int coef_val)
1985{
1986 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1987 coef_idx);
1988 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1989 coef_val);
1990}
1991
757899ac
TI
1992/* set right pin controls for digital I/O */
1993static void alc_auto_init_digital(struct hda_codec *codec)
1994{
1995 struct alc_spec *spec = codec->spec;
1996 int i;
1997 hda_nid_t pin;
1998
1999 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2000 pin = spec->autocfg.dig_out_pins[i];
2001 if (pin) {
2002 snd_hda_codec_write(codec, pin, 0,
2003 AC_VERB_SET_PIN_WIDGET_CONTROL,
2004 PIN_OUT);
2005 }
2006 }
2007 pin = spec->autocfg.dig_in_pin;
2008 if (pin)
2009 snd_hda_codec_write(codec, pin, 0,
2010 AC_VERB_SET_PIN_WIDGET_CONTROL,
2011 PIN_IN);
2012}
2013
2014/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2015static void alc_auto_parse_digital(struct hda_codec *codec)
2016{
2017 struct alc_spec *spec = codec->spec;
2018 int i, err;
2019 hda_nid_t dig_nid;
2020
2021 /* support multiple SPDIFs; the secondary is set up as a slave */
2022 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2023 err = snd_hda_get_connections(codec,
2024 spec->autocfg.dig_out_pins[i],
2025 &dig_nid, 1);
2026 if (err < 0)
2027 continue;
2028 if (!i) {
2029 spec->multiout.dig_out_nid = dig_nid;
2030 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2031 } else {
2032 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2033 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2034 break;
2035 spec->slave_dig_outs[i - 1] = dig_nid;
2036 }
2037 }
2038
2039 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
2040 dig_nid = codec->start_nid;
2041 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2042 unsigned int wcaps = get_wcaps(codec, dig_nid);
2043 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2044 continue;
2045 if (!(wcaps & AC_WCAP_DIGITAL))
2046 continue;
2047 if (!(wcaps & AC_WCAP_CONN_LIST))
2048 continue;
2049 err = get_connection_index(codec, dig_nid,
2050 spec->autocfg.dig_in_pin);
2051 if (err >= 0) {
2052 spec->dig_in_nid = dig_nid;
2053 break;
2054 }
2055 }
757899ac
TI
2056 }
2057}
2058
ef8ef5fb
VP
2059/*
2060 * ALC888
2061 */
2062
2063/*
2064 * 2ch mode
2065 */
2066static struct hda_verb alc888_4ST_ch2_intel_init[] = {
2067/* Mic-in jack as mic in */
2068 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2069 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2070/* Line-in jack as Line in */
2071 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2072 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2073/* Line-Out as Front */
2074 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2075 { } /* end */
2076};
2077
2078/*
2079 * 4ch mode
2080 */
2081static struct hda_verb alc888_4ST_ch4_intel_init[] = {
2082/* Mic-in jack as mic in */
2083 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2084 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2085/* Line-in jack as Surround */
2086 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2087 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2088/* Line-Out as Front */
2089 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2090 { } /* end */
2091};
2092
2093/*
2094 * 6ch mode
2095 */
2096static struct hda_verb alc888_4ST_ch6_intel_init[] = {
2097/* Mic-in jack as CLFE */
2098 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2099 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2100/* Line-in jack as Surround */
2101 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2102 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2103/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2104 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2105 { } /* end */
2106};
2107
2108/*
2109 * 8ch mode
2110 */
2111static struct hda_verb alc888_4ST_ch8_intel_init[] = {
2112/* Mic-in jack as CLFE */
2113 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2114 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2115/* Line-in jack as Surround */
2116 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2117 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2118/* Line-Out as Side */
2119 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2120 { } /* end */
2121};
2122
2123static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2124 { 2, alc888_4ST_ch2_intel_init },
2125 { 4, alc888_4ST_ch4_intel_init },
2126 { 6, alc888_4ST_ch6_intel_init },
2127 { 8, alc888_4ST_ch8_intel_init },
2128};
2129
2130/*
2131 * ALC888 Fujitsu Siemens Amillo xa3530
2132 */
2133
2134static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2135/* Front Mic: set to PIN_IN (empty by default) */
2136 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2137/* Connect Internal HP to Front */
2138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2140 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2141/* Connect Bass HP to Front */
2142 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2143 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2144 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2145/* Connect Line-Out side jack (SPDIF) to Side */
2146 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2147 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2148 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2149/* Connect Mic jack to CLFE */
2150 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2151 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2152 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2153/* Connect Line-in jack to Surround */
2154 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2155 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2156 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2157/* Connect HP out jack to Front */
2158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2159 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2160 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2161/* Enable unsolicited event for HP jack and Line-out jack */
2162 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2163 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2164 {}
2165};
2166
4f5d1706 2167static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
2168{
2169 struct alc_spec *spec = codec->spec;
2170
2171 spec->autocfg.hp_pins[0] = 0x15;
2172 spec->autocfg.speaker_pins[0] = 0x14;
2173 spec->autocfg.speaker_pins[1] = 0x16;
2174 spec->autocfg.speaker_pins[2] = 0x17;
2175 spec->autocfg.speaker_pins[3] = 0x19;
2176 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
2177 spec->automute = 1;
2178 spec->automute_mode = ALC_AUTOMUTE_AMP;
6732bd0d
WF
2179}
2180
2181static void alc889_intel_init_hook(struct hda_codec *codec)
2182{
2183 alc889_coef_init(codec);
d922b51d 2184 alc_hp_automute(codec);
6732bd0d
WF
2185}
2186
4f5d1706 2187static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2188{
2189 struct alc_spec *spec = codec->spec;
2190
2191 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2192 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2193 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2194 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
d922b51d
TI
2195 spec->automute = 1;
2196 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f 2197}
ef8ef5fb 2198
5b2d1eca
VP
2199/*
2200 * ALC888 Acer Aspire 4930G model
2201 */
2202
2203static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2204/* Front Mic: set to PIN_IN (empty by default) */
2205 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2206/* Unselect Front Mic by default in input mixer 3 */
2207 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2208/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2209 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2210/* Connect Internal HP to front */
2211 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2212 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2213 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2214/* Connect HP out to front */
2215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2216 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2217 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2218 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2219 { }
2220};
2221
d2fd4b09
TV
2222/*
2223 * ALC888 Acer Aspire 6530G model
2224 */
2225
2226static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2227/* Route to built-in subwoofer as well as speakers */
2228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2229 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2230 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2231 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2232/* Bias voltage on for external mic port */
2233 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2234/* Front Mic: set to PIN_IN (empty by default) */
2235 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2236/* Unselect Front Mic by default in input mixer 3 */
2237 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2238/* Enable unsolicited event for HP jack */
2239 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2240/* Enable speaker output */
2241 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2242 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2243 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2244/* Enable headphone output */
2245 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2246 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2247 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2248 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2249 { }
2250};
2251
d9477207
DK
2252/*
2253 *ALC888 Acer Aspire 7730G model
2254 */
2255
2256static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2257/* Bias voltage on for external mic port */
2258 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2259/* Front Mic: set to PIN_IN (empty by default) */
2260 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2261/* Unselect Front Mic by default in input mixer 3 */
2262 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2263/* Enable unsolicited event for HP jack */
2264 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2265/* Enable speaker output */
2266 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2267 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2268 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2269/* Enable headphone output */
2270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2272 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2273 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2274/*Enable internal subwoofer */
2275 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2276 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2277 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2278 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2279 { }
2280};
2281
3b315d70 2282/*
018df418 2283 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2284 */
2285
018df418 2286static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2287/* Front Mic: set to PIN_IN (empty by default) */
2288 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2289/* Unselect Front Mic by default in input mixer 3 */
2290 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2291/* Enable unsolicited event for HP jack */
2292 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2293/* Connect Internal Front to Front */
2294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2295 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2296 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2297/* Connect Internal Rear to Rear */
2298 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2299 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2300 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2301/* Connect Internal CLFE to CLFE */
2302 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2303 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2304 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2305/* Connect HP out to Front */
018df418 2306 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2307 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2308 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2309/* Enable all DACs */
2310/* DAC DISABLE/MUTE 1? */
2311/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2312 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2313 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2314/* DAC DISABLE/MUTE 2? */
2315/* some bit here disables the other DACs. Init=0x4900 */
2316 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2317 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2318/* DMIC fix
2319 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2320 * which makes the stereo useless. However, either the mic or the ALC889
2321 * makes the signal become a difference/sum signal instead of standard
2322 * stereo, which is annoying. So instead we flip this bit which makes the
2323 * codec replicate the sum signal to both channels, turning it into a
2324 * normal mono mic.
2325 */
2326/* DMIC_CONTROL? Init value = 0x0001 */
2327 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2328 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2329 { }
2330};
2331
ef8ef5fb 2332static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2333 /* Front mic only available on one ADC */
2334 {
2335 .num_items = 4,
2336 .items = {
2337 { "Mic", 0x0 },
2338 { "Line", 0x2 },
2339 { "CD", 0x4 },
2340 { "Front Mic", 0xb },
2341 },
2342 },
2343 {
2344 .num_items = 3,
2345 .items = {
2346 { "Mic", 0x0 },
2347 { "Line", 0x2 },
2348 { "CD", 0x4 },
2349 },
2350 }
2351};
2352
d2fd4b09
TV
2353static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2354 /* Interal mic only available on one ADC */
2355 {
684a8842 2356 .num_items = 5,
d2fd4b09 2357 .items = {
8607f7c4 2358 { "Mic", 0x0 },
684a8842 2359 { "Line In", 0x2 },
d2fd4b09 2360 { "CD", 0x4 },
684a8842 2361 { "Input Mix", 0xa },
28c4edb7 2362 { "Internal Mic", 0xb },
d2fd4b09
TV
2363 },
2364 },
2365 {
684a8842 2366 .num_items = 4,
d2fd4b09 2367 .items = {
8607f7c4 2368 { "Mic", 0x0 },
684a8842 2369 { "Line In", 0x2 },
d2fd4b09 2370 { "CD", 0x4 },
684a8842 2371 { "Input Mix", 0xa },
d2fd4b09
TV
2372 },
2373 }
2374};
2375
018df418
HM
2376static struct hda_input_mux alc889_capture_sources[3] = {
2377 /* Digital mic only available on first "ADC" */
2378 {
2379 .num_items = 5,
2380 .items = {
2381 { "Mic", 0x0 },
2382 { "Line", 0x2 },
2383 { "CD", 0x4 },
2384 { "Front Mic", 0xb },
2385 { "Input Mix", 0xa },
2386 },
2387 },
2388 {
2389 .num_items = 4,
2390 .items = {
2391 { "Mic", 0x0 },
2392 { "Line", 0x2 },
2393 { "CD", 0x4 },
2394 { "Input Mix", 0xa },
2395 },
2396 },
2397 {
2398 .num_items = 4,
2399 .items = {
2400 { "Mic", 0x0 },
2401 { "Line", 0x2 },
2402 { "CD", 0x4 },
2403 { "Input Mix", 0xa },
2404 },
2405 }
2406};
2407
ef8ef5fb 2408static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2409 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2410 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2411 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2412 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2413 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2414 HDA_OUTPUT),
2415 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2416 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2417 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2418 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2419 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2420 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2421 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2422 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2423 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2425 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2427 { } /* end */
2428};
2429
460c92fa
ŁW
2430static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2431 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2432 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2433 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2434 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2435 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2436 HDA_OUTPUT),
786c51f9
ŁW
2437 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2438 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2439 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2440 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2441 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2444 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2445 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2447 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2448 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2449 { } /* end */
2450};
2451
556eea9a
HM
2452static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2453 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2454 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2455 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2456 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2457 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2458 HDA_OUTPUT),
2459 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2460 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2461 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2462 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2463 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2465 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2467 { } /* end */
2468};
2469
2470
4f5d1706 2471static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2472{
a9fd4f3f 2473 struct alc_spec *spec = codec->spec;
5b2d1eca 2474
a9fd4f3f
TI
2475 spec->autocfg.hp_pins[0] = 0x15;
2476 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2477 spec->autocfg.speaker_pins[1] = 0x16;
2478 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2479 spec->automute = 1;
2480 spec->automute_mode = ALC_AUTOMUTE_AMP;
5b2d1eca
VP
2481}
2482
4f5d1706 2483static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2484{
2485 struct alc_spec *spec = codec->spec;
2486
2487 spec->autocfg.hp_pins[0] = 0x15;
2488 spec->autocfg.speaker_pins[0] = 0x14;
2489 spec->autocfg.speaker_pins[1] = 0x16;
2490 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2491 spec->automute = 1;
2492 spec->automute_mode = ALC_AUTOMUTE_AMP;
320d5920
EL
2493}
2494
d9477207
DK
2495static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2496{
2497 struct alc_spec *spec = codec->spec;
2498
2499 spec->autocfg.hp_pins[0] = 0x15;
2500 spec->autocfg.speaker_pins[0] = 0x14;
2501 spec->autocfg.speaker_pins[1] = 0x16;
2502 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2503 spec->automute = 1;
2504 spec->automute_mode = ALC_AUTOMUTE_AMP;
d9477207
DK
2505}
2506
4f5d1706 2507static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2508{
2509 struct alc_spec *spec = codec->spec;
2510
2511 spec->autocfg.hp_pins[0] = 0x15;
2512 spec->autocfg.speaker_pins[0] = 0x14;
2513 spec->autocfg.speaker_pins[1] = 0x16;
2514 spec->autocfg.speaker_pins[2] = 0x1b;
d922b51d
TI
2515 spec->automute = 1;
2516 spec->automute_mode = ALC_AUTOMUTE_AMP;
3b315d70
HM
2517}
2518
1da177e4 2519/*
e9edcee0
TI
2520 * ALC880 3-stack model
2521 *
2522 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2523 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2524 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2525 */
2526
e9edcee0
TI
2527static hda_nid_t alc880_dac_nids[4] = {
2528 /* front, rear, clfe, rear_surr */
2529 0x02, 0x05, 0x04, 0x03
2530};
2531
2532static hda_nid_t alc880_adc_nids[3] = {
2533 /* ADC0-2 */
2534 0x07, 0x08, 0x09,
2535};
2536
2537/* The datasheet says the node 0x07 is connected from inputs,
2538 * but it shows zero connection in the real implementation on some devices.
df694daa 2539 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2540 */
e9edcee0
TI
2541static hda_nid_t alc880_adc_nids_alt[2] = {
2542 /* ADC1-2 */
2543 0x08, 0x09,
2544};
2545
2546#define ALC880_DIGOUT_NID 0x06
2547#define ALC880_DIGIN_NID 0x0a
2548
2549static struct hda_input_mux alc880_capture_source = {
2550 .num_items = 4,
2551 .items = {
2552 { "Mic", 0x0 },
2553 { "Front Mic", 0x3 },
2554 { "Line", 0x2 },
2555 { "CD", 0x4 },
2556 },
2557};
2558
2559/* channel source setting (2/6 channel selection for 3-stack) */
2560/* 2ch mode */
2561static struct hda_verb alc880_threestack_ch2_init[] = {
2562 /* set line-in to input, mute it */
2563 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2564 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2565 /* set mic-in to input vref 80%, mute it */
2566 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2567 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2568 { } /* end */
2569};
2570
2571/* 6ch mode */
2572static struct hda_verb alc880_threestack_ch6_init[] = {
2573 /* set line-in to output, unmute it */
2574 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2575 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2576 /* set mic-in to output, unmute it */
2577 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2578 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2579 { } /* end */
2580};
2581
d2a6d7dc 2582static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2583 { 2, alc880_threestack_ch2_init },
2584 { 6, alc880_threestack_ch6_init },
2585};
2586
c8b6bf9b 2587static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2588 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2589 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2590 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2591 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2592 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2593 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2594 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2595 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2596 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2597 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2598 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2599 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2602 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2603 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2604 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2605 {
2606 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2607 .name = "Channel Mode",
df694daa
KY
2608 .info = alc_ch_mode_info,
2609 .get = alc_ch_mode_get,
2610 .put = alc_ch_mode_put,
e9edcee0
TI
2611 },
2612 { } /* end */
2613};
2614
2615/* capture mixer elements */
f9e336f6
TI
2616static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2617 struct snd_ctl_elem_info *uinfo)
2618{
2619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2620 struct alc_spec *spec = codec->spec;
2621 int err;
1da177e4 2622
5a9e02e9 2623 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2624 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2625 HDA_INPUT);
2626 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2627 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2628 return err;
2629}
2630
2631static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2632 unsigned int size, unsigned int __user *tlv)
2633{
2634 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2635 struct alc_spec *spec = codec->spec;
2636 int err;
1da177e4 2637
5a9e02e9 2638 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2639 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2640 HDA_INPUT);
2641 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2642 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2643 return err;
2644}
2645
2646typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2647 struct snd_ctl_elem_value *ucontrol);
2648
2649static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2650 struct snd_ctl_elem_value *ucontrol,
2651 getput_call_t func)
2652{
2653 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2654 struct alc_spec *spec = codec->spec;
2655 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2656 int err;
2657
5a9e02e9 2658 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2659 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2660 3, 0, HDA_INPUT);
2661 err = func(kcontrol, ucontrol);
5a9e02e9 2662 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2663 return err;
2664}
2665
2666static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2667 struct snd_ctl_elem_value *ucontrol)
2668{
2669 return alc_cap_getput_caller(kcontrol, ucontrol,
2670 snd_hda_mixer_amp_volume_get);
2671}
2672
2673static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2674 struct snd_ctl_elem_value *ucontrol)
2675{
2676 return alc_cap_getput_caller(kcontrol, ucontrol,
2677 snd_hda_mixer_amp_volume_put);
2678}
2679
2680/* capture mixer elements */
2681#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2682
2683static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2684 struct snd_ctl_elem_value *ucontrol)
2685{
2686 return alc_cap_getput_caller(kcontrol, ucontrol,
2687 snd_hda_mixer_amp_switch_get);
2688}
2689
2690static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2691 struct snd_ctl_elem_value *ucontrol)
2692{
2693 return alc_cap_getput_caller(kcontrol, ucontrol,
2694 snd_hda_mixer_amp_switch_put);
2695}
2696
a23b688f 2697#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2698 { \
2699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2700 .name = "Capture Switch", \
2701 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2702 .count = num, \
2703 .info = alc_cap_sw_info, \
2704 .get = alc_cap_sw_get, \
2705 .put = alc_cap_sw_put, \
2706 }, \
2707 { \
2708 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2709 .name = "Capture Volume", \
2710 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2711 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2712 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2713 .count = num, \
2714 .info = alc_cap_vol_info, \
2715 .get = alc_cap_vol_get, \
2716 .put = alc_cap_vol_put, \
2717 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2718 }
2719
2720#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2721 { \
2722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2723 /* .name = "Capture Source", */ \
2724 .name = "Input Source", \
2725 .count = num, \
2726 .info = alc_mux_enum_info, \
2727 .get = alc_mux_enum_get, \
2728 .put = alc_mux_enum_put, \
a23b688f
TI
2729 }
2730
2731#define DEFINE_CAPMIX(num) \
2732static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2733 _DEFINE_CAPMIX(num), \
2734 _DEFINE_CAPSRC(num), \
2735 { } /* end */ \
2736}
2737
2738#define DEFINE_CAPMIX_NOSRC(num) \
2739static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2740 _DEFINE_CAPMIX(num), \
2741 { } /* end */ \
f9e336f6
TI
2742}
2743
2744/* up to three ADCs */
2745DEFINE_CAPMIX(1);
2746DEFINE_CAPMIX(2);
2747DEFINE_CAPMIX(3);
a23b688f
TI
2748DEFINE_CAPMIX_NOSRC(1);
2749DEFINE_CAPMIX_NOSRC(2);
2750DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2751
2752/*
2753 * ALC880 5-stack model
2754 *
9c7f852e
TI
2755 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2756 * Side = 0x02 (0xd)
e9edcee0
TI
2757 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2758 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2759 */
2760
2761/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2762static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2763 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2764 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2765 { } /* end */
2766};
2767
e9edcee0
TI
2768/* channel source setting (6/8 channel selection for 5-stack) */
2769/* 6ch mode */
2770static struct hda_verb alc880_fivestack_ch6_init[] = {
2771 /* set line-in to input, mute it */
2772 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2773 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2774 { } /* end */
2775};
2776
e9edcee0
TI
2777/* 8ch mode */
2778static struct hda_verb alc880_fivestack_ch8_init[] = {
2779 /* set line-in to output, unmute it */
2780 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2781 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2782 { } /* end */
2783};
2784
d2a6d7dc 2785static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2786 { 6, alc880_fivestack_ch6_init },
2787 { 8, alc880_fivestack_ch8_init },
2788};
2789
2790
2791/*
2792 * ALC880 6-stack model
2793 *
9c7f852e
TI
2794 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2795 * Side = 0x05 (0x0f)
e9edcee0
TI
2796 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2797 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2798 */
2799
2800static hda_nid_t alc880_6st_dac_nids[4] = {
2801 /* front, rear, clfe, rear_surr */
2802 0x02, 0x03, 0x04, 0x05
f12ab1e0 2803};
e9edcee0
TI
2804
2805static struct hda_input_mux alc880_6stack_capture_source = {
2806 .num_items = 4,
2807 .items = {
2808 { "Mic", 0x0 },
2809 { "Front Mic", 0x1 },
2810 { "Line", 0x2 },
2811 { "CD", 0x4 },
2812 },
2813};
2814
2815/* fixed 8-channels */
d2a6d7dc 2816static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2817 { 8, NULL },
2818};
2819
c8b6bf9b 2820static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2821 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2822 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2823 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2824 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2825 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2826 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2827 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2828 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2829 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2830 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2831 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2832 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2833 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2834 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2835 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2836 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2837 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2838 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2839 {
2840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2841 .name = "Channel Mode",
df694daa
KY
2842 .info = alc_ch_mode_info,
2843 .get = alc_ch_mode_get,
2844 .put = alc_ch_mode_put,
16ded525
TI
2845 },
2846 { } /* end */
2847};
2848
e9edcee0
TI
2849
2850/*
2851 * ALC880 W810 model
2852 *
2853 * W810 has rear IO for:
2854 * Front (DAC 02)
2855 * Surround (DAC 03)
2856 * Center/LFE (DAC 04)
2857 * Digital out (06)
2858 *
2859 * The system also has a pair of internal speakers, and a headphone jack.
2860 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2861 *
e9edcee0
TI
2862 * There is a variable resistor to control the speaker or headphone
2863 * volume. This is a hardware-only device without a software API.
2864 *
2865 * Plugging headphones in will disable the internal speakers. This is
2866 * implemented in hardware, not via the driver using jack sense. In
2867 * a similar fashion, plugging into the rear socket marked "front" will
2868 * disable both the speakers and headphones.
2869 *
2870 * For input, there's a microphone jack, and an "audio in" jack.
2871 * These may not do anything useful with this driver yet, because I
2872 * haven't setup any initialization verbs for these yet...
2873 */
2874
2875static hda_nid_t alc880_w810_dac_nids[3] = {
2876 /* front, rear/surround, clfe */
2877 0x02, 0x03, 0x04
16ded525
TI
2878};
2879
e9edcee0 2880/* fixed 6 channels */
d2a6d7dc 2881static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2882 { 6, NULL }
2883};
2884
2885/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2886static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2888 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2889 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2890 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2891 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2892 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2893 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2894 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2895 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2896 { } /* end */
2897};
2898
2899
2900/*
2901 * Z710V model
2902 *
2903 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2904 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2905 * Line = 0x1a
e9edcee0
TI
2906 */
2907
2908static hda_nid_t alc880_z71v_dac_nids[1] = {
2909 0x02
2910};
2911#define ALC880_Z71V_HP_DAC 0x03
2912
2913/* fixed 2 channels */
d2a6d7dc 2914static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2915 { 2, NULL }
2916};
2917
c8b6bf9b 2918static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2919 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2920 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2921 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2922 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2923 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2924 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2925 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2926 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2927 { } /* end */
2928};
2929
e9edcee0 2930
e9edcee0
TI
2931/*
2932 * ALC880 F1734 model
2933 *
2934 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2935 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2936 */
2937
2938static hda_nid_t alc880_f1734_dac_nids[1] = {
2939 0x03
2940};
2941#define ALC880_F1734_HP_DAC 0x02
2942
c8b6bf9b 2943static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2944 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2945 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2946 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2947 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2948 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2949 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2950 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2951 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2952 { } /* end */
2953};
2954
937b4160
TI
2955static struct hda_input_mux alc880_f1734_capture_source = {
2956 .num_items = 2,
2957 .items = {
2958 { "Mic", 0x1 },
2959 { "CD", 0x4 },
2960 },
2961};
2962
e9edcee0 2963
e9edcee0
TI
2964/*
2965 * ALC880 ASUS model
2966 *
2967 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2968 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2969 * Mic = 0x18, Line = 0x1a
2970 */
2971
2972#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2973#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2974
c8b6bf9b 2975static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2976 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2977 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2978 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2979 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2980 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2981 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2982 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2983 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2984 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2985 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2986 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2987 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2988 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2989 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2990 {
2991 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2992 .name = "Channel Mode",
df694daa
KY
2993 .info = alc_ch_mode_info,
2994 .get = alc_ch_mode_get,
2995 .put = alc_ch_mode_put,
16ded525
TI
2996 },
2997 { } /* end */
2998};
e9edcee0 2999
e9edcee0
TI
3000/*
3001 * ALC880 ASUS W1V model
3002 *
3003 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3004 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3005 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3006 */
3007
3008/* additional mixers to alc880_asus_mixer */
c8b6bf9b 3009static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
3010 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3011 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3012 { } /* end */
3013};
3014
df694daa
KY
3015/* TCL S700 */
3016static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3017 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3018 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3019 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3020 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3021 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3022 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3023 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3024 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3025 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
3026 { } /* end */
3027};
3028
ccc656ce
KY
3029/* Uniwill */
3030static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
3031 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3032 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3033 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3034 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3035 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3036 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3037 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3038 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3039 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3040 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3041 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3042 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3045 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3046 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
3047 {
3048 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3049 .name = "Channel Mode",
3050 .info = alc_ch_mode_info,
3051 .get = alc_ch_mode_get,
3052 .put = alc_ch_mode_put,
3053 },
3054 { } /* end */
3055};
3056
2cf9f0fc
TD
3057static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3058 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3059 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3060 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3061 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3062 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3063 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
3064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3065 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
3066 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3067 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
3068 { } /* end */
3069};
3070
ccc656ce 3071static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
3072 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3073 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3074 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3075 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3077 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3078 { } /* end */
3079};
3080
2134ea4f
TI
3081/*
3082 * virtual master controls
3083 */
3084
3085/*
3086 * slave controls for virtual master
3087 */
ea734963 3088static const char * const alc_slave_vols[] = {
2134ea4f
TI
3089 "Front Playback Volume",
3090 "Surround Playback Volume",
3091 "Center Playback Volume",
3092 "LFE Playback Volume",
3093 "Side Playback Volume",
3094 "Headphone Playback Volume",
3095 "Speaker Playback Volume",
3096 "Mono Playback Volume",
2134ea4f 3097 "Line-Out Playback Volume",
26f5df26 3098 "PCM Playback Volume",
2134ea4f
TI
3099 NULL,
3100};
3101
ea734963 3102static const char * const alc_slave_sws[] = {
2134ea4f
TI
3103 "Front Playback Switch",
3104 "Surround Playback Switch",
3105 "Center Playback Switch",
3106 "LFE Playback Switch",
3107 "Side Playback Switch",
3108 "Headphone Playback Switch",
3109 "Speaker Playback Switch",
3110 "Mono Playback Switch",
edb54a55 3111 "IEC958 Playback Switch",
23033b2b
TI
3112 "Line-Out Playback Switch",
3113 "PCM Playback Switch",
2134ea4f
TI
3114 NULL,
3115};
3116
1da177e4 3117/*
e9edcee0 3118 * build control elements
1da177e4 3119 */
603c4019 3120
5b0cb1d8
JK
3121#define NID_MAPPING (-1)
3122
3123#define SUBDEV_SPEAKER_ (0 << 6)
3124#define SUBDEV_HP_ (1 << 6)
3125#define SUBDEV_LINE_ (2 << 6)
3126#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3127#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3128#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3129
603c4019
TI
3130static void alc_free_kctls(struct hda_codec *codec);
3131
67d634c0 3132#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3133/* additional beep mixers; the actual parameters are overwritten at build */
3134static struct snd_kcontrol_new alc_beep_mixer[] = {
3135 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 3136 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
3137 { } /* end */
3138};
67d634c0 3139#endif
45bdd1c1 3140
1da177e4
LT
3141static int alc_build_controls(struct hda_codec *codec)
3142{
3143 struct alc_spec *spec = codec->spec;
2f44f847 3144 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
3145 struct snd_kcontrol_new *knew;
3146 int i, j, err;
3147 unsigned int u;
3148 hda_nid_t nid;
1da177e4
LT
3149
3150 for (i = 0; i < spec->num_mixers; i++) {
3151 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3152 if (err < 0)
3153 return err;
3154 }
f9e336f6
TI
3155 if (spec->cap_mixer) {
3156 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3157 if (err < 0)
3158 return err;
3159 }
1da177e4 3160 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
3161 err = snd_hda_create_spdif_out_ctls(codec,
3162 spec->multiout.dig_out_nid);
1da177e4
LT
3163 if (err < 0)
3164 return err;
e64f14f4
TI
3165 if (!spec->no_analog) {
3166 err = snd_hda_create_spdif_share_sw(codec,
3167 &spec->multiout);
3168 if (err < 0)
3169 return err;
3170 spec->multiout.share_spdif = 1;
3171 }
1da177e4
LT
3172 }
3173 if (spec->dig_in_nid) {
3174 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3175 if (err < 0)
3176 return err;
3177 }
2134ea4f 3178
67d634c0 3179#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3180 /* create beep controls if needed */
3181 if (spec->beep_amp) {
3182 struct snd_kcontrol_new *knew;
3183 for (knew = alc_beep_mixer; knew->name; knew++) {
3184 struct snd_kcontrol *kctl;
3185 kctl = snd_ctl_new1(knew, codec);
3186 if (!kctl)
3187 return -ENOMEM;
3188 kctl->private_value = spec->beep_amp;
5e26dfd0 3189 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3190 if (err < 0)
3191 return err;
3192 }
3193 }
67d634c0 3194#endif
45bdd1c1 3195
2134ea4f 3196 /* if we have no master control, let's create it */
e64f14f4
TI
3197 if (!spec->no_analog &&
3198 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3199 unsigned int vmaster_tlv[4];
2134ea4f 3200 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3201 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3202 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3203 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3204 if (err < 0)
3205 return err;
3206 }
e64f14f4
TI
3207 if (!spec->no_analog &&
3208 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3209 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3210 NULL, alc_slave_sws);
3211 if (err < 0)
3212 return err;
3213 }
3214
5b0cb1d8 3215 /* assign Capture Source enums to NID */
fbe618f2
TI
3216 if (spec->capsrc_nids || spec->adc_nids) {
3217 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3218 if (!kctl)
3219 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3220 for (i = 0; kctl && i < kctl->count; i++) {
3221 hda_nid_t *nids = spec->capsrc_nids;
3222 if (!nids)
3223 nids = spec->adc_nids;
3224 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3225 if (err < 0)
3226 return err;
3227 }
5b0cb1d8
JK
3228 }
3229 if (spec->cap_mixer) {
3230 const char *kname = kctl ? kctl->id.name : NULL;
3231 for (knew = spec->cap_mixer; knew->name; knew++) {
3232 if (kname && strcmp(knew->name, kname) == 0)
3233 continue;
3234 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3235 for (i = 0; kctl && i < kctl->count; i++) {
3236 err = snd_hda_add_nid(codec, kctl, i,
3237 spec->adc_nids[i]);
3238 if (err < 0)
3239 return err;
3240 }
3241 }
3242 }
3243
3244 /* other nid->control mapping */
3245 for (i = 0; i < spec->num_mixers; i++) {
3246 for (knew = spec->mixers[i]; knew->name; knew++) {
3247 if (knew->iface != NID_MAPPING)
3248 continue;
3249 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3250 if (kctl == NULL)
3251 continue;
3252 u = knew->subdevice;
3253 for (j = 0; j < 4; j++, u >>= 8) {
3254 nid = u & 0x3f;
3255 if (nid == 0)
3256 continue;
3257 switch (u & 0xc0) {
3258 case SUBDEV_SPEAKER_:
3259 nid = spec->autocfg.speaker_pins[nid];
3260 break;
3261 case SUBDEV_LINE_:
3262 nid = spec->autocfg.line_out_pins[nid];
3263 break;
3264 case SUBDEV_HP_:
3265 nid = spec->autocfg.hp_pins[nid];
3266 break;
3267 default:
3268 continue;
3269 }
3270 err = snd_hda_add_nid(codec, kctl, 0, nid);
3271 if (err < 0)
3272 return err;
3273 }
3274 u = knew->private_value;
3275 for (j = 0; j < 4; j++, u >>= 8) {
3276 nid = u & 0xff;
3277 if (nid == 0)
3278 continue;
3279 err = snd_hda_add_nid(codec, kctl, 0, nid);
3280 if (err < 0)
3281 return err;
3282 }
3283 }
3284 }
bae84e70
TI
3285
3286 alc_free_kctls(codec); /* no longer needed */
3287
1da177e4
LT
3288 return 0;
3289}
3290
e9edcee0 3291
1da177e4
LT
3292/*
3293 * initialize the codec volumes, etc
3294 */
3295
e9edcee0
TI
3296/*
3297 * generic initialization of ADC, input mixers and output mixers
3298 */
3299static struct hda_verb alc880_volume_init_verbs[] = {
3300 /*
3301 * Unmute ADC0-2 and set the default input to mic-in
3302 */
71fe7b82 3303 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3304 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3305 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3306 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3307 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3308 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3309
e9edcee0
TI
3310 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3311 * mixer widget
9c7f852e
TI
3312 * Note: PASD motherboards uses the Line In 2 as the input for front
3313 * panel mic (mic 2)
1da177e4 3314 */
e9edcee0 3315 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3316 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3317 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3318 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3319 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3320 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3321 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3322 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3323
e9edcee0
TI
3324 /*
3325 * Set up output mixers (0x0c - 0x0f)
1da177e4 3326 */
e9edcee0
TI
3327 /* set vol=0 to output mixers */
3328 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3329 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3330 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3331 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3332 /* set up input amps for analog loopback */
3333 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3336 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3337 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3338 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3339 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3340 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3341 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3342
3343 { }
3344};
3345
e9edcee0
TI
3346/*
3347 * 3-stack pin configuration:
3348 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3349 */
3350static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3351 /*
3352 * preset connection lists of input pins
3353 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3354 */
3355 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3356 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3357 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3358
3359 /*
3360 * Set pin mode and muting
3361 */
3362 /* set front pin widgets 0x14 for output */
05acb863 3363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3365 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3366 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3367 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3368 /* Mic2 (as headphone out) for HP output */
3369 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3370 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3371 /* Line In pin widget for input */
05acb863 3372 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3373 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3374 /* Line2 (as front mic) pin widget for input and vref at 80% */
3375 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3376 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3377 /* CD pin widget for input */
05acb863 3378 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3379
e9edcee0
TI
3380 { }
3381};
1da177e4 3382
e9edcee0
TI
3383/*
3384 * 5-stack pin configuration:
3385 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3386 * line-in/side = 0x1a, f-mic = 0x1b
3387 */
3388static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3389 /*
3390 * preset connection lists of input pins
3391 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3392 */
e9edcee0
TI
3393 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3394 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3395
e9edcee0
TI
3396 /*
3397 * Set pin mode and muting
1da177e4 3398 */
e9edcee0
TI
3399 /* set pin widgets 0x14-0x17 for output */
3400 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3401 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3402 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3403 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3404 /* unmute pins for output (no gain on this amp) */
3405 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3406 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3407 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3408 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3409
3410 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3411 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3412 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3413 /* Mic2 (as headphone out) for HP output */
3414 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3415 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3416 /* Line In pin widget for input */
3417 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3418 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3419 /* Line2 (as front mic) pin widget for input and vref at 80% */
3420 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3421 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3422 /* CD pin widget for input */
3423 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3424
3425 { }
3426};
3427
e9edcee0
TI
3428/*
3429 * W810 pin configuration:
3430 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3431 */
3432static struct hda_verb alc880_pin_w810_init_verbs[] = {
3433 /* hphone/speaker input selector: front DAC */
3434 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3435
05acb863 3436 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3437 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3439 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3440 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3441 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3442
e9edcee0 3443 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3444 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3445
1da177e4
LT
3446 { }
3447};
3448
e9edcee0
TI
3449/*
3450 * Z71V pin configuration:
3451 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3452 */
3453static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3454 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3455 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3457 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3458
16ded525 3459 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3460 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3461 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3462 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3463
3464 { }
3465};
3466
e9edcee0
TI
3467/*
3468 * 6-stack pin configuration:
9c7f852e
TI
3469 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3470 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3471 */
3472static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3473 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3474
16ded525 3475 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3476 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3477 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3478 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3479 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3480 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3481 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3482 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3483
16ded525 3484 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3485 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3486 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3487 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3488 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3489 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3490 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3491 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3492 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3493
e9edcee0
TI
3494 { }
3495};
3496
ccc656ce
KY
3497/*
3498 * Uniwill pin configuration:
3499 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3500 * line = 0x1a
3501 */
3502static struct hda_verb alc880_uniwill_init_verbs[] = {
3503 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3504
3505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3506 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3507 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3508 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3509 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3510 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3511 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3512 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3514 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3515 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3516 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3518 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3519
3520 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3521 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3522 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3523 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3524 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3525 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3526 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3527 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3528 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3529
3530 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3531 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3532
3533 { }
3534};
3535
3536/*
3537* Uniwill P53
ea1fb29a 3538* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3539 */
3540static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3541 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3542
3543 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3544 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3545 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3547 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3548 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3549 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3551 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3552 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3553 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3554 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3555
3556 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3557 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3558 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3559 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3560 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3561 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3562
3563 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3564 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3565
3566 { }
3567};
3568
2cf9f0fc
TD
3569static struct hda_verb alc880_beep_init_verbs[] = {
3570 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3571 { }
3572};
3573
458a4fab 3574/* auto-toggle front mic */
eeb43387 3575static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3576{
3577 unsigned int present;
3578 unsigned char bits;
ccc656ce 3579
864f92be 3580 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3581 bits = present ? HDA_AMP_MUTE : 0;
3582 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3583}
3584
4f5d1706 3585static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3586{
a9fd4f3f
TI
3587 struct alc_spec *spec = codec->spec;
3588
3589 spec->autocfg.hp_pins[0] = 0x14;
3590 spec->autocfg.speaker_pins[0] = 0x15;
3591 spec->autocfg.speaker_pins[0] = 0x16;
d922b51d
TI
3592 spec->automute = 1;
3593 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
3594}
3595
3596static void alc880_uniwill_init_hook(struct hda_codec *codec)
3597{
d922b51d 3598 alc_hp_automute(codec);
eeb43387 3599 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3600}
3601
3602static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3603 unsigned int res)
3604{
3605 /* Looks like the unsol event is incompatible with the standard
3606 * definition. 4bit tag is placed at 28 bit!
3607 */
458a4fab 3608 switch (res >> 28) {
458a4fab 3609 case ALC880_MIC_EVENT:
eeb43387 3610 alc88x_simple_mic_automute(codec);
458a4fab 3611 break;
a9fd4f3f 3612 default:
d922b51d 3613 alc_sku_unsol_event(codec, res);
a9fd4f3f 3614 break;
458a4fab 3615 }
ccc656ce
KY
3616}
3617
4f5d1706 3618static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3619{
a9fd4f3f 3620 struct alc_spec *spec = codec->spec;
ccc656ce 3621
a9fd4f3f
TI
3622 spec->autocfg.hp_pins[0] = 0x14;
3623 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
3624 spec->automute = 1;
3625 spec->automute_mode = ALC_AUTOMUTE_AMP;
ccc656ce
KY
3626}
3627
3628static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3629{
3630 unsigned int present;
ea1fb29a 3631
ccc656ce 3632 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3633 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3634 present &= HDA_AMP_VOLMASK;
3635 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3636 HDA_AMP_VOLMASK, present);
3637 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3638 HDA_AMP_VOLMASK, present);
ccc656ce 3639}
47fd830a 3640
ccc656ce
KY
3641static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3642 unsigned int res)
3643{
3644 /* Looks like the unsol event is incompatible with the standard
3645 * definition. 4bit tag is placed at 28 bit!
3646 */
f12ab1e0 3647 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3648 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f 3649 else
d922b51d 3650 alc_sku_unsol_event(codec, res);
ccc656ce
KY
3651}
3652
e9edcee0
TI
3653/*
3654 * F1734 pin configuration:
3655 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3656 */
3657static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3658 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3659 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3660 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3661 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3662 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3663
e9edcee0 3664 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3665 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3666 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3667 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3668
e9edcee0
TI
3669 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3670 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3671 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3672 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3673 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3674 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3675 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3676 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3677 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3678
937b4160
TI
3679 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3680 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3681
dfc0ff62
TI
3682 { }
3683};
3684
e9edcee0
TI
3685/*
3686 * ASUS pin configuration:
3687 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3688 */
3689static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3690 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3691 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3692 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3693 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3694
3695 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3696 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3697 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3698 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3699 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3700 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3701 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3702 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3703
3704 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3705 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3706 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3707 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3708 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3709 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3710 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3711 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3712 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3713
e9edcee0
TI
3714 { }
3715};
16ded525 3716
e9edcee0 3717/* Enable GPIO mask and set output */
bc9f98a9
KY
3718#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3719#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3720#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3721
3722/* Clevo m520g init */
3723static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3724 /* headphone output */
3725 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3726 /* line-out */
3727 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3728 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3729 /* Line-in */
3730 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3731 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3732 /* CD */
3733 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3734 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3735 /* Mic1 (rear panel) */
3736 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3737 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3738 /* Mic2 (front panel) */
3739 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3740 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3741 /* headphone */
3742 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3743 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3744 /* change to EAPD mode */
3745 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3746 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3747
3748 { }
16ded525
TI
3749};
3750
df694daa 3751static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3752 /* change to EAPD mode */
3753 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3754 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3755
df694daa
KY
3756 /* Headphone output */
3757 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3758 /* Front output*/
3759 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3760 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3761
3762 /* Line In pin widget for input */
3763 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3764 /* CD pin widget for input */
3765 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3766 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3767 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3768
3769 /* change to EAPD mode */
3770 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3771 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3772
3773 { }
3774};
16ded525 3775
e9edcee0 3776/*
ae6b813a
TI
3777 * LG m1 express dual
3778 *
3779 * Pin assignment:
3780 * Rear Line-In/Out (blue): 0x14
3781 * Build-in Mic-In: 0x15
3782 * Speaker-out: 0x17
3783 * HP-Out (green): 0x1b
3784 * Mic-In/Out (red): 0x19
3785 * SPDIF-Out: 0x1e
3786 */
3787
3788/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3789static hda_nid_t alc880_lg_dac_nids[3] = {
3790 0x05, 0x02, 0x03
3791};
3792
3793/* seems analog CD is not working */
3794static struct hda_input_mux alc880_lg_capture_source = {
3795 .num_items = 3,
3796 .items = {
3797 { "Mic", 0x1 },
3798 { "Line", 0x5 },
3799 { "Internal Mic", 0x6 },
3800 },
3801};
3802
3803/* 2,4,6 channel modes */
3804static struct hda_verb alc880_lg_ch2_init[] = {
3805 /* set line-in and mic-in to input */
3806 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3807 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3808 { }
3809};
3810
3811static struct hda_verb alc880_lg_ch4_init[] = {
3812 /* set line-in to out and mic-in to input */
3813 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3814 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3815 { }
3816};
3817
3818static struct hda_verb alc880_lg_ch6_init[] = {
3819 /* set line-in and mic-in to output */
3820 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3821 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3822 { }
3823};
3824
3825static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3826 { 2, alc880_lg_ch2_init },
3827 { 4, alc880_lg_ch4_init },
3828 { 6, alc880_lg_ch6_init },
3829};
3830
3831static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3832 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3833 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3834 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3835 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3836 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3837 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3838 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3839 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3842 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3843 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3844 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3845 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3846 {
3847 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3848 .name = "Channel Mode",
3849 .info = alc_ch_mode_info,
3850 .get = alc_ch_mode_get,
3851 .put = alc_ch_mode_put,
3852 },
3853 { } /* end */
3854};
3855
3856static struct hda_verb alc880_lg_init_verbs[] = {
3857 /* set capture source to mic-in */
3858 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3859 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3860 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3861 /* mute all amp mixer inputs */
3862 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3863 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3864 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3865 /* line-in to input */
3866 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3867 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3868 /* built-in mic */
3869 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3870 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3871 /* speaker-out */
3872 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3873 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3874 /* mic-in to input */
3875 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3876 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3877 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3878 /* HP-out */
3879 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3880 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3881 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3882 /* jack sense */
a9fd4f3f 3883 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3884 { }
3885};
3886
3887/* toggle speaker-output according to the hp-jack state */
4f5d1706 3888static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3889{
a9fd4f3f 3890 struct alc_spec *spec = codec->spec;
ae6b813a 3891
a9fd4f3f
TI
3892 spec->autocfg.hp_pins[0] = 0x1b;
3893 spec->autocfg.speaker_pins[0] = 0x17;
d922b51d
TI
3894 spec->automute = 1;
3895 spec->automute_mode = ALC_AUTOMUTE_AMP;
ae6b813a
TI
3896}
3897
d681518a
TI
3898/*
3899 * LG LW20
3900 *
3901 * Pin assignment:
3902 * Speaker-out: 0x14
3903 * Mic-In: 0x18
e4f41da9
CM
3904 * Built-in Mic-In: 0x19
3905 * Line-In: 0x1b
3906 * HP-Out: 0x1a
d681518a
TI
3907 * SPDIF-Out: 0x1e
3908 */
3909
d681518a 3910static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3911 .num_items = 3,
d681518a
TI
3912 .items = {
3913 { "Mic", 0x0 },
3914 { "Internal Mic", 0x1 },
e4f41da9 3915 { "Line In", 0x2 },
d681518a
TI
3916 },
3917};
3918
0a8c5da3
CM
3919#define alc880_lg_lw_modes alc880_threestack_modes
3920
d681518a 3921static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3922 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3923 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3924 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3925 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3926 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3927 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3928 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3929 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3930 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3931 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3933 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3934 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3935 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3936 {
3937 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3938 .name = "Channel Mode",
3939 .info = alc_ch_mode_info,
3940 .get = alc_ch_mode_get,
3941 .put = alc_ch_mode_put,
3942 },
d681518a
TI
3943 { } /* end */
3944};
3945
3946static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3947 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3948 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3949 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3950
d681518a
TI
3951 /* set capture source to mic-in */
3952 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3953 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3954 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3955 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3956 /* speaker-out */
3957 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3958 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3959 /* HP-out */
d681518a
TI
3960 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3961 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3962 /* mic-in to input */
3963 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3964 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3965 /* built-in mic */
3966 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3967 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3968 /* jack sense */
a9fd4f3f 3969 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3970 { }
3971};
3972
3973/* toggle speaker-output according to the hp-jack state */
4f5d1706 3974static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3975{
a9fd4f3f 3976 struct alc_spec *spec = codec->spec;
d681518a 3977
a9fd4f3f
TI
3978 spec->autocfg.hp_pins[0] = 0x1b;
3979 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
3980 spec->automute = 1;
3981 spec->automute_mode = ALC_AUTOMUTE_AMP;
d681518a
TI
3982}
3983
df99cd33
TI
3984static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3985 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3986 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3987 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3988 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3989 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3990 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3991 { } /* end */
3992};
3993
3994static struct hda_input_mux alc880_medion_rim_capture_source = {
3995 .num_items = 2,
3996 .items = {
3997 { "Mic", 0x0 },
3998 { "Internal Mic", 0x1 },
3999 },
4000};
4001
4002static struct hda_verb alc880_medion_rim_init_verbs[] = {
4003 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4004
4005 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4006 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4007
4008 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4009 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4011 /* Mic2 (as headphone out) for HP output */
4012 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4013 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4014 /* Internal Speaker */
4015 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4016 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4017
4018 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4019 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4020
4021 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4022 { }
4023};
4024
4025/* toggle speaker-output according to the hp-jack state */
4026static void alc880_medion_rim_automute(struct hda_codec *codec)
4027{
a9fd4f3f 4028 struct alc_spec *spec = codec->spec;
d922b51d 4029 alc_hp_automute(codec);
a9fd4f3f
TI
4030 /* toggle EAPD */
4031 if (spec->jack_present)
df99cd33
TI
4032 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4033 else
4034 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4035}
4036
4037static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4038 unsigned int res)
4039{
4040 /* Looks like the unsol event is incompatible with the standard
4041 * definition. 4bit tag is placed at 28 bit!
4042 */
4043 if ((res >> 28) == ALC880_HP_EVENT)
4044 alc880_medion_rim_automute(codec);
4045}
4046
4f5d1706 4047static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
4048{
4049 struct alc_spec *spec = codec->spec;
4050
4051 spec->autocfg.hp_pins[0] = 0x14;
4052 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
4053 spec->automute = 1;
4054 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f
TI
4055}
4056
cb53c626
TI
4057#ifdef CONFIG_SND_HDA_POWER_SAVE
4058static struct hda_amp_list alc880_loopbacks[] = {
4059 { 0x0b, HDA_INPUT, 0 },
4060 { 0x0b, HDA_INPUT, 1 },
4061 { 0x0b, HDA_INPUT, 2 },
4062 { 0x0b, HDA_INPUT, 3 },
4063 { 0x0b, HDA_INPUT, 4 },
4064 { } /* end */
4065};
4066
4067static struct hda_amp_list alc880_lg_loopbacks[] = {
4068 { 0x0b, HDA_INPUT, 1 },
4069 { 0x0b, HDA_INPUT, 6 },
4070 { 0x0b, HDA_INPUT, 7 },
4071 { } /* end */
4072};
4073#endif
4074
ae6b813a
TI
4075/*
4076 * Common callbacks
e9edcee0
TI
4077 */
4078
584c0c4c
TI
4079static void alc_init_special_input_src(struct hda_codec *codec);
4080
1da177e4
LT
4081static int alc_init(struct hda_codec *codec)
4082{
4083 struct alc_spec *spec = codec->spec;
e9edcee0
TI
4084 unsigned int i;
4085
2c3bf9ab 4086 alc_fix_pll(codec);
4a79ba34 4087 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 4088
e9edcee0
TI
4089 for (i = 0; i < spec->num_init_verbs; i++)
4090 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 4091 alc_init_special_input_src(codec);
ae6b813a
TI
4092
4093 if (spec->init_hook)
4094 spec->init_hook(codec);
4095
58701120
TI
4096 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4097
9e5341b9 4098 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
4099 return 0;
4100}
4101
ae6b813a
TI
4102static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4103{
4104 struct alc_spec *spec = codec->spec;
4105
4106 if (spec->unsol_event)
4107 spec->unsol_event(codec, res);
4108}
4109
cb53c626
TI
4110#ifdef CONFIG_SND_HDA_POWER_SAVE
4111static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4112{
4113 struct alc_spec *spec = codec->spec;
4114 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4115}
4116#endif
4117
1da177e4
LT
4118/*
4119 * Analog playback callbacks
4120 */
4121static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4122 struct hda_codec *codec,
c8b6bf9b 4123 struct snd_pcm_substream *substream)
1da177e4
LT
4124{
4125 struct alc_spec *spec = codec->spec;
9a08160b
TI
4126 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4127 hinfo);
1da177e4
LT
4128}
4129
4130static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4131 struct hda_codec *codec,
4132 unsigned int stream_tag,
4133 unsigned int format,
c8b6bf9b 4134 struct snd_pcm_substream *substream)
1da177e4
LT
4135{
4136 struct alc_spec *spec = codec->spec;
9c7f852e
TI
4137 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4138 stream_tag, format, substream);
1da177e4
LT
4139}
4140
4141static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4142 struct hda_codec *codec,
c8b6bf9b 4143 struct snd_pcm_substream *substream)
1da177e4
LT
4144{
4145 struct alc_spec *spec = codec->spec;
4146 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4147}
4148
4149/*
4150 * Digital out
4151 */
4152static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4153 struct hda_codec *codec,
c8b6bf9b 4154 struct snd_pcm_substream *substream)
1da177e4
LT
4155{
4156 struct alc_spec *spec = codec->spec;
4157 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4158}
4159
6b97eb45
TI
4160static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4161 struct hda_codec *codec,
4162 unsigned int stream_tag,
4163 unsigned int format,
4164 struct snd_pcm_substream *substream)
4165{
4166 struct alc_spec *spec = codec->spec;
4167 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4168 stream_tag, format, substream);
4169}
4170
9b5f12e5
TI
4171static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4172 struct hda_codec *codec,
4173 struct snd_pcm_substream *substream)
4174{
4175 struct alc_spec *spec = codec->spec;
4176 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4177}
4178
1da177e4
LT
4179static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4180 struct hda_codec *codec,
c8b6bf9b 4181 struct snd_pcm_substream *substream)
1da177e4
LT
4182{
4183 struct alc_spec *spec = codec->spec;
4184 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4185}
4186
4187/*
4188 * Analog capture
4189 */
6330079f 4190static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4191 struct hda_codec *codec,
4192 unsigned int stream_tag,
4193 unsigned int format,
c8b6bf9b 4194 struct snd_pcm_substream *substream)
1da177e4
LT
4195{
4196 struct alc_spec *spec = codec->spec;
4197
6330079f 4198 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4199 stream_tag, 0, format);
4200 return 0;
4201}
4202
6330079f 4203static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4204 struct hda_codec *codec,
c8b6bf9b 4205 struct snd_pcm_substream *substream)
1da177e4
LT
4206{
4207 struct alc_spec *spec = codec->spec;
4208
888afa15
TI
4209 snd_hda_codec_cleanup_stream(codec,
4210 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4211 return 0;
4212}
4213
840b64c0
TI
4214/* analog capture with dynamic dual-adc changes */
4215static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4216 struct hda_codec *codec,
4217 unsigned int stream_tag,
4218 unsigned int format,
4219 struct snd_pcm_substream *substream)
4220{
4221 struct alc_spec *spec = codec->spec;
4222 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4223 spec->cur_adc_stream_tag = stream_tag;
4224 spec->cur_adc_format = format;
4225 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4226 return 0;
4227}
4228
4229static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4230 struct hda_codec *codec,
4231 struct snd_pcm_substream *substream)
4232{
4233 struct alc_spec *spec = codec->spec;
4234 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4235 spec->cur_adc = 0;
4236 return 0;
4237}
4238
4239static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4240 .substreams = 1,
4241 .channels_min = 2,
4242 .channels_max = 2,
4243 .nid = 0, /* fill later */
4244 .ops = {
4245 .prepare = dualmic_capture_pcm_prepare,
4246 .cleanup = dualmic_capture_pcm_cleanup
4247 },
4248};
1da177e4
LT
4249
4250/*
4251 */
4252static struct hda_pcm_stream alc880_pcm_analog_playback = {
4253 .substreams = 1,
4254 .channels_min = 2,
4255 .channels_max = 8,
e9edcee0 4256 /* NID is set in alc_build_pcms */
1da177e4
LT
4257 .ops = {
4258 .open = alc880_playback_pcm_open,
4259 .prepare = alc880_playback_pcm_prepare,
4260 .cleanup = alc880_playback_pcm_cleanup
4261 },
4262};
4263
4264static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4265 .substreams = 1,
4266 .channels_min = 2,
4267 .channels_max = 2,
4268 /* NID is set in alc_build_pcms */
4269};
4270
4271static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4272 .substreams = 1,
4273 .channels_min = 2,
4274 .channels_max = 2,
4275 /* NID is set in alc_build_pcms */
4276};
4277
4278static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4279 .substreams = 2, /* can be overridden */
1da177e4
LT
4280 .channels_min = 2,
4281 .channels_max = 2,
e9edcee0 4282 /* NID is set in alc_build_pcms */
1da177e4 4283 .ops = {
6330079f
TI
4284 .prepare = alc880_alt_capture_pcm_prepare,
4285 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4286 },
4287};
4288
4289static struct hda_pcm_stream alc880_pcm_digital_playback = {
4290 .substreams = 1,
4291 .channels_min = 2,
4292 .channels_max = 2,
4293 /* NID is set in alc_build_pcms */
4294 .ops = {
4295 .open = alc880_dig_playback_pcm_open,
6b97eb45 4296 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4297 .prepare = alc880_dig_playback_pcm_prepare,
4298 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4299 },
4300};
4301
4302static struct hda_pcm_stream alc880_pcm_digital_capture = {
4303 .substreams = 1,
4304 .channels_min = 2,
4305 .channels_max = 2,
4306 /* NID is set in alc_build_pcms */
4307};
4308
4c5186ed 4309/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 4310static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4311 .substreams = 0,
4312 .channels_min = 0,
4313 .channels_max = 0,
4314};
4315
1da177e4
LT
4316static int alc_build_pcms(struct hda_codec *codec)
4317{
4318 struct alc_spec *spec = codec->spec;
4319 struct hda_pcm *info = spec->pcm_rec;
4320 int i;
4321
4322 codec->num_pcms = 1;
4323 codec->pcm_info = info;
4324
e64f14f4
TI
4325 if (spec->no_analog)
4326 goto skip_analog;
4327
812a2cca
TI
4328 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4329 "%s Analog", codec->chip_name);
1da177e4 4330 info->name = spec->stream_name_analog;
274693f3 4331
4a471b7d 4332 if (spec->stream_analog_playback) {
da3cec35
TI
4333 if (snd_BUG_ON(!spec->multiout.dac_nids))
4334 return -EINVAL;
4a471b7d
TI
4335 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4336 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4337 }
4338 if (spec->stream_analog_capture) {
da3cec35
TI
4339 if (snd_BUG_ON(!spec->adc_nids))
4340 return -EINVAL;
4a471b7d
TI
4341 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4342 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4343 }
4344
4345 if (spec->channel_mode) {
4346 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4347 for (i = 0; i < spec->num_channel_mode; i++) {
4348 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4349 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4350 }
1da177e4
LT
4351 }
4352 }
4353
e64f14f4 4354 skip_analog:
e08a007d 4355 /* SPDIF for stream index #1 */
1da177e4 4356 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4357 snprintf(spec->stream_name_digital,
4358 sizeof(spec->stream_name_digital),
4359 "%s Digital", codec->chip_name);
e08a007d 4360 codec->num_pcms = 2;
b25c9da1 4361 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4362 info = spec->pcm_rec + 1;
1da177e4 4363 info->name = spec->stream_name_digital;
8c441982
TI
4364 if (spec->dig_out_type)
4365 info->pcm_type = spec->dig_out_type;
4366 else
4367 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4368 if (spec->multiout.dig_out_nid &&
4369 spec->stream_digital_playback) {
1da177e4
LT
4370 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4371 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4372 }
4a471b7d
TI
4373 if (spec->dig_in_nid &&
4374 spec->stream_digital_capture) {
1da177e4
LT
4375 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4376 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4377 }
963f803f
TI
4378 /* FIXME: do we need this for all Realtek codec models? */
4379 codec->spdif_status_reset = 1;
1da177e4
LT
4380 }
4381
e64f14f4
TI
4382 if (spec->no_analog)
4383 return 0;
4384
e08a007d
TI
4385 /* If the use of more than one ADC is requested for the current
4386 * model, configure a second analog capture-only PCM.
4387 */
4388 /* Additional Analaog capture for index #2 */
6330079f
TI
4389 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4390 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4391 codec->num_pcms = 3;
c06134d7 4392 info = spec->pcm_rec + 2;
e08a007d 4393 info->name = spec->stream_name_analog;
6330079f
TI
4394 if (spec->alt_dac_nid) {
4395 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4396 *spec->stream_analog_alt_playback;
4397 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4398 spec->alt_dac_nid;
4399 } else {
4400 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4401 alc_pcm_null_stream;
4402 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4403 }
4404 if (spec->num_adc_nids > 1) {
4405 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4406 *spec->stream_analog_alt_capture;
4407 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4408 spec->adc_nids[1];
4409 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4410 spec->num_adc_nids - 1;
4411 } else {
4412 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4413 alc_pcm_null_stream;
4414 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4415 }
4416 }
4417
1da177e4
LT
4418 return 0;
4419}
4420
a4e09aa3
TI
4421static inline void alc_shutup(struct hda_codec *codec)
4422{
1c716153
TI
4423 struct alc_spec *spec = codec->spec;
4424
4425 if (spec && spec->shutup)
4426 spec->shutup(codec);
a4e09aa3
TI
4427 snd_hda_shutup_pins(codec);
4428}
4429
603c4019
TI
4430static void alc_free_kctls(struct hda_codec *codec)
4431{
4432 struct alc_spec *spec = codec->spec;
4433
4434 if (spec->kctls.list) {
4435 struct snd_kcontrol_new *kctl = spec->kctls.list;
4436 int i;
4437 for (i = 0; i < spec->kctls.used; i++)
4438 kfree(kctl[i].name);
4439 }
4440 snd_array_free(&spec->kctls);
4441}
4442
1da177e4
LT
4443static void alc_free(struct hda_codec *codec)
4444{
e9edcee0 4445 struct alc_spec *spec = codec->spec;
e9edcee0 4446
f12ab1e0 4447 if (!spec)
e9edcee0
TI
4448 return;
4449
a4e09aa3 4450 alc_shutup(codec);
cd372fb3 4451 snd_hda_input_jack_free(codec);
603c4019 4452 alc_free_kctls(codec);
e9edcee0 4453 kfree(spec);
680cd536 4454 snd_hda_detach_beep_device(codec);
1da177e4
LT
4455}
4456
f5de24b0 4457#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4458static void alc_power_eapd(struct hda_codec *codec)
4459{
691f1fcc 4460 alc_auto_setup_eapd(codec, false);
c97259df
DC
4461}
4462
f5de24b0
HM
4463static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4464{
4465 struct alc_spec *spec = codec->spec;
a4e09aa3 4466 alc_shutup(codec);
f5de24b0 4467 if (spec && spec->power_hook)
c97259df 4468 spec->power_hook(codec);
f5de24b0
HM
4469 return 0;
4470}
4471#endif
4472
e044c39a 4473#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4474static int alc_resume(struct hda_codec *codec)
4475{
1c716153 4476 msleep(150); /* to avoid pop noise */
e044c39a
TI
4477 codec->patch_ops.init(codec);
4478 snd_hda_codec_resume_amp(codec);
4479 snd_hda_codec_resume_cache(codec);
9e5341b9 4480 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4481 return 0;
4482}
e044c39a
TI
4483#endif
4484
1da177e4
LT
4485/*
4486 */
4487static struct hda_codec_ops alc_patch_ops = {
4488 .build_controls = alc_build_controls,
4489 .build_pcms = alc_build_pcms,
4490 .init = alc_init,
4491 .free = alc_free,
ae6b813a 4492 .unsol_event = alc_unsol_event,
e044c39a
TI
4493#ifdef SND_HDA_NEEDS_RESUME
4494 .resume = alc_resume,
4495#endif
cb53c626 4496#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4497 .suspend = alc_suspend,
cb53c626
TI
4498 .check_power_status = alc_check_power_status,
4499#endif
c97259df 4500 .reboot_notify = alc_shutup,
1da177e4
LT
4501};
4502
c027ddcd
KY
4503/* replace the codec chip_name with the given string */
4504static int alc_codec_rename(struct hda_codec *codec, const char *name)
4505{
4506 kfree(codec->chip_name);
4507 codec->chip_name = kstrdup(name, GFP_KERNEL);
4508 if (!codec->chip_name) {
4509 alc_free(codec);
4510 return -ENOMEM;
4511 }
4512 return 0;
4513}
4514
2fa522be
TI
4515/*
4516 * Test configuration for debugging
4517 *
4518 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4519 * enum controls.
4520 */
4521#ifdef CONFIG_SND_DEBUG
4522static hda_nid_t alc880_test_dac_nids[4] = {
4523 0x02, 0x03, 0x04, 0x05
4524};
4525
4526static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4527 .num_items = 7,
2fa522be
TI
4528 .items = {
4529 { "In-1", 0x0 },
4530 { "In-2", 0x1 },
4531 { "In-3", 0x2 },
4532 { "In-4", 0x3 },
4533 { "CD", 0x4 },
ae6b813a
TI
4534 { "Front", 0x5 },
4535 { "Surround", 0x6 },
2fa522be
TI
4536 },
4537};
4538
d2a6d7dc 4539static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4540 { 2, NULL },
fd2c326d 4541 { 4, NULL },
2fa522be 4542 { 6, NULL },
fd2c326d 4543 { 8, NULL },
2fa522be
TI
4544};
4545
9c7f852e
TI
4546static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4547 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4548{
4549 static char *texts[] = {
4550 "N/A", "Line Out", "HP Out",
4551 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4552 };
4553 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4554 uinfo->count = 1;
4555 uinfo->value.enumerated.items = 8;
4556 if (uinfo->value.enumerated.item >= 8)
4557 uinfo->value.enumerated.item = 7;
4558 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4559 return 0;
4560}
4561
9c7f852e
TI
4562static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4563 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4564{
4565 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4566 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4567 unsigned int pin_ctl, item = 0;
4568
4569 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4570 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4571 if (pin_ctl & AC_PINCTL_OUT_EN) {
4572 if (pin_ctl & AC_PINCTL_HP_EN)
4573 item = 2;
4574 else
4575 item = 1;
4576 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4577 switch (pin_ctl & AC_PINCTL_VREFEN) {
4578 case AC_PINCTL_VREF_HIZ: item = 3; break;
4579 case AC_PINCTL_VREF_50: item = 4; break;
4580 case AC_PINCTL_VREF_GRD: item = 5; break;
4581 case AC_PINCTL_VREF_80: item = 6; break;
4582 case AC_PINCTL_VREF_100: item = 7; break;
4583 }
4584 }
4585 ucontrol->value.enumerated.item[0] = item;
4586 return 0;
4587}
4588
9c7f852e
TI
4589static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4590 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4591{
4592 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4593 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4594 static unsigned int ctls[] = {
4595 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4596 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4597 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4598 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4599 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4600 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4601 };
4602 unsigned int old_ctl, new_ctl;
4603
4604 old_ctl = snd_hda_codec_read(codec, nid, 0,
4605 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4606 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4607 if (old_ctl != new_ctl) {
82beb8fd
TI
4608 int val;
4609 snd_hda_codec_write_cache(codec, nid, 0,
4610 AC_VERB_SET_PIN_WIDGET_CONTROL,
4611 new_ctl);
47fd830a
TI
4612 val = ucontrol->value.enumerated.item[0] >= 3 ?
4613 HDA_AMP_MUTE : 0;
4614 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4615 HDA_AMP_MUTE, val);
2fa522be
TI
4616 return 1;
4617 }
4618 return 0;
4619}
4620
9c7f852e
TI
4621static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4622 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4623{
4624 static char *texts[] = {
4625 "Front", "Surround", "CLFE", "Side"
4626 };
4627 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4628 uinfo->count = 1;
4629 uinfo->value.enumerated.items = 4;
4630 if (uinfo->value.enumerated.item >= 4)
4631 uinfo->value.enumerated.item = 3;
4632 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4633 return 0;
4634}
4635
9c7f852e
TI
4636static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4637 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4638{
4639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4640 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4641 unsigned int sel;
4642
4643 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4644 ucontrol->value.enumerated.item[0] = sel & 3;
4645 return 0;
4646}
4647
9c7f852e
TI
4648static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4649 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4650{
4651 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4652 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4653 unsigned int sel;
4654
4655 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4656 if (ucontrol->value.enumerated.item[0] != sel) {
4657 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4658 snd_hda_codec_write_cache(codec, nid, 0,
4659 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4660 return 1;
4661 }
4662 return 0;
4663}
4664
4665#define PIN_CTL_TEST(xname,nid) { \
4666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4667 .name = xname, \
5b0cb1d8 4668 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4669 .info = alc_test_pin_ctl_info, \
4670 .get = alc_test_pin_ctl_get, \
4671 .put = alc_test_pin_ctl_put, \
4672 .private_value = nid \
4673 }
4674
4675#define PIN_SRC_TEST(xname,nid) { \
4676 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4677 .name = xname, \
5b0cb1d8 4678 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4679 .info = alc_test_pin_src_info, \
4680 .get = alc_test_pin_src_get, \
4681 .put = alc_test_pin_src_put, \
4682 .private_value = nid \
4683 }
4684
c8b6bf9b 4685static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4686 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4687 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4688 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4689 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4690 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4691 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4692 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4693 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4694 PIN_CTL_TEST("Front Pin Mode", 0x14),
4695 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4696 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4697 PIN_CTL_TEST("Side Pin Mode", 0x17),
4698 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4699 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4700 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4701 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4702 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4703 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4704 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4705 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4706 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4707 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4708 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4709 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4710 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4711 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4712 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4713 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4714 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4715 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4716 {
4717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4718 .name = "Channel Mode",
df694daa
KY
4719 .info = alc_ch_mode_info,
4720 .get = alc_ch_mode_get,
4721 .put = alc_ch_mode_put,
2fa522be
TI
4722 },
4723 { } /* end */
4724};
4725
4726static struct hda_verb alc880_test_init_verbs[] = {
4727 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4728 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4729 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4732 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4734 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4735 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4736 /* Vol output for 0x0c-0x0f */
05acb863
TI
4737 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4738 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4739 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4740 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4741 /* Set output pins 0x14-0x17 */
05acb863
TI
4742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4743 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4744 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4745 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4746 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4747 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4749 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4750 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4751 /* Set input pins 0x18-0x1c */
16ded525
TI
4752 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4753 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4754 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4755 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4756 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4757 /* Mute input pins 0x18-0x1b */
05acb863
TI
4758 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4759 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4761 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4762 /* ADC set up */
05acb863 4763 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4764 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4765 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4766 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4767 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4768 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4769 /* Analog input/passthru */
4770 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4771 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4772 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4773 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4774 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4775 { }
4776};
4777#endif
4778
1da177e4
LT
4779/*
4780 */
4781
ea734963 4782static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4783 [ALC880_3ST] = "3stack",
4784 [ALC880_TCL_S700] = "tcl",
4785 [ALC880_3ST_DIG] = "3stack-digout",
4786 [ALC880_CLEVO] = "clevo",
4787 [ALC880_5ST] = "5stack",
4788 [ALC880_5ST_DIG] = "5stack-digout",
4789 [ALC880_W810] = "w810",
4790 [ALC880_Z71V] = "z71v",
4791 [ALC880_6ST] = "6stack",
4792 [ALC880_6ST_DIG] = "6stack-digout",
4793 [ALC880_ASUS] = "asus",
4794 [ALC880_ASUS_W1V] = "asus-w1v",
4795 [ALC880_ASUS_DIG] = "asus-dig",
4796 [ALC880_ASUS_DIG2] = "asus-dig2",
4797 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4798 [ALC880_UNIWILL_P53] = "uniwill-p53",
4799 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4800 [ALC880_F1734] = "F1734",
4801 [ALC880_LG] = "lg",
4802 [ALC880_LG_LW] = "lg-lw",
df99cd33 4803 [ALC880_MEDION_RIM] = "medion",
2fa522be 4804#ifdef CONFIG_SND_DEBUG
f5fcc13c 4805 [ALC880_TEST] = "test",
2fa522be 4806#endif
f5fcc13c
TI
4807 [ALC880_AUTO] = "auto",
4808};
4809
4810static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4811 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4812 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4813 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4814 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4815 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4816 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4817 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4818 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4819 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4820 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4821 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4822 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4823 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4824 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4825 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4826 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4827 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4828 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4829 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4830 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4831 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4832 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4833 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4834 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4835 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4836 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4837 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4838 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4839 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4840 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4841 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4842 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4843 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4844 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4845 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4846 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4847 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4848 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4849 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4850 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4851 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
4852 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4853 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4854 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4855 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4856 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4857 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4858 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4859 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4860 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4861 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4862 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4863 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4864 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4865 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4866 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4867 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4868 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4869 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4870 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4871 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4872 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4873 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4874 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4875 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4876 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4877 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4878 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4879 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4880 /* default Intel */
4881 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4882 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4883 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4884 {}
4885};
4886
16ded525 4887/*
df694daa 4888 * ALC880 codec presets
16ded525 4889 */
16ded525
TI
4890static struct alc_config_preset alc880_presets[] = {
4891 [ALC880_3ST] = {
e9edcee0 4892 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4893 .init_verbs = { alc880_volume_init_verbs,
4894 alc880_pin_3stack_init_verbs },
16ded525 4895 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4896 .dac_nids = alc880_dac_nids,
16ded525
TI
4897 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4898 .channel_mode = alc880_threestack_modes,
4e195a7b 4899 .need_dac_fix = 1,
16ded525
TI
4900 .input_mux = &alc880_capture_source,
4901 },
4902 [ALC880_3ST_DIG] = {
e9edcee0 4903 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4904 .init_verbs = { alc880_volume_init_verbs,
4905 alc880_pin_3stack_init_verbs },
16ded525 4906 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4907 .dac_nids = alc880_dac_nids,
4908 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4909 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4910 .channel_mode = alc880_threestack_modes,
4e195a7b 4911 .need_dac_fix = 1,
16ded525
TI
4912 .input_mux = &alc880_capture_source,
4913 },
df694daa
KY
4914 [ALC880_TCL_S700] = {
4915 .mixers = { alc880_tcl_s700_mixer },
4916 .init_verbs = { alc880_volume_init_verbs,
4917 alc880_pin_tcl_S700_init_verbs,
4918 alc880_gpio2_init_verbs },
4919 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4920 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4921 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4922 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4923 .hp_nid = 0x03,
4924 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4925 .channel_mode = alc880_2_jack_modes,
4926 .input_mux = &alc880_capture_source,
4927 },
16ded525 4928 [ALC880_5ST] = {
f12ab1e0
TI
4929 .mixers = { alc880_three_stack_mixer,
4930 alc880_five_stack_mixer},
4931 .init_verbs = { alc880_volume_init_verbs,
4932 alc880_pin_5stack_init_verbs },
16ded525
TI
4933 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4934 .dac_nids = alc880_dac_nids,
16ded525
TI
4935 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4936 .channel_mode = alc880_fivestack_modes,
4937 .input_mux = &alc880_capture_source,
4938 },
4939 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4940 .mixers = { alc880_three_stack_mixer,
4941 alc880_five_stack_mixer },
4942 .init_verbs = { alc880_volume_init_verbs,
4943 alc880_pin_5stack_init_verbs },
16ded525
TI
4944 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4945 .dac_nids = alc880_dac_nids,
4946 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4947 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4948 .channel_mode = alc880_fivestack_modes,
4949 .input_mux = &alc880_capture_source,
4950 },
b6482d48
TI
4951 [ALC880_6ST] = {
4952 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4953 .init_verbs = { alc880_volume_init_verbs,
4954 alc880_pin_6stack_init_verbs },
b6482d48
TI
4955 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4956 .dac_nids = alc880_6st_dac_nids,
4957 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4958 .channel_mode = alc880_sixstack_modes,
4959 .input_mux = &alc880_6stack_capture_source,
4960 },
16ded525 4961 [ALC880_6ST_DIG] = {
e9edcee0 4962 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4963 .init_verbs = { alc880_volume_init_verbs,
4964 alc880_pin_6stack_init_verbs },
16ded525
TI
4965 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4966 .dac_nids = alc880_6st_dac_nids,
4967 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4968 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4969 .channel_mode = alc880_sixstack_modes,
4970 .input_mux = &alc880_6stack_capture_source,
4971 },
4972 [ALC880_W810] = {
e9edcee0 4973 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4974 .init_verbs = { alc880_volume_init_verbs,
4975 alc880_pin_w810_init_verbs,
b0af0de5 4976 alc880_gpio2_init_verbs },
16ded525
TI
4977 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4978 .dac_nids = alc880_w810_dac_nids,
4979 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4980 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4981 .channel_mode = alc880_w810_modes,
4982 .input_mux = &alc880_capture_source,
4983 },
4984 [ALC880_Z71V] = {
e9edcee0 4985 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4986 .init_verbs = { alc880_volume_init_verbs,
4987 alc880_pin_z71v_init_verbs },
16ded525
TI
4988 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4989 .dac_nids = alc880_z71v_dac_nids,
4990 .dig_out_nid = ALC880_DIGOUT_NID,
4991 .hp_nid = 0x03,
e9edcee0
TI
4992 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4993 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4994 .input_mux = &alc880_capture_source,
4995 },
4996 [ALC880_F1734] = {
e9edcee0 4997 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4998 .init_verbs = { alc880_volume_init_verbs,
4999 alc880_pin_f1734_init_verbs },
e9edcee0
TI
5000 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5001 .dac_nids = alc880_f1734_dac_nids,
5002 .hp_nid = 0x02,
5003 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5004 .channel_mode = alc880_2_jack_modes,
937b4160
TI
5005 .input_mux = &alc880_f1734_capture_source,
5006 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5007 .setup = alc880_uniwill_p53_setup,
d922b51d 5008 .init_hook = alc_hp_automute,
16ded525
TI
5009 },
5010 [ALC880_ASUS] = {
e9edcee0 5011 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5012 .init_verbs = { alc880_volume_init_verbs,
5013 alc880_pin_asus_init_verbs,
e9edcee0
TI
5014 alc880_gpio1_init_verbs },
5015 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5016 .dac_nids = alc880_asus_dac_nids,
5017 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5018 .channel_mode = alc880_asus_modes,
4e195a7b 5019 .need_dac_fix = 1,
16ded525
TI
5020 .input_mux = &alc880_capture_source,
5021 },
5022 [ALC880_ASUS_DIG] = {
e9edcee0 5023 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5024 .init_verbs = { alc880_volume_init_verbs,
5025 alc880_pin_asus_init_verbs,
e9edcee0
TI
5026 alc880_gpio1_init_verbs },
5027 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5028 .dac_nids = alc880_asus_dac_nids,
16ded525 5029 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5030 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5031 .channel_mode = alc880_asus_modes,
4e195a7b 5032 .need_dac_fix = 1,
16ded525
TI
5033 .input_mux = &alc880_capture_source,
5034 },
df694daa
KY
5035 [ALC880_ASUS_DIG2] = {
5036 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5037 .init_verbs = { alc880_volume_init_verbs,
5038 alc880_pin_asus_init_verbs,
df694daa
KY
5039 alc880_gpio2_init_verbs }, /* use GPIO2 */
5040 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5041 .dac_nids = alc880_asus_dac_nids,
5042 .dig_out_nid = ALC880_DIGOUT_NID,
5043 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5044 .channel_mode = alc880_asus_modes,
4e195a7b 5045 .need_dac_fix = 1,
df694daa
KY
5046 .input_mux = &alc880_capture_source,
5047 },
16ded525 5048 [ALC880_ASUS_W1V] = {
e9edcee0 5049 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
5050 .init_verbs = { alc880_volume_init_verbs,
5051 alc880_pin_asus_init_verbs,
e9edcee0
TI
5052 alc880_gpio1_init_verbs },
5053 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5054 .dac_nids = alc880_asus_dac_nids,
16ded525 5055 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5056 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5057 .channel_mode = alc880_asus_modes,
4e195a7b 5058 .need_dac_fix = 1,
16ded525
TI
5059 .input_mux = &alc880_capture_source,
5060 },
5061 [ALC880_UNIWILL_DIG] = {
45bdd1c1 5062 .mixers = { alc880_asus_mixer },
ccc656ce
KY
5063 .init_verbs = { alc880_volume_init_verbs,
5064 alc880_pin_asus_init_verbs },
e9edcee0
TI
5065 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5066 .dac_nids = alc880_asus_dac_nids,
16ded525 5067 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5068 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5069 .channel_mode = alc880_asus_modes,
4e195a7b 5070 .need_dac_fix = 1,
16ded525
TI
5071 .input_mux = &alc880_capture_source,
5072 },
ccc656ce
KY
5073 [ALC880_UNIWILL] = {
5074 .mixers = { alc880_uniwill_mixer },
5075 .init_verbs = { alc880_volume_init_verbs,
5076 alc880_uniwill_init_verbs },
5077 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5078 .dac_nids = alc880_asus_dac_nids,
5079 .dig_out_nid = ALC880_DIGOUT_NID,
5080 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5081 .channel_mode = alc880_threestack_modes,
5082 .need_dac_fix = 1,
5083 .input_mux = &alc880_capture_source,
5084 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 5085 .setup = alc880_uniwill_setup,
a9fd4f3f 5086 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
5087 },
5088 [ALC880_UNIWILL_P53] = {
5089 .mixers = { alc880_uniwill_p53_mixer },
5090 .init_verbs = { alc880_volume_init_verbs,
5091 alc880_uniwill_p53_init_verbs },
5092 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5093 .dac_nids = alc880_asus_dac_nids,
5094 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
5095 .channel_mode = alc880_threestack_modes,
5096 .input_mux = &alc880_capture_source,
5097 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5098 .setup = alc880_uniwill_p53_setup,
d922b51d 5099 .init_hook = alc_hp_automute,
2cf9f0fc
TD
5100 },
5101 [ALC880_FUJITSU] = {
45bdd1c1 5102 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
5103 .init_verbs = { alc880_volume_init_verbs,
5104 alc880_uniwill_p53_init_verbs,
5105 alc880_beep_init_verbs },
5106 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5107 .dac_nids = alc880_dac_nids,
d53d7d9e 5108 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
5109 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5110 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
5111 .input_mux = &alc880_capture_source,
5112 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5113 .setup = alc880_uniwill_p53_setup,
d922b51d 5114 .init_hook = alc_hp_automute,
ccc656ce 5115 },
df694daa
KY
5116 [ALC880_CLEVO] = {
5117 .mixers = { alc880_three_stack_mixer },
5118 .init_verbs = { alc880_volume_init_verbs,
5119 alc880_pin_clevo_init_verbs },
5120 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5121 .dac_nids = alc880_dac_nids,
5122 .hp_nid = 0x03,
5123 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5124 .channel_mode = alc880_threestack_modes,
4e195a7b 5125 .need_dac_fix = 1,
df694daa
KY
5126 .input_mux = &alc880_capture_source,
5127 },
ae6b813a
TI
5128 [ALC880_LG] = {
5129 .mixers = { alc880_lg_mixer },
5130 .init_verbs = { alc880_volume_init_verbs,
5131 alc880_lg_init_verbs },
5132 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5133 .dac_nids = alc880_lg_dac_nids,
5134 .dig_out_nid = ALC880_DIGOUT_NID,
5135 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5136 .channel_mode = alc880_lg_ch_modes,
4e195a7b 5137 .need_dac_fix = 1,
ae6b813a 5138 .input_mux = &alc880_lg_capture_source,
d922b51d 5139 .unsol_event = alc_sku_unsol_event,
4f5d1706 5140 .setup = alc880_lg_setup,
d922b51d 5141 .init_hook = alc_hp_automute,
cb53c626
TI
5142#ifdef CONFIG_SND_HDA_POWER_SAVE
5143 .loopbacks = alc880_lg_loopbacks,
5144#endif
ae6b813a 5145 },
d681518a
TI
5146 [ALC880_LG_LW] = {
5147 .mixers = { alc880_lg_lw_mixer },
5148 .init_verbs = { alc880_volume_init_verbs,
5149 alc880_lg_lw_init_verbs },
0a8c5da3 5150 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5151 .dac_nids = alc880_dac_nids,
5152 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5153 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5154 .channel_mode = alc880_lg_lw_modes,
d681518a 5155 .input_mux = &alc880_lg_lw_capture_source,
d922b51d 5156 .unsol_event = alc_sku_unsol_event,
4f5d1706 5157 .setup = alc880_lg_lw_setup,
d922b51d 5158 .init_hook = alc_hp_automute,
d681518a 5159 },
df99cd33
TI
5160 [ALC880_MEDION_RIM] = {
5161 .mixers = { alc880_medion_rim_mixer },
5162 .init_verbs = { alc880_volume_init_verbs,
5163 alc880_medion_rim_init_verbs,
5164 alc_gpio2_init_verbs },
5165 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5166 .dac_nids = alc880_dac_nids,
5167 .dig_out_nid = ALC880_DIGOUT_NID,
5168 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5169 .channel_mode = alc880_2_jack_modes,
5170 .input_mux = &alc880_medion_rim_capture_source,
5171 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5172 .setup = alc880_medion_rim_setup,
5173 .init_hook = alc880_medion_rim_automute,
df99cd33 5174 },
16ded525
TI
5175#ifdef CONFIG_SND_DEBUG
5176 [ALC880_TEST] = {
e9edcee0
TI
5177 .mixers = { alc880_test_mixer },
5178 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5179 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5180 .dac_nids = alc880_test_dac_nids,
5181 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5182 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5183 .channel_mode = alc880_test_modes,
5184 .input_mux = &alc880_test_capture_source,
5185 },
5186#endif
5187};
5188
e9edcee0
TI
5189/*
5190 * Automatic parse of I/O pins from the BIOS configuration
5191 */
5192
e9edcee0
TI
5193enum {
5194 ALC_CTL_WIDGET_VOL,
5195 ALC_CTL_WIDGET_MUTE,
5196 ALC_CTL_BIND_MUTE,
5197};
c8b6bf9b 5198static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5199 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5200 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5201 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5202};
5203
ce764ab2
TI
5204static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5205{
5206 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5207 return snd_array_new(&spec->kctls);
5208}
5209
e9edcee0 5210/* add dynamic controls */
f12ab1e0 5211static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5212 int cidx, unsigned long val)
e9edcee0 5213{
c8b6bf9b 5214 struct snd_kcontrol_new *knew;
e9edcee0 5215
ce764ab2 5216 knew = alc_kcontrol_new(spec);
603c4019
TI
5217 if (!knew)
5218 return -ENOMEM;
e9edcee0 5219 *knew = alc880_control_templates[type];
543537bd 5220 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5221 if (!knew->name)
e9edcee0 5222 return -ENOMEM;
66ceeb6b 5223 knew->index = cidx;
4d02d1b6 5224 if (get_amp_nid_(val))
5e26dfd0 5225 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5226 knew->private_value = val;
e9edcee0
TI
5227 return 0;
5228}
5229
0afe5f89
TI
5230static int add_control_with_pfx(struct alc_spec *spec, int type,
5231 const char *pfx, const char *dir,
66ceeb6b 5232 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5233{
5234 char name[32];
5235 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5236 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5237}
5238
66ceeb6b
TI
5239#define add_pb_vol_ctrl(spec, type, pfx, val) \
5240 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5241#define add_pb_sw_ctrl(spec, type, pfx, val) \
5242 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5243#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5244 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5245#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5246 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5247
e9edcee0
TI
5248#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5249#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5250#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5251#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5252#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5253#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5254#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5255#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5256#define ALC880_PIN_CD_NID 0x1c
5257
5258/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5259static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5260 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5261{
5262 hda_nid_t nid;
5263 int assigned[4];
5264 int i, j;
5265
5266 memset(assigned, 0, sizeof(assigned));
b0af0de5 5267 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5268
5269 /* check the pins hardwired to audio widget */
5270 for (i = 0; i < cfg->line_outs; i++) {
5271 nid = cfg->line_out_pins[i];
5272 if (alc880_is_fixed_pin(nid)) {
5273 int idx = alc880_fixed_pin_idx(nid);
5014f193 5274 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5275 assigned[idx] = 1;
5276 }
5277 }
5278 /* left pins can be connect to any audio widget */
5279 for (i = 0; i < cfg->line_outs; i++) {
5280 nid = cfg->line_out_pins[i];
5281 if (alc880_is_fixed_pin(nid))
5282 continue;
5283 /* search for an empty channel */
5284 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
5285 if (!assigned[j]) {
5286 spec->multiout.dac_nids[i] =
5287 alc880_idx_to_dac(j);
e9edcee0
TI
5288 assigned[j] = 1;
5289 break;
5290 }
5291 }
5292 }
5293 spec->multiout.num_dacs = cfg->line_outs;
5294 return 0;
5295}
5296
ce764ab2 5297static const char *alc_get_line_out_pfx(struct alc_spec *spec,
bcb2f0f5
TI
5298 bool can_be_master)
5299{
ce764ab2
TI
5300 struct auto_pin_cfg *cfg = &spec->autocfg;
5301
5302 if (cfg->line_outs == 1 && !spec->multi_ios &&
5303 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
bcb2f0f5
TI
5304 return "Master";
5305
5306 switch (cfg->line_out_type) {
5307 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5308 if (cfg->line_outs == 1)
5309 return "Speaker";
5310 break;
bcb2f0f5
TI
5311 case AUTO_PIN_HP_OUT:
5312 return "Headphone";
5313 default:
ce764ab2 5314 if (cfg->line_outs == 1 && !spec->multi_ios)
bcb2f0f5
TI
5315 return "PCM";
5316 break;
5317 }
5318 return NULL;
5319}
5320
e9edcee0 5321/* add playback controls from the parsed DAC table */
df694daa
KY
5322static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5323 const struct auto_pin_cfg *cfg)
e9edcee0 5324{
ea734963 5325 static const char * const chname[4] = {
f12ab1e0
TI
5326 "Front", "Surround", NULL /*CLFE*/, "Side"
5327 };
ce764ab2 5328 const char *pfx = alc_get_line_out_pfx(spec, false);
e9edcee0 5329 hda_nid_t nid;
ce764ab2 5330 int i, err, noutputs;
e9edcee0 5331
ce764ab2
TI
5332 noutputs = cfg->line_outs;
5333 if (spec->multi_ios > 0)
5334 noutputs += spec->multi_ios;
5335
5336 for (i = 0; i < noutputs; i++) {
f12ab1e0 5337 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5338 continue;
5339 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5340 if (!pfx && i == 2) {
e9edcee0 5341 /* Center/LFE */
0afe5f89
TI
5342 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5343 "Center",
f12ab1e0
TI
5344 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5345 HDA_OUTPUT));
5346 if (err < 0)
e9edcee0 5347 return err;
0afe5f89
TI
5348 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5349 "LFE",
f12ab1e0
TI
5350 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5351 HDA_OUTPUT));
5352 if (err < 0)
e9edcee0 5353 return err;
0afe5f89
TI
5354 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5355 "Center",
f12ab1e0
TI
5356 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5357 HDA_INPUT));
5358 if (err < 0)
e9edcee0 5359 return err;
0afe5f89
TI
5360 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5361 "LFE",
f12ab1e0
TI
5362 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5363 HDA_INPUT));
5364 if (err < 0)
e9edcee0
TI
5365 return err;
5366 } else {
bcb2f0f5 5367 const char *name = pfx;
7e59e097
DH
5368 int index = i;
5369 if (!name) {
bcb2f0f5 5370 name = chname[i];
7e59e097
DH
5371 index = 0;
5372 }
bcb2f0f5 5373 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5374 name, index,
f12ab1e0
TI
5375 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5376 HDA_OUTPUT));
5377 if (err < 0)
e9edcee0 5378 return err;
bcb2f0f5 5379 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5380 name, index,
f12ab1e0
TI
5381 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5382 HDA_INPUT));
5383 if (err < 0)
e9edcee0
TI
5384 return err;
5385 }
5386 }
e9edcee0
TI
5387 return 0;
5388}
5389
8d88bc3d
TI
5390/* add playback controls for speaker and HP outputs */
5391static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5392 const char *pfx)
e9edcee0
TI
5393{
5394 hda_nid_t nid;
5395 int err;
5396
f12ab1e0 5397 if (!pin)
e9edcee0
TI
5398 return 0;
5399
5400 if (alc880_is_fixed_pin(pin)) {
5401 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5402 /* specify the DAC as the extra output */
f12ab1e0 5403 if (!spec->multiout.hp_nid)
e9edcee0 5404 spec->multiout.hp_nid = nid;
82bc955f
TI
5405 else
5406 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5407 /* control HP volume/switch on the output mixer amp */
5408 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5409 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5410 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5411 if (err < 0)
e9edcee0 5412 return err;
0afe5f89 5413 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5414 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5415 if (err < 0)
e9edcee0
TI
5416 return err;
5417 } else if (alc880_is_multi_pin(pin)) {
5418 /* set manual connection */
e9edcee0 5419 /* we have only a switch on HP-out PIN */
0afe5f89 5420 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5421 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5422 if (err < 0)
e9edcee0
TI
5423 return err;
5424 }
5425 return 0;
5426}
5427
5428/* create input playback/capture controls for the given pin */
f12ab1e0 5429static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5430 const char *ctlname, int ctlidx,
df694daa 5431 int idx, hda_nid_t mix_nid)
e9edcee0 5432{
df694daa 5433 int err;
e9edcee0 5434
66ceeb6b 5435 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5436 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5437 if (err < 0)
e9edcee0 5438 return err;
66ceeb6b 5439 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5440 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5441 if (err < 0)
e9edcee0
TI
5442 return err;
5443 return 0;
5444}
5445
05f5f477
TI
5446static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5447{
5448 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5449 return (pincap & AC_PINCAP_IN) != 0;
5450}
5451
e9edcee0 5452/* create playback/capture controls for input pins */
05f5f477
TI
5453static int alc_auto_create_input_ctls(struct hda_codec *codec,
5454 const struct auto_pin_cfg *cfg,
5455 hda_nid_t mixer,
5456 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5457{
05f5f477 5458 struct alc_spec *spec = codec->spec;
61b9b9b1 5459 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5460 int i, err, idx, type_idx = 0;
5461 const char *prev_label = NULL;
e9edcee0 5462
66ceeb6b 5463 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5464 hda_nid_t pin;
10a20af7 5465 const char *label;
05f5f477 5466
66ceeb6b 5467 pin = cfg->inputs[i].pin;
05f5f477
TI
5468 if (!alc_is_input_pin(codec, pin))
5469 continue;
5470
5322bf27
DH
5471 label = hda_get_autocfg_input_label(codec, cfg, i);
5472 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5473 type_idx++;
5474 else
5475 type_idx = 0;
5322bf27
DH
5476 prev_label = label;
5477
05f5f477
TI
5478 if (mixer) {
5479 idx = get_connection_index(codec, mixer, pin);
5480 if (idx >= 0) {
5481 err = new_analog_input(spec, pin,
10a20af7
TI
5482 label, type_idx,
5483 idx, mixer);
05f5f477
TI
5484 if (err < 0)
5485 return err;
5486 }
5487 }
5488
5489 if (!cap1)
5490 continue;
5491 idx = get_connection_index(codec, cap1, pin);
5492 if (idx < 0 && cap2)
5493 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5494 if (idx >= 0)
5495 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5496 }
5497 return 0;
5498}
5499
05f5f477
TI
5500static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5501 const struct auto_pin_cfg *cfg)
5502{
5503 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5504}
5505
f6c7e546
TI
5506static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5507 unsigned int pin_type)
5508{
5509 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5510 pin_type);
5511 /* unmute pin */
d260cdf6
TI
5512 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5513 AMP_OUT_UNMUTE);
f6c7e546
TI
5514}
5515
df694daa
KY
5516static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5517 hda_nid_t nid, int pin_type,
e9edcee0
TI
5518 int dac_idx)
5519{
f6c7e546 5520 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5521 /* need the manual connection? */
5522 if (alc880_is_multi_pin(nid)) {
5523 struct alc_spec *spec = codec->spec;
5524 int idx = alc880_multi_pin_idx(nid);
5525 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5526 AC_VERB_SET_CONNECT_SEL,
5527 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5528 }
5529}
5530
baba8ee9
TI
5531static int get_pin_type(int line_out_type)
5532{
5533 if (line_out_type == AUTO_PIN_HP_OUT)
5534 return PIN_HP;
5535 else
5536 return PIN_OUT;
5537}
5538
e9edcee0
TI
5539static void alc880_auto_init_multi_out(struct hda_codec *codec)
5540{
5541 struct alc_spec *spec = codec->spec;
5542 int i;
ea1fb29a 5543
e9edcee0
TI
5544 for (i = 0; i < spec->autocfg.line_outs; i++) {
5545 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5546 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5547 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5548 }
5549}
5550
8d88bc3d 5551static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5552{
5553 struct alc_spec *spec = codec->spec;
5554 hda_nid_t pin;
5555
82bc955f 5556 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5557 if (pin) /* connect to front */
5558 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5559 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5560 if (pin) /* connect to front */
5561 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5562}
5563
5564static void alc880_auto_init_analog_input(struct hda_codec *codec)
5565{
5566 struct alc_spec *spec = codec->spec;
66ceeb6b 5567 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5568 int i;
5569
66ceeb6b
TI
5570 for (i = 0; i < cfg->num_inputs; i++) {
5571 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5572 if (alc_is_input_pin(codec, nid)) {
30ea098f 5573 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5574 if (nid != ALC880_PIN_CD_NID &&
5575 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5576 snd_hda_codec_write(codec, nid, 0,
5577 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5578 AMP_OUT_MUTE);
5579 }
5580 }
5581}
5582
7f311a46
TI
5583static void alc880_auto_init_input_src(struct hda_codec *codec)
5584{
5585 struct alc_spec *spec = codec->spec;
5586 int c;
5587
5588 for (c = 0; c < spec->num_adc_nids; c++) {
5589 unsigned int mux_idx;
5590 const struct hda_input_mux *imux;
5591 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5592 imux = &spec->input_mux[mux_idx];
5593 if (!imux->num_items && mux_idx > 0)
5594 imux = &spec->input_mux[0];
5595 if (imux)
5596 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5597 AC_VERB_SET_CONNECT_SEL,
5598 imux->items[0].index);
5599 }
5600}
5601
ce764ab2
TI
5602static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5603
e9edcee0 5604/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5605/* return 1 if successful, 0 if the proper config is not found,
5606 * or a negative error code
5607 */
e9edcee0
TI
5608static int alc880_parse_auto_config(struct hda_codec *codec)
5609{
5610 struct alc_spec *spec = codec->spec;
757899ac 5611 int err;
df694daa 5612 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5613
f12ab1e0
TI
5614 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5615 alc880_ignore);
5616 if (err < 0)
e9edcee0 5617 return err;
f12ab1e0 5618 if (!spec->autocfg.line_outs)
e9edcee0 5619 return 0; /* can't find valid BIOS pin config */
df694daa 5620
f12ab1e0 5621 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
5622 if (err < 0)
5623 return err;
5624 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
5625 if (err < 0)
5626 return err;
5627 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5628 if (err < 0)
5629 return err;
5630 err = alc880_auto_create_extra_out(spec,
5631 spec->autocfg.speaker_pins[0],
5632 "Speaker");
5633 if (err < 0)
5634 return err;
5635 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5636 "Headphone");
5637 if (err < 0)
5638 return err;
05f5f477 5639 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5640 if (err < 0)
e9edcee0
TI
5641 return err;
5642
5643 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5644
757899ac 5645 alc_auto_parse_digital(codec);
e9edcee0 5646
603c4019 5647 if (spec->kctls.list)
d88897ea 5648 add_mixer(spec, spec->kctls.list);
e9edcee0 5649
d88897ea 5650 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5651
a1e8d2da 5652 spec->num_mux_defs = 1;
61b9b9b1 5653 spec->input_mux = &spec->private_imux[0];
e9edcee0 5654
6227cdce 5655 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5656
e9edcee0
TI
5657 return 1;
5658}
5659
ae6b813a
TI
5660/* additional initialization for auto-configuration model */
5661static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5662{
f6c7e546 5663 struct alc_spec *spec = codec->spec;
e9edcee0 5664 alc880_auto_init_multi_out(codec);
8d88bc3d 5665 alc880_auto_init_extra_out(codec);
e9edcee0 5666 alc880_auto_init_analog_input(codec);
7f311a46 5667 alc880_auto_init_input_src(codec);
757899ac 5668 alc_auto_init_digital(codec);
f6c7e546 5669 if (spec->unsol_event)
7fb0d78f 5670 alc_inithook(codec);
e9edcee0
TI
5671}
5672
b59bdf3b
TI
5673/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5674 * one of two digital mic pins, e.g. on ALC272
5675 */
5676static void fixup_automic_adc(struct hda_codec *codec)
5677{
5678 struct alc_spec *spec = codec->spec;
5679 int i;
5680
5681 for (i = 0; i < spec->num_adc_nids; i++) {
5682 hda_nid_t cap = spec->capsrc_nids ?
5683 spec->capsrc_nids[i] : spec->adc_nids[i];
5684 int iidx, eidx;
5685
5686 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5687 if (iidx < 0)
5688 continue;
5689 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5690 if (eidx < 0)
5691 continue;
5692 spec->int_mic.mux_idx = iidx;
5693 spec->ext_mic.mux_idx = eidx;
5694 if (spec->capsrc_nids)
5695 spec->capsrc_nids += i;
5696 spec->adc_nids += i;
5697 spec->num_adc_nids = 1;
5698 return;
5699 }
5700 snd_printd(KERN_INFO "hda_codec: %s: "
5701 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5702 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5703 spec->auto_mic = 0; /* disable auto-mic to be sure */
5704}
5705
748cce43
TI
5706/* select or unmute the given capsrc route */
5707static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5708 int idx)
5709{
5710 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5711 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5712 HDA_AMP_MUTE, 0);
5713 } else {
5714 snd_hda_codec_write_cache(codec, cap, 0,
5715 AC_VERB_SET_CONNECT_SEL, idx);
5716 }
5717}
5718
840b64c0
TI
5719/* set the default connection to that pin */
5720static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5721{
5722 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5723 int i;
5724
eaa9b3a7
TI
5725 for (i = 0; i < spec->num_adc_nids; i++) {
5726 hda_nid_t cap = spec->capsrc_nids ?
5727 spec->capsrc_nids[i] : spec->adc_nids[i];
5728 int idx;
5729
5730 idx = get_connection_index(codec, cap, pin);
5731 if (idx < 0)
5732 continue;
748cce43 5733 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5734 return i; /* return the found index */
5735 }
5736 return -1; /* not found */
5737}
5738
5739/* choose the ADC/MUX containing the input pin and initialize the setup */
5740static void fixup_single_adc(struct hda_codec *codec)
5741{
5742 struct alc_spec *spec = codec->spec;
66ceeb6b 5743 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5744 int i;
5745
5746 /* search for the input pin; there must be only one */
66ceeb6b 5747 if (cfg->num_inputs != 1)
eaa9b3a7 5748 return;
66ceeb6b 5749 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5750 if (i >= 0) {
5751 /* use only this ADC */
5752 if (spec->capsrc_nids)
5753 spec->capsrc_nids += i;
5754 spec->adc_nids += i;
5755 spec->num_adc_nids = 1;
584c0c4c 5756 spec->single_input_src = 1;
eaa9b3a7
TI
5757 }
5758}
5759
840b64c0
TI
5760/* initialize dual adcs */
5761static void fixup_dual_adc_switch(struct hda_codec *codec)
5762{
5763 struct alc_spec *spec = codec->spec;
5764 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5765 init_capsrc_for_pin(codec, spec->int_mic.pin);
5766}
5767
584c0c4c
TI
5768/* initialize some special cases for input sources */
5769static void alc_init_special_input_src(struct hda_codec *codec)
5770{
5771 struct alc_spec *spec = codec->spec;
5772 if (spec->dual_adc_switch)
5773 fixup_dual_adc_switch(codec);
5774 else if (spec->single_input_src)
5775 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5776}
5777
b59bdf3b 5778static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5779{
b59bdf3b 5780 struct alc_spec *spec = codec->spec;
a23b688f
TI
5781 static struct snd_kcontrol_new *caps[2][3] = {
5782 { alc_capture_mixer_nosrc1,
5783 alc_capture_mixer_nosrc2,
5784 alc_capture_mixer_nosrc3 },
5785 { alc_capture_mixer1,
5786 alc_capture_mixer2,
5787 alc_capture_mixer3 },
f9e336f6 5788 };
a23b688f 5789 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5790 int mux = 0;
840b64c0
TI
5791 int num_adcs = spec->num_adc_nids;
5792 if (spec->dual_adc_switch)
584c0c4c 5793 num_adcs = 1;
840b64c0 5794 else if (spec->auto_mic)
b59bdf3b 5795 fixup_automic_adc(codec);
eaa9b3a7
TI
5796 else if (spec->input_mux) {
5797 if (spec->input_mux->num_items > 1)
5798 mux = 1;
5799 else if (spec->input_mux->num_items == 1)
5800 fixup_single_adc(codec);
5801 }
840b64c0 5802 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5803 }
f9e336f6
TI
5804}
5805
6694635d
TI
5806/* fill adc_nids (and capsrc_nids) containing all active input pins */
5807static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5808 int num_nids)
5809{
5810 struct alc_spec *spec = codec->spec;
66ceeb6b 5811 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5812 int n;
5813 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5814
5815 for (n = 0; n < num_nids; n++) {
5816 hda_nid_t adc, cap;
5817 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5818 int nconns, i, j;
5819
5820 adc = nids[n];
5821 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5822 continue;
5823 cap = adc;
5824 nconns = snd_hda_get_connections(codec, cap, conn,
5825 ARRAY_SIZE(conn));
5826 if (nconns == 1) {
5827 cap = conn[0];
5828 nconns = snd_hda_get_connections(codec, cap, conn,
5829 ARRAY_SIZE(conn));
5830 }
5831 if (nconns <= 0)
5832 continue;
5833 if (!fallback_adc) {
5834 fallback_adc = adc;
5835 fallback_cap = cap;
5836 }
66ceeb6b
TI
5837 for (i = 0; i < cfg->num_inputs; i++) {
5838 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5839 for (j = 0; j < nconns; j++) {
5840 if (conn[j] == nid)
5841 break;
5842 }
5843 if (j >= nconns)
5844 break;
5845 }
66ceeb6b 5846 if (i >= cfg->num_inputs) {
6694635d
TI
5847 int num_adcs = spec->num_adc_nids;
5848 spec->private_adc_nids[num_adcs] = adc;
5849 spec->private_capsrc_nids[num_adcs] = cap;
5850 spec->num_adc_nids++;
5851 spec->adc_nids = spec->private_adc_nids;
5852 if (adc != cap)
5853 spec->capsrc_nids = spec->private_capsrc_nids;
5854 }
5855 }
5856 if (!spec->num_adc_nids) {
5857 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5858 " using fallback 0x%x\n",
5859 codec->chip_name, fallback_adc);
6694635d
TI
5860 spec->private_adc_nids[0] = fallback_adc;
5861 spec->adc_nids = spec->private_adc_nids;
5862 if (fallback_adc != fallback_cap) {
5863 spec->private_capsrc_nids[0] = fallback_cap;
5864 spec->capsrc_nids = spec->private_adc_nids;
5865 }
5866 }
5867}
5868
67d634c0 5869#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5870#define set_beep_amp(spec, nid, idx, dir) \
5871 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5872
5873static struct snd_pci_quirk beep_white_list[] = {
5874 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5875 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5876 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5877 {}
5878};
5879
5880static inline int has_cdefine_beep(struct hda_codec *codec)
5881{
5882 struct alc_spec *spec = codec->spec;
5883 const struct snd_pci_quirk *q;
5884 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5885 if (q)
5886 return q->value;
5887 return spec->cdefine.enable_pcbeep;
5888}
67d634c0
TI
5889#else
5890#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5891#define has_cdefine_beep(codec) 0
67d634c0 5892#endif
45bdd1c1
TI
5893
5894/*
5895 * OK, here we have finally the patch for ALC880
5896 */
5897
1da177e4
LT
5898static int patch_alc880(struct hda_codec *codec)
5899{
5900 struct alc_spec *spec;
5901 int board_config;
df694daa 5902 int err;
1da177e4 5903
e560d8d8 5904 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5905 if (spec == NULL)
5906 return -ENOMEM;
5907
5908 codec->spec = spec;
5909
f5fcc13c
TI
5910 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5911 alc880_models,
5912 alc880_cfg_tbl);
5913 if (board_config < 0) {
9a11f1aa
TI
5914 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5915 codec->chip_name);
e9edcee0 5916 board_config = ALC880_AUTO;
1da177e4 5917 }
1da177e4 5918
e9edcee0
TI
5919 if (board_config == ALC880_AUTO) {
5920 /* automatic parse from the BIOS config */
5921 err = alc880_parse_auto_config(codec);
5922 if (err < 0) {
5923 alc_free(codec);
5924 return err;
f12ab1e0 5925 } else if (!err) {
9c7f852e
TI
5926 printk(KERN_INFO
5927 "hda_codec: Cannot set up configuration "
5928 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5929 board_config = ALC880_3ST;
5930 }
1da177e4
LT
5931 }
5932
680cd536
KK
5933 err = snd_hda_attach_beep_device(codec, 0x1);
5934 if (err < 0) {
5935 alc_free(codec);
5936 return err;
5937 }
5938
df694daa 5939 if (board_config != ALC880_AUTO)
e9c364c0 5940 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5941
1da177e4
LT
5942 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5943 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5944 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5945
1da177e4
LT
5946 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5947 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5948
f12ab1e0 5949 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5950 /* check whether NID 0x07 is valid */
54d17403 5951 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5952 /* get type */
a22d543a 5953 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5954 if (wcap != AC_WID_AUD_IN) {
5955 spec->adc_nids = alc880_adc_nids_alt;
5956 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5957 } else {
5958 spec->adc_nids = alc880_adc_nids;
5959 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5960 }
5961 }
b59bdf3b 5962 set_capture_mixer(codec);
45bdd1c1 5963 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5964
2134ea4f
TI
5965 spec->vmaster_nid = 0x0c;
5966
1da177e4 5967 codec->patch_ops = alc_patch_ops;
e9edcee0 5968 if (board_config == ALC880_AUTO)
ae6b813a 5969 spec->init_hook = alc880_auto_init;
cb53c626
TI
5970#ifdef CONFIG_SND_HDA_POWER_SAVE
5971 if (!spec->loopback.amplist)
5972 spec->loopback.amplist = alc880_loopbacks;
5973#endif
1da177e4
LT
5974
5975 return 0;
5976}
5977
e9edcee0 5978
1da177e4
LT
5979/*
5980 * ALC260 support
5981 */
5982
e9edcee0
TI
5983static hda_nid_t alc260_dac_nids[1] = {
5984 /* front */
5985 0x02,
5986};
5987
5988static hda_nid_t alc260_adc_nids[1] = {
5989 /* ADC0 */
5990 0x04,
5991};
5992
df694daa 5993static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5994 /* ADC1 */
5995 0x05,
5996};
5997
d57fdac0
JW
5998/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5999 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6000 */
6001static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
6002 /* ADC0, ADC1 */
6003 0x04, 0x05
6004};
6005
e9edcee0
TI
6006#define ALC260_DIGOUT_NID 0x03
6007#define ALC260_DIGIN_NID 0x06
6008
6009static struct hda_input_mux alc260_capture_source = {
6010 .num_items = 4,
6011 .items = {
6012 { "Mic", 0x0 },
6013 { "Front Mic", 0x1 },
6014 { "Line", 0x2 },
6015 { "CD", 0x4 },
6016 },
6017};
6018
17e7aec6 6019/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
6020 * headphone jack and the internal CD lines since these are the only pins at
6021 * which audio can appear. For flexibility, also allow the option of
6022 * recording the mixer output on the second ADC (ADC0 doesn't have a
6023 * connection to the mixer output).
a9430dd8 6024 */
a1e8d2da
JW
6025static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6026 {
6027 .num_items = 3,
6028 .items = {
6029 { "Mic/Line", 0x0 },
6030 { "CD", 0x4 },
6031 { "Headphone", 0x2 },
6032 },
a9430dd8 6033 },
a1e8d2da
JW
6034 {
6035 .num_items = 4,
6036 .items = {
6037 { "Mic/Line", 0x0 },
6038 { "CD", 0x4 },
6039 { "Headphone", 0x2 },
6040 { "Mixer", 0x5 },
6041 },
6042 },
6043
a9430dd8
JW
6044};
6045
a1e8d2da
JW
6046/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6047 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 6048 */
a1e8d2da
JW
6049static struct hda_input_mux alc260_acer_capture_sources[2] = {
6050 {
6051 .num_items = 4,
6052 .items = {
6053 { "Mic", 0x0 },
6054 { "Line", 0x2 },
6055 { "CD", 0x4 },
6056 { "Headphone", 0x5 },
6057 },
6058 },
6059 {
6060 .num_items = 5,
6061 .items = {
6062 { "Mic", 0x0 },
6063 { "Line", 0x2 },
6064 { "CD", 0x4 },
6065 { "Headphone", 0x6 },
6066 { "Mixer", 0x5 },
6067 },
0bfc90e9
JW
6068 },
6069};
cc959489
MS
6070
6071/* Maxdata Favorit 100XS */
6072static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6073 {
6074 .num_items = 2,
6075 .items = {
6076 { "Line/Mic", 0x0 },
6077 { "CD", 0x4 },
6078 },
6079 },
6080 {
6081 .num_items = 3,
6082 .items = {
6083 { "Line/Mic", 0x0 },
6084 { "CD", 0x4 },
6085 { "Mixer", 0x5 },
6086 },
6087 },
6088};
6089
1da177e4
LT
6090/*
6091 * This is just place-holder, so there's something for alc_build_pcms to look
6092 * at when it calculates the maximum number of channels. ALC260 has no mixer
6093 * element which allows changing the channel mode, so the verb list is
6094 * never used.
6095 */
d2a6d7dc 6096static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
6097 { 2, NULL },
6098};
6099
df694daa
KY
6100
6101/* Mixer combinations
6102 *
6103 * basic: base_output + input + pc_beep + capture
6104 * HP: base_output + input + capture_alt
6105 * HP_3013: hp_3013 + input + capture
6106 * fujitsu: fujitsu + capture
0bfc90e9 6107 * acer: acer + capture
df694daa
KY
6108 */
6109
6110static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 6111 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6112 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 6113 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 6114 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 6115 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 6116 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 6117 { } /* end */
f12ab1e0 6118};
1da177e4 6119
df694daa 6120static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
6121 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6122 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6123 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6124 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6125 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6126 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6127 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6128 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
6129 { } /* end */
6130};
6131
bec15c3a 6132/* update HP, line and mono out pins according to the master switch */
e9427969 6133static void alc260_hp_master_update(struct hda_codec *codec)
bec15c3a
TI
6134{
6135 struct alc_spec *spec = codec->spec;
e9427969
TI
6136
6137 /* change HP pins */
6138 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
6139 spec->autocfg.hp_pins, spec->master_mute, true);
6140 update_speakers(codec);
bec15c3a
TI
6141}
6142
6143static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6144 struct snd_ctl_elem_value *ucontrol)
6145{
6146 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6147 struct alc_spec *spec = codec->spec;
e9427969 6148 *ucontrol->value.integer.value = !spec->master_mute;
bec15c3a
TI
6149 return 0;
6150}
6151
6152static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6153 struct snd_ctl_elem_value *ucontrol)
6154{
6155 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6156 struct alc_spec *spec = codec->spec;
e9427969 6157 int val = !*ucontrol->value.integer.value;
bec15c3a 6158
e9427969 6159 if (val == spec->master_mute)
bec15c3a 6160 return 0;
e9427969
TI
6161 spec->master_mute = val;
6162 alc260_hp_master_update(codec);
bec15c3a
TI
6163 return 1;
6164}
6165
6166static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6167 {
6168 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6169 .name = "Master Playback Switch",
5b0cb1d8 6170 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6171 .info = snd_ctl_boolean_mono_info,
6172 .get = alc260_hp_master_sw_get,
6173 .put = alc260_hp_master_sw_put,
bec15c3a
TI
6174 },
6175 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6176 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6177 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6178 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6179 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6180 HDA_OUTPUT),
6181 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6182 { } /* end */
6183};
6184
6185static struct hda_verb alc260_hp_unsol_verbs[] = {
6186 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6187 {},
6188};
6189
e9427969 6190static void alc260_hp_setup(struct hda_codec *codec)
bec15c3a
TI
6191{
6192 struct alc_spec *spec = codec->spec;
bec15c3a 6193
e9427969
TI
6194 spec->autocfg.hp_pins[0] = 0x0f;
6195 spec->autocfg.speaker_pins[0] = 0x10;
6196 spec->autocfg.speaker_pins[1] = 0x11;
6197 spec->automute = 1;
6198 spec->automute_mode = ALC_AUTOMUTE_PIN;
bec15c3a
TI
6199}
6200
df694daa 6201static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6202 {
6203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6204 .name = "Master Playback Switch",
5b0cb1d8 6205 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6206 .info = snd_ctl_boolean_mono_info,
6207 .get = alc260_hp_master_sw_get,
6208 .put = alc260_hp_master_sw_put,
bec15c3a 6209 },
df694daa
KY
6210 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6211 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6212 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6213 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6214 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6216 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6217 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6218 { } /* end */
6219};
6220
e9427969
TI
6221static void alc260_hp_3013_setup(struct hda_codec *codec)
6222{
6223 struct alc_spec *spec = codec->spec;
6224
6225 spec->autocfg.hp_pins[0] = 0x15;
6226 spec->autocfg.speaker_pins[0] = 0x10;
6227 spec->autocfg.speaker_pins[1] = 0x11;
6228 spec->automute = 1;
6229 spec->automute_mode = ALC_AUTOMUTE_PIN;
6230}
6231
3f878308
KY
6232static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6233 .ops = &snd_hda_bind_vol,
6234 .values = {
6235 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6236 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6237 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6238 0
6239 },
6240};
6241
6242static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6243 .ops = &snd_hda_bind_sw,
6244 .values = {
6245 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6246 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6247 0
6248 },
6249};
6250
6251static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6252 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6253 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6254 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6255 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6256 { } /* end */
6257};
6258
bec15c3a
TI
6259static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6260 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6261 {},
6262};
6263
e9427969 6264static void alc260_hp_3012_setup(struct hda_codec *codec)
bec15c3a
TI
6265{
6266 struct alc_spec *spec = codec->spec;
bec15c3a 6267
e9427969
TI
6268 spec->autocfg.hp_pins[0] = 0x10;
6269 spec->autocfg.speaker_pins[0] = 0x0f;
6270 spec->autocfg.speaker_pins[1] = 0x11;
6271 spec->autocfg.speaker_pins[2] = 0x15;
6272 spec->automute = 1;
6273 spec->automute_mode = ALC_AUTOMUTE_PIN;
3f878308
KY
6274}
6275
6276/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6277 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6278 */
c8b6bf9b 6279static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6280 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6281 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6282 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6283 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6284 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6285 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6286 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6287 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6288 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6289 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6290 { } /* end */
6291};
6292
a1e8d2da
JW
6293/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6294 * versions of the ALC260 don't act on requests to enable mic bias from NID
6295 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6296 * datasheet doesn't mention this restriction. At this stage it's not clear
6297 * whether this behaviour is intentional or is a hardware bug in chip
6298 * revisions available in early 2006. Therefore for now allow the
6299 * "Headphone Jack Mode" control to span all choices, but if it turns out
6300 * that the lack of mic bias for this NID is intentional we could change the
6301 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6302 *
6303 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6304 * don't appear to make the mic bias available from the "line" jack, even
6305 * though the NID used for this jack (0x14) can supply it. The theory is
6306 * that perhaps Acer have included blocking capacitors between the ALC260
6307 * and the output jack. If this turns out to be the case for all such
6308 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6309 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6310 *
6311 * The C20x Tablet series have a mono internal speaker which is controlled
6312 * via the chip's Mono sum widget and pin complex, so include the necessary
6313 * controls for such models. On models without a "mono speaker" the control
6314 * won't do anything.
a1e8d2da 6315 */
0bfc90e9
JW
6316static struct snd_kcontrol_new alc260_acer_mixer[] = {
6317 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6318 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6319 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6320 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6321 HDA_OUTPUT),
31bffaa9 6322 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6323 HDA_INPUT),
0bfc90e9
JW
6324 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6325 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6326 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6327 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6328 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6329 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6330 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6331 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6332 { } /* end */
6333};
6334
cc959489
MS
6335/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6336 */
6337static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6338 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6339 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6340 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6341 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6342 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6343 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6344 { } /* end */
6345};
6346
bc9f98a9
KY
6347/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6348 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6349 */
6350static struct snd_kcontrol_new alc260_will_mixer[] = {
6351 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6352 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6354 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6355 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6356 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6357 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6358 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6359 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6360 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6361 { } /* end */
6362};
6363
6364/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6365 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6366 */
6367static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6368 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6369 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6371 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6372 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6373 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6374 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6375 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6376 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6377 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6378 { } /* end */
6379};
6380
df694daa
KY
6381/*
6382 * initialization verbs
6383 */
1da177e4
LT
6384static struct hda_verb alc260_init_verbs[] = {
6385 /* Line In pin widget for input */
05acb863 6386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6387 /* CD pin widget for input */
05acb863 6388 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6389 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6390 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6391 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6392 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6393 /* LINE-2 is used for line-out in rear */
05acb863 6394 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6395 /* select line-out */
fd56f2db 6396 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6397 /* LINE-OUT pin */
05acb863 6398 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6399 /* enable HP */
05acb863 6400 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6401 /* enable Mono */
05acb863
TI
6402 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6403 /* mute capture amp left and right */
16ded525 6404 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6405 /* set connection select to line in (default select for this ADC) */
6406 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6407 /* mute capture amp left and right */
6408 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6409 /* set connection select to line in (default select for this ADC) */
6410 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6411 /* set vol=0 Line-Out mixer amp left and right */
6412 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6413 /* unmute pin widget amp left and right (no gain on this amp) */
6414 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6415 /* set vol=0 HP mixer amp left and right */
6416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6417 /* unmute pin widget amp left and right (no gain on this amp) */
6418 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6419 /* set vol=0 Mono mixer amp left and right */
6420 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6421 /* unmute pin widget amp left and right (no gain on this amp) */
6422 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6423 /* unmute LINE-2 out pin */
6424 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6425 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6426 * Line In 2 = 0x03
6427 */
cb53c626
TI
6428 /* mute analog inputs */
6429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6433 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6434 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6435 /* mute Front out path */
6436 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6437 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6438 /* mute Headphone out path */
6439 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6440 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6441 /* mute Mono out path */
6442 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6443 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6444 { }
6445};
6446
474167d6 6447#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6448static struct hda_verb alc260_hp_init_verbs[] = {
6449 /* Headphone and output */
6450 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6451 /* mono output */
6452 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6453 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6454 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6455 /* Mic2 (front panel) pin widget for input and vref at 80% */
6456 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6457 /* Line In pin widget for input */
6458 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6459 /* Line-2 pin widget for output */
6460 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6461 /* CD pin widget for input */
6462 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6463 /* unmute amp left and right */
6464 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6465 /* set connection select to line in (default select for this ADC) */
6466 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6467 /* unmute Line-Out mixer amp left and right (volume = 0) */
6468 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6469 /* mute pin widget amp left and right (no gain on this amp) */
6470 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6471 /* unmute HP mixer amp left and right (volume = 0) */
6472 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6473 /* mute pin widget amp left and right (no gain on this amp) */
6474 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6475 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6476 * Line In 2 = 0x03
6477 */
cb53c626
TI
6478 /* mute analog inputs */
6479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6480 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6482 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6484 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6485 /* Unmute Front out path */
6486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6487 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6488 /* Unmute Headphone out path */
6489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6490 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6491 /* Unmute Mono out path */
6492 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6493 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6494 { }
6495};
474167d6 6496#endif
df694daa
KY
6497
6498static struct hda_verb alc260_hp_3013_init_verbs[] = {
6499 /* Line out and output */
6500 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6501 /* mono output */
6502 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6503 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6504 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6505 /* Mic2 (front panel) pin widget for input and vref at 80% */
6506 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6507 /* Line In pin widget for input */
6508 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6509 /* Headphone pin widget for output */
6510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6511 /* CD pin widget for input */
6512 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6513 /* unmute amp left and right */
6514 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6515 /* set connection select to line in (default select for this ADC) */
6516 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6517 /* unmute Line-Out mixer amp left and right (volume = 0) */
6518 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6519 /* mute pin widget amp left and right (no gain on this amp) */
6520 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6521 /* unmute HP mixer amp left and right (volume = 0) */
6522 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6523 /* mute pin widget amp left and right (no gain on this amp) */
6524 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6525 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6526 * Line In 2 = 0x03
6527 */
cb53c626
TI
6528 /* mute analog inputs */
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6534 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6535 /* Unmute Front out path */
6536 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6538 /* Unmute Headphone out path */
6539 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6541 /* Unmute Mono out path */
6542 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6543 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6544 { }
6545};
6546
a9430dd8 6547/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6548 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6549 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6550 */
6551static struct hda_verb alc260_fujitsu_init_verbs[] = {
6552 /* Disable all GPIOs */
6553 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6554 /* Internal speaker is connected to headphone pin */
6555 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6556 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6557 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6558 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6559 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6560 /* Ensure all other unused pins are disabled and muted. */
6561 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6562 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6563 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6564 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6565 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6566 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6567 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6568 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6569
6570 /* Disable digital (SPDIF) pins */
6571 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6572 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6573
ea1fb29a 6574 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6575 * when acting as an output.
6576 */
6577 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6578
f7ace40d 6579 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6581 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6582 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6584 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6585 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6587 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6588 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6589
f7ace40d
JW
6590 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6591 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6592 /* Unmute Line1 pin widget output buffer since it starts as an output.
6593 * If the pin mode is changed by the user the pin mode control will
6594 * take care of enabling the pin's input/output buffers as needed.
6595 * Therefore there's no need to enable the input buffer at this
6596 * stage.
cdcd9268 6597 */
f7ace40d 6598 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6599 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6600 * mixer ctrl)
6601 */
f7ace40d
JW
6602 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6603
6604 /* Mute capture amp left and right */
6605 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6606 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6607 * in (on mic1 pin)
6608 */
6609 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6610
6611 /* Do the same for the second ADC: mute capture input amp and
6612 * set ADC connection to line in (on mic1 pin)
6613 */
6614 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6615 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6616
6617 /* Mute all inputs to mixer widget (even unconnected ones) */
6618 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6626
6627 { }
a9430dd8
JW
6628};
6629
0bfc90e9
JW
6630/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6631 * similar laptops (adapted from Fujitsu init verbs).
6632 */
6633static struct hda_verb alc260_acer_init_verbs[] = {
6634 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6635 * the headphone jack. Turn this on and rely on the standard mute
6636 * methods whenever the user wants to turn these outputs off.
6637 */
6638 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6639 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6640 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6641 /* Internal speaker/Headphone jack is connected to Line-out pin */
6642 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6643 /* Internal microphone/Mic jack is connected to Mic1 pin */
6644 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6645 /* Line In jack is connected to Line1 pin */
6646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6647 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6648 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6649 /* Ensure all other unused pins are disabled and muted. */
6650 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6651 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6652 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6653 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6654 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6655 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6656 /* Disable digital (SPDIF) pins */
6657 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6658 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6659
ea1fb29a 6660 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6661 * bus when acting as outputs.
6662 */
6663 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6664 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6665
6666 /* Start with output sum widgets muted and their output gains at min */
6667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6668 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6669 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6670 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6671 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6672 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6673 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6674 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6675 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6676
f12ab1e0
TI
6677 /* Unmute Line-out pin widget amp left and right
6678 * (no equiv mixer ctrl)
6679 */
0bfc90e9 6680 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6681 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6682 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6683 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6684 * inputs. If the pin mode is changed by the user the pin mode control
6685 * will take care of enabling the pin's input/output buffers as needed.
6686 * Therefore there's no need to enable the input buffer at this
6687 * stage.
6688 */
6689 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6690 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6691
6692 /* Mute capture amp left and right */
6693 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6694 /* Set ADC connection select to match default mixer setting - mic
6695 * (on mic1 pin)
6696 */
6697 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6698
6699 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6700 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6701 */
6702 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6703 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6704
6705 /* Mute all inputs to mixer widget (even unconnected ones) */
6706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6708 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6709 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6710 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6712 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6714
6715 { }
6716};
6717
cc959489
MS
6718/* Initialisation sequence for Maxdata Favorit 100XS
6719 * (adapted from Acer init verbs).
6720 */
6721static struct hda_verb alc260_favorit100_init_verbs[] = {
6722 /* GPIO 0 enables the output jack.
6723 * Turn this on and rely on the standard mute
6724 * methods whenever the user wants to turn these outputs off.
6725 */
6726 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6727 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6728 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6729 /* Line/Mic input jack is connected to Mic1 pin */
6730 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6731 /* Ensure all other unused pins are disabled and muted. */
6732 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6733 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6734 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6735 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6736 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6737 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6738 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6740 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6742 /* Disable digital (SPDIF) pins */
6743 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6744 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6745
6746 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6747 * bus when acting as outputs.
6748 */
6749 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6750 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6751
6752 /* Start with output sum widgets muted and their output gains at min */
6753 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6754 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6755 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6756 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6757 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6758 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6759 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6760 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6761 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6762
6763 /* Unmute Line-out pin widget amp left and right
6764 * (no equiv mixer ctrl)
6765 */
6766 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6767 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6768 * inputs. If the pin mode is changed by the user the pin mode control
6769 * will take care of enabling the pin's input/output buffers as needed.
6770 * Therefore there's no need to enable the input buffer at this
6771 * stage.
6772 */
6773 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6774
6775 /* Mute capture amp left and right */
6776 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6777 /* Set ADC connection select to match default mixer setting - mic
6778 * (on mic1 pin)
6779 */
6780 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6781
6782 /* Do similar with the second ADC: mute capture input amp and
6783 * set ADC connection to mic to match ALSA's default state.
6784 */
6785 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6786 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6787
6788 /* Mute all inputs to mixer widget (even unconnected ones) */
6789 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6791 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6793 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6794 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6795 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6796 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6797
6798 { }
6799};
6800
bc9f98a9
KY
6801static struct hda_verb alc260_will_verbs[] = {
6802 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6803 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6804 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6805 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6806 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6807 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6808 {}
6809};
6810
6811static struct hda_verb alc260_replacer_672v_verbs[] = {
6812 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6813 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6814 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6815
6816 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6817 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6818 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6819
6820 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6821 {}
6822};
6823
6824/* toggle speaker-output according to the hp-jack state */
6825static void alc260_replacer_672v_automute(struct hda_codec *codec)
6826{
6827 unsigned int present;
6828
6829 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6830 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6831 if (present) {
82beb8fd
TI
6832 snd_hda_codec_write_cache(codec, 0x01, 0,
6833 AC_VERB_SET_GPIO_DATA, 1);
6834 snd_hda_codec_write_cache(codec, 0x0f, 0,
6835 AC_VERB_SET_PIN_WIDGET_CONTROL,
6836 PIN_HP);
bc9f98a9 6837 } else {
82beb8fd
TI
6838 snd_hda_codec_write_cache(codec, 0x01, 0,
6839 AC_VERB_SET_GPIO_DATA, 0);
6840 snd_hda_codec_write_cache(codec, 0x0f, 0,
6841 AC_VERB_SET_PIN_WIDGET_CONTROL,
6842 PIN_OUT);
bc9f98a9
KY
6843 }
6844}
6845
6846static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6847 unsigned int res)
6848{
6849 if ((res >> 26) == ALC880_HP_EVENT)
6850 alc260_replacer_672v_automute(codec);
6851}
6852
3f878308
KY
6853static struct hda_verb alc260_hp_dc7600_verbs[] = {
6854 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6855 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6856 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6857 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6858 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6859 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6860 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6861 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6862 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6863 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6864 {}
6865};
6866
7cf51e48
JW
6867/* Test configuration for debugging, modelled after the ALC880 test
6868 * configuration.
6869 */
6870#ifdef CONFIG_SND_DEBUG
6871static hda_nid_t alc260_test_dac_nids[1] = {
6872 0x02,
6873};
6874static hda_nid_t alc260_test_adc_nids[2] = {
6875 0x04, 0x05,
6876};
a1e8d2da 6877/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6878 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6879 * is NID 0x04.
17e7aec6 6880 */
a1e8d2da
JW
6881static struct hda_input_mux alc260_test_capture_sources[2] = {
6882 {
6883 .num_items = 7,
6884 .items = {
6885 { "MIC1 pin", 0x0 },
6886 { "MIC2 pin", 0x1 },
6887 { "LINE1 pin", 0x2 },
6888 { "LINE2 pin", 0x3 },
6889 { "CD pin", 0x4 },
6890 { "LINE-OUT pin", 0x5 },
6891 { "HP-OUT pin", 0x6 },
6892 },
6893 },
6894 {
6895 .num_items = 8,
6896 .items = {
6897 { "MIC1 pin", 0x0 },
6898 { "MIC2 pin", 0x1 },
6899 { "LINE1 pin", 0x2 },
6900 { "LINE2 pin", 0x3 },
6901 { "CD pin", 0x4 },
6902 { "Mixer", 0x5 },
6903 { "LINE-OUT pin", 0x6 },
6904 { "HP-OUT pin", 0x7 },
6905 },
7cf51e48
JW
6906 },
6907};
6908static struct snd_kcontrol_new alc260_test_mixer[] = {
6909 /* Output driver widgets */
6910 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6911 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6912 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6913 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6914 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6915 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6916
a1e8d2da
JW
6917 /* Modes for retasking pin widgets
6918 * Note: the ALC260 doesn't seem to act on requests to enable mic
6919 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6920 * mention this restriction. At this stage it's not clear whether
6921 * this behaviour is intentional or is a hardware bug in chip
6922 * revisions available at least up until early 2006. Therefore for
6923 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6924 * choices, but if it turns out that the lack of mic bias for these
6925 * NIDs is intentional we could change their modes from
6926 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6927 */
7cf51e48
JW
6928 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6929 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6930 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6931 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6932 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6933 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6934
6935 /* Loopback mixer controls */
6936 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6937 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6938 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6939 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6940 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6941 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6942 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6943 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6944 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6945 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6946 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6947 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6948 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6949 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6950
6951 /* Controls for GPIO pins, assuming they are configured as outputs */
6952 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6953 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6954 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6955 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6956
92621f13
JW
6957 /* Switches to allow the digital IO pins to be enabled. The datasheet
6958 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6959 * make this output available should provide clarification.
92621f13
JW
6960 */
6961 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6962 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6963
f8225f6d
JW
6964 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6965 * this output to turn on an external amplifier.
6966 */
6967 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6968 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6969
7cf51e48
JW
6970 { } /* end */
6971};
6972static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6973 /* Enable all GPIOs as outputs with an initial value of 0 */
6974 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6975 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6976 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6977
7cf51e48
JW
6978 /* Enable retasking pins as output, initially without power amp */
6979 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6980 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6981 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6982 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6983 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6984 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6985
92621f13
JW
6986 /* Disable digital (SPDIF) pins initially, but users can enable
6987 * them via a mixer switch. In the case of SPDIF-out, this initverb
6988 * payload also sets the generation to 0, output to be in "consumer"
6989 * PCM format, copyright asserted, no pre-emphasis and no validity
6990 * control.
6991 */
7cf51e48
JW
6992 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6993 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6994
ea1fb29a 6995 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6996 * OUT1 sum bus when acting as an output.
6997 */
6998 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6999 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7000 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7001 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7002
7003 /* Start with output sum widgets muted and their output gains at min */
7004 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7006 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7007 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7008 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7010 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7011 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7012 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7013
cdcd9268
JW
7014 /* Unmute retasking pin widget output buffers since the default
7015 * state appears to be output. As the pin mode is changed by the
7016 * user the pin mode control will take care of enabling the pin's
7017 * input/output buffers as needed.
7018 */
7cf51e48
JW
7019 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7021 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7022 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7023 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7024 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7025 /* Also unmute the mono-out pin widget */
7026 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7027
7cf51e48
JW
7028 /* Mute capture amp left and right */
7029 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
7030 /* Set ADC connection select to match default mixer setting (mic1
7031 * pin)
7cf51e48
JW
7032 */
7033 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7034
7035 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 7036 * set ADC connection to mic1 pin
7cf51e48
JW
7037 */
7038 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7039 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7040
7041 /* Mute all inputs to mixer widget (even unconnected ones) */
7042 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7043 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7044 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7046 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7047 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7048 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7049 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7050
7051 { }
7052};
7053#endif
7054
6330079f
TI
7055#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7056#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 7057
a3bcba38
TI
7058#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7059#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7060
df694daa
KY
7061/*
7062 * for BIOS auto-configuration
7063 */
16ded525 7064
df694daa 7065static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 7066 const char *pfx, int *vol_bits)
df694daa
KY
7067{
7068 hda_nid_t nid_vol;
7069 unsigned long vol_val, sw_val;
df694daa
KY
7070 int err;
7071
7072 if (nid >= 0x0f && nid < 0x11) {
7073 nid_vol = nid - 0x7;
7074 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7075 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7076 } else if (nid == 0x11) {
7077 nid_vol = nid - 0x7;
7078 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7079 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7080 } else if (nid >= 0x12 && nid <= 0x15) {
7081 nid_vol = 0x08;
7082 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7083 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7084 } else
7085 return 0; /* N/A */
ea1fb29a 7086
863b4518
TI
7087 if (!(*vol_bits & (1 << nid_vol))) {
7088 /* first control for the volume widget */
0afe5f89 7089 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
7090 if (err < 0)
7091 return err;
7092 *vol_bits |= (1 << nid_vol);
7093 }
0afe5f89 7094 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 7095 if (err < 0)
df694daa
KY
7096 return err;
7097 return 1;
7098}
7099
7100/* add playback controls from the parsed DAC table */
7101static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7102 const struct auto_pin_cfg *cfg)
7103{
7104 hda_nid_t nid;
7105 int err;
863b4518 7106 int vols = 0;
df694daa
KY
7107
7108 spec->multiout.num_dacs = 1;
7109 spec->multiout.dac_nids = spec->private_dac_nids;
7110 spec->multiout.dac_nids[0] = 0x02;
7111
7112 nid = cfg->line_out_pins[0];
7113 if (nid) {
23112d6d
TI
7114 const char *pfx;
7115 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7116 pfx = "Master";
7117 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7118 pfx = "Speaker";
7119 else
7120 pfx = "Front";
7121 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
7122 if (err < 0)
7123 return err;
7124 }
7125
82bc955f 7126 nid = cfg->speaker_pins[0];
df694daa 7127 if (nid) {
863b4518 7128 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
7129 if (err < 0)
7130 return err;
7131 }
7132
eb06ed8f 7133 nid = cfg->hp_pins[0];
df694daa 7134 if (nid) {
863b4518
TI
7135 err = alc260_add_playback_controls(spec, nid, "Headphone",
7136 &vols);
df694daa
KY
7137 if (err < 0)
7138 return err;
7139 }
f12ab1e0 7140 return 0;
df694daa
KY
7141}
7142
7143/* create playback/capture controls for input pins */
05f5f477 7144static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
7145 const struct auto_pin_cfg *cfg)
7146{
05f5f477 7147 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
7148}
7149
7150static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7151 hda_nid_t nid, int pin_type,
7152 int sel_idx)
7153{
f6c7e546 7154 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7155 /* need the manual connection? */
7156 if (nid >= 0x12) {
7157 int idx = nid - 0x12;
7158 snd_hda_codec_write(codec, idx + 0x0b, 0,
7159 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
7160 }
7161}
7162
7163static void alc260_auto_init_multi_out(struct hda_codec *codec)
7164{
7165 struct alc_spec *spec = codec->spec;
7166 hda_nid_t nid;
7167
f12ab1e0 7168 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7169 if (nid) {
7170 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7171 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7172 }
ea1fb29a 7173
82bc955f 7174 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7175 if (nid)
7176 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7177
eb06ed8f 7178 nid = spec->autocfg.hp_pins[0];
df694daa 7179 if (nid)
baba8ee9 7180 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 7181}
df694daa
KY
7182
7183#define ALC260_PIN_CD_NID 0x16
7184static void alc260_auto_init_analog_input(struct hda_codec *codec)
7185{
7186 struct alc_spec *spec = codec->spec;
66ceeb6b 7187 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
7188 int i;
7189
66ceeb6b
TI
7190 for (i = 0; i < cfg->num_inputs; i++) {
7191 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 7192 if (nid >= 0x12) {
30ea098f 7193 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
7194 if (nid != ALC260_PIN_CD_NID &&
7195 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
7196 snd_hda_codec_write(codec, nid, 0,
7197 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
7198 AMP_OUT_MUTE);
7199 }
7200 }
7201}
7202
7f311a46
TI
7203#define alc260_auto_init_input_src alc880_auto_init_input_src
7204
df694daa
KY
7205/*
7206 * generic initialization of ADC, input mixers and output mixers
7207 */
7208static struct hda_verb alc260_volume_init_verbs[] = {
7209 /*
7210 * Unmute ADC0-1 and set the default input to mic-in
7211 */
7212 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7213 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7214 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7215 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7216
df694daa
KY
7217 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7218 * mixer widget
f12ab1e0
TI
7219 * Note: PASD motherboards uses the Line In 2 as the input for
7220 * front panel mic (mic 2)
df694daa
KY
7221 */
7222 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7223 /* mute analog inputs */
7224 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7229
7230 /*
7231 * Set up output mixers (0x08 - 0x0a)
7232 */
7233 /* set vol=0 to output mixers */
7234 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7235 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7236 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7237 /* set up input amps for analog loopback */
7238 /* Amp Indices: DAC = 0, mixer = 1 */
7239 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7240 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7241 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7242 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7243 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7244 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7245
df694daa
KY
7246 { }
7247};
7248
7249static int alc260_parse_auto_config(struct hda_codec *codec)
7250{
7251 struct alc_spec *spec = codec->spec;
df694daa
KY
7252 int err;
7253 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7254
f12ab1e0
TI
7255 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7256 alc260_ignore);
7257 if (err < 0)
df694daa 7258 return err;
f12ab1e0
TI
7259 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7260 if (err < 0)
4a471b7d 7261 return err;
603c4019 7262 if (!spec->kctls.list)
df694daa 7263 return 0; /* can't find valid BIOS pin config */
05f5f477 7264 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7265 if (err < 0)
df694daa
KY
7266 return err;
7267
7268 spec->multiout.max_channels = 2;
7269
0852d7a6 7270 if (spec->autocfg.dig_outs)
df694daa 7271 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7272 if (spec->kctls.list)
d88897ea 7273 add_mixer(spec, spec->kctls.list);
df694daa 7274
d88897ea 7275 add_verb(spec, alc260_volume_init_verbs);
df694daa 7276
a1e8d2da 7277 spec->num_mux_defs = 1;
61b9b9b1 7278 spec->input_mux = &spec->private_imux[0];
df694daa 7279
6227cdce 7280 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7281
df694daa
KY
7282 return 1;
7283}
7284
ae6b813a
TI
7285/* additional initialization for auto-configuration model */
7286static void alc260_auto_init(struct hda_codec *codec)
df694daa 7287{
f6c7e546 7288 struct alc_spec *spec = codec->spec;
df694daa
KY
7289 alc260_auto_init_multi_out(codec);
7290 alc260_auto_init_analog_input(codec);
7f311a46 7291 alc260_auto_init_input_src(codec);
757899ac 7292 alc_auto_init_digital(codec);
f6c7e546 7293 if (spec->unsol_event)
7fb0d78f 7294 alc_inithook(codec);
df694daa
KY
7295}
7296
cb53c626
TI
7297#ifdef CONFIG_SND_HDA_POWER_SAVE
7298static struct hda_amp_list alc260_loopbacks[] = {
7299 { 0x07, HDA_INPUT, 0 },
7300 { 0x07, HDA_INPUT, 1 },
7301 { 0x07, HDA_INPUT, 2 },
7302 { 0x07, HDA_INPUT, 3 },
7303 { 0x07, HDA_INPUT, 4 },
7304 { } /* end */
7305};
7306#endif
7307
fc091769
TI
7308/*
7309 * Pin config fixes
7310 */
7311enum {
7312 PINFIX_HP_DC5750,
7313};
7314
fc091769
TI
7315static const struct alc_fixup alc260_fixups[] = {
7316 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7317 .type = ALC_FIXUP_PINS,
7318 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7319 { 0x11, 0x90130110 }, /* speaker */
7320 { }
7321 }
fc091769
TI
7322 },
7323};
7324
7325static struct snd_pci_quirk alc260_fixup_tbl[] = {
7326 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7327 {}
7328};
7329
df694daa
KY
7330/*
7331 * ALC260 configurations
7332 */
ea734963 7333static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7334 [ALC260_BASIC] = "basic",
7335 [ALC260_HP] = "hp",
7336 [ALC260_HP_3013] = "hp-3013",
2922c9af 7337 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7338 [ALC260_FUJITSU_S702X] = "fujitsu",
7339 [ALC260_ACER] = "acer",
bc9f98a9
KY
7340 [ALC260_WILL] = "will",
7341 [ALC260_REPLACER_672V] = "replacer",
cc959489 7342 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7343#ifdef CONFIG_SND_DEBUG
f5fcc13c 7344 [ALC260_TEST] = "test",
7cf51e48 7345#endif
f5fcc13c
TI
7346 [ALC260_AUTO] = "auto",
7347};
7348
7349static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7350 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7351 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7352 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7353 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7354 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7355 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7356 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7357 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7358 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7359 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7360 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7361 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7362 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7363 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7364 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7365 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7366 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7367 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7368 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7369 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7370 {}
7371};
7372
7373static struct alc_config_preset alc260_presets[] = {
7374 [ALC260_BASIC] = {
7375 .mixers = { alc260_base_output_mixer,
45bdd1c1 7376 alc260_input_mixer },
df694daa
KY
7377 .init_verbs = { alc260_init_verbs },
7378 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7379 .dac_nids = alc260_dac_nids,
f9e336f6 7380 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7381 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7382 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7383 .channel_mode = alc260_modes,
7384 .input_mux = &alc260_capture_source,
7385 },
7386 [ALC260_HP] = {
bec15c3a 7387 .mixers = { alc260_hp_output_mixer,
f9e336f6 7388 alc260_input_mixer },
bec15c3a
TI
7389 .init_verbs = { alc260_init_verbs,
7390 alc260_hp_unsol_verbs },
df694daa
KY
7391 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7392 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7393 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7394 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7395 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7396 .channel_mode = alc260_modes,
7397 .input_mux = &alc260_capture_source,
e9427969
TI
7398 .unsol_event = alc_sku_unsol_event,
7399 .setup = alc260_hp_setup,
7400 .init_hook = alc_inithook,
df694daa 7401 },
3f878308
KY
7402 [ALC260_HP_DC7600] = {
7403 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7404 alc260_input_mixer },
3f878308
KY
7405 .init_verbs = { alc260_init_verbs,
7406 alc260_hp_dc7600_verbs },
7407 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7408 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7409 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7410 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7411 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7412 .channel_mode = alc260_modes,
7413 .input_mux = &alc260_capture_source,
e9427969
TI
7414 .unsol_event = alc_sku_unsol_event,
7415 .setup = alc260_hp_3012_setup,
7416 .init_hook = alc_inithook,
3f878308 7417 },
df694daa
KY
7418 [ALC260_HP_3013] = {
7419 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7420 alc260_input_mixer },
bec15c3a
TI
7421 .init_verbs = { alc260_hp_3013_init_verbs,
7422 alc260_hp_3013_unsol_verbs },
df694daa
KY
7423 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7424 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7425 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7426 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7427 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7428 .channel_mode = alc260_modes,
7429 .input_mux = &alc260_capture_source,
e9427969
TI
7430 .unsol_event = alc_sku_unsol_event,
7431 .setup = alc260_hp_3013_setup,
7432 .init_hook = alc_inithook,
df694daa
KY
7433 },
7434 [ALC260_FUJITSU_S702X] = {
f9e336f6 7435 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7436 .init_verbs = { alc260_fujitsu_init_verbs },
7437 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7438 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7439 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7440 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7441 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7442 .channel_mode = alc260_modes,
a1e8d2da
JW
7443 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7444 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7445 },
0bfc90e9 7446 [ALC260_ACER] = {
f9e336f6 7447 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7448 .init_verbs = { alc260_acer_init_verbs },
7449 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7450 .dac_nids = alc260_dac_nids,
7451 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7452 .adc_nids = alc260_dual_adc_nids,
7453 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7454 .channel_mode = alc260_modes,
a1e8d2da
JW
7455 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7456 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7457 },
cc959489
MS
7458 [ALC260_FAVORIT100] = {
7459 .mixers = { alc260_favorit100_mixer },
7460 .init_verbs = { alc260_favorit100_init_verbs },
7461 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7462 .dac_nids = alc260_dac_nids,
7463 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7464 .adc_nids = alc260_dual_adc_nids,
7465 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7466 .channel_mode = alc260_modes,
7467 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7468 .input_mux = alc260_favorit100_capture_sources,
7469 },
bc9f98a9 7470 [ALC260_WILL] = {
f9e336f6 7471 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7472 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7473 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7474 .dac_nids = alc260_dac_nids,
7475 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7476 .adc_nids = alc260_adc_nids,
7477 .dig_out_nid = ALC260_DIGOUT_NID,
7478 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7479 .channel_mode = alc260_modes,
7480 .input_mux = &alc260_capture_source,
7481 },
7482 [ALC260_REPLACER_672V] = {
f9e336f6 7483 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7484 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7485 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7486 .dac_nids = alc260_dac_nids,
7487 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7488 .adc_nids = alc260_adc_nids,
7489 .dig_out_nid = ALC260_DIGOUT_NID,
7490 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7491 .channel_mode = alc260_modes,
7492 .input_mux = &alc260_capture_source,
7493 .unsol_event = alc260_replacer_672v_unsol_event,
7494 .init_hook = alc260_replacer_672v_automute,
7495 },
7cf51e48
JW
7496#ifdef CONFIG_SND_DEBUG
7497 [ALC260_TEST] = {
f9e336f6 7498 .mixers = { alc260_test_mixer },
7cf51e48
JW
7499 .init_verbs = { alc260_test_init_verbs },
7500 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7501 .dac_nids = alc260_test_dac_nids,
7502 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7503 .adc_nids = alc260_test_adc_nids,
7504 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7505 .channel_mode = alc260_modes,
a1e8d2da
JW
7506 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7507 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7508 },
7509#endif
df694daa
KY
7510};
7511
7512static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7513{
7514 struct alc_spec *spec;
df694daa 7515 int err, board_config;
1da177e4 7516
e560d8d8 7517 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7518 if (spec == NULL)
7519 return -ENOMEM;
7520
7521 codec->spec = spec;
7522
f5fcc13c
TI
7523 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7524 alc260_models,
7525 alc260_cfg_tbl);
7526 if (board_config < 0) {
9a11f1aa 7527 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7528 codec->chip_name);
df694daa 7529 board_config = ALC260_AUTO;
16ded525 7530 }
1da177e4 7531
b5bfbc67
TI
7532 if (board_config == ALC260_AUTO) {
7533 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7534 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7535 }
fc091769 7536
df694daa
KY
7537 if (board_config == ALC260_AUTO) {
7538 /* automatic parse from the BIOS config */
7539 err = alc260_parse_auto_config(codec);
7540 if (err < 0) {
7541 alc_free(codec);
7542 return err;
f12ab1e0 7543 } else if (!err) {
9c7f852e
TI
7544 printk(KERN_INFO
7545 "hda_codec: Cannot set up configuration "
7546 "from BIOS. Using base mode...\n");
df694daa
KY
7547 board_config = ALC260_BASIC;
7548 }
a9430dd8 7549 }
e9edcee0 7550
680cd536
KK
7551 err = snd_hda_attach_beep_device(codec, 0x1);
7552 if (err < 0) {
7553 alc_free(codec);
7554 return err;
7555 }
7556
df694daa 7557 if (board_config != ALC260_AUTO)
e9c364c0 7558 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7559
1da177e4
LT
7560 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7561 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7562 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7563
a3bcba38
TI
7564 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7565 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7566
4ef0ef19
TI
7567 if (!spec->adc_nids && spec->input_mux) {
7568 /* check whether NID 0x04 is valid */
7569 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7570 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7571 /* get type */
7572 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7573 spec->adc_nids = alc260_adc_nids_alt;
7574 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7575 } else {
7576 spec->adc_nids = alc260_adc_nids;
7577 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7578 }
7579 }
b59bdf3b 7580 set_capture_mixer(codec);
45bdd1c1 7581 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7582
b5bfbc67 7583 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7584
2134ea4f
TI
7585 spec->vmaster_nid = 0x08;
7586
1da177e4 7587 codec->patch_ops = alc_patch_ops;
df694daa 7588 if (board_config == ALC260_AUTO)
ae6b813a 7589 spec->init_hook = alc260_auto_init;
1c716153 7590 spec->shutup = alc_eapd_shutup;
cb53c626
TI
7591#ifdef CONFIG_SND_HDA_POWER_SAVE
7592 if (!spec->loopback.amplist)
7593 spec->loopback.amplist = alc260_loopbacks;
7594#endif
1da177e4
LT
7595
7596 return 0;
7597}
7598
e9edcee0 7599
1da177e4 7600/*
4953550a 7601 * ALC882/883/885/888/889 support
1da177e4
LT
7602 *
7603 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7604 * configuration. Each pin widget can choose any input DACs and a mixer.
7605 * Each ADC is connected from a mixer of all inputs. This makes possible
7606 * 6-channel independent captures.
7607 *
7608 * In addition, an independent DAC for the multi-playback (not used in this
7609 * driver yet).
7610 */
df694daa
KY
7611#define ALC882_DIGOUT_NID 0x06
7612#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7613#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7614#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7615#define ALC1200_DIGOUT_NID 0x10
7616
1da177e4 7617
d2a6d7dc 7618static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7619 { 8, NULL }
7620};
7621
4953550a 7622/* DACs */
1da177e4
LT
7623static hda_nid_t alc882_dac_nids[4] = {
7624 /* front, rear, clfe, rear_surr */
7625 0x02, 0x03, 0x04, 0x05
7626};
4953550a 7627#define alc883_dac_nids alc882_dac_nids
1da177e4 7628
4953550a 7629/* ADCs */
df694daa
KY
7630#define alc882_adc_nids alc880_adc_nids
7631#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7632#define alc883_adc_nids alc882_adc_nids_alt
7633static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7634static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7635#define alc889_adc_nids alc880_adc_nids
1da177e4 7636
e1406348
TI
7637static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7638static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7639#define alc883_capsrc_nids alc882_capsrc_nids_alt
7640static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7641#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7642
1da177e4
LT
7643/* input MUX */
7644/* FIXME: should be a matrix-type input source selection */
7645
7646static struct hda_input_mux alc882_capture_source = {
7647 .num_items = 4,
7648 .items = {
7649 { "Mic", 0x0 },
7650 { "Front Mic", 0x1 },
7651 { "Line", 0x2 },
7652 { "CD", 0x4 },
7653 },
7654};
41d5545d 7655
4953550a
TI
7656#define alc883_capture_source alc882_capture_source
7657
87a8c370
JK
7658static struct hda_input_mux alc889_capture_source = {
7659 .num_items = 3,
7660 .items = {
7661 { "Front Mic", 0x0 },
7662 { "Mic", 0x3 },
7663 { "Line", 0x2 },
7664 },
7665};
7666
41d5545d
KS
7667static struct hda_input_mux mb5_capture_source = {
7668 .num_items = 3,
7669 .items = {
7670 { "Mic", 0x1 },
b8f171e7 7671 { "Line", 0x7 },
41d5545d
KS
7672 { "CD", 0x4 },
7673 },
7674};
7675
e458b1fa
LY
7676static struct hda_input_mux macmini3_capture_source = {
7677 .num_items = 2,
7678 .items = {
7679 { "Line", 0x2 },
7680 { "CD", 0x4 },
7681 },
7682};
7683
4953550a
TI
7684static struct hda_input_mux alc883_3stack_6ch_intel = {
7685 .num_items = 4,
7686 .items = {
7687 { "Mic", 0x1 },
7688 { "Front Mic", 0x0 },
7689 { "Line", 0x2 },
7690 { "CD", 0x4 },
7691 },
7692};
7693
7694static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7695 .num_items = 2,
7696 .items = {
7697 { "Mic", 0x1 },
7698 { "Line", 0x2 },
7699 },
7700};
7701
7702static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7703 .num_items = 4,
7704 .items = {
7705 { "Mic", 0x0 },
28c4edb7 7706 { "Internal Mic", 0x1 },
4953550a
TI
7707 { "Line", 0x2 },
7708 { "CD", 0x4 },
7709 },
7710};
7711
7712static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7713 .num_items = 2,
7714 .items = {
7715 { "Mic", 0x0 },
28c4edb7 7716 { "Internal Mic", 0x1 },
4953550a
TI
7717 },
7718};
7719
7720static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7721 .num_items = 3,
7722 .items = {
7723 { "Mic", 0x0 },
7724 { "Front Mic", 0x1 },
7725 { "Line", 0x4 },
7726 },
7727};
7728
7729static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7730 .num_items = 2,
7731 .items = {
7732 { "Mic", 0x0 },
7733 { "Line", 0x2 },
7734 },
7735};
7736
7737static struct hda_input_mux alc889A_mb31_capture_source = {
7738 .num_items = 2,
7739 .items = {
7740 { "Mic", 0x0 },
7741 /* Front Mic (0x01) unused */
7742 { "Line", 0x2 },
7743 /* Line 2 (0x03) unused */
af901ca1 7744 /* CD (0x04) unused? */
4953550a
TI
7745 },
7746};
7747
b7cccc52
JM
7748static struct hda_input_mux alc889A_imac91_capture_source = {
7749 .num_items = 2,
7750 .items = {
7751 { "Mic", 0x01 },
7752 { "Line", 0x2 }, /* Not sure! */
7753 },
7754};
7755
4953550a
TI
7756/*
7757 * 2ch mode
7758 */
7759static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7760 { 2, NULL }
7761};
7762
272a527c
KY
7763/*
7764 * 2ch mode
7765 */
7766static struct hda_verb alc882_3ST_ch2_init[] = {
7767 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7768 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7769 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7770 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7771 { } /* end */
7772};
7773
4953550a
TI
7774/*
7775 * 4ch mode
7776 */
7777static struct hda_verb alc882_3ST_ch4_init[] = {
7778 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7779 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7780 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7781 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7782 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7783 { } /* end */
7784};
7785
272a527c
KY
7786/*
7787 * 6ch mode
7788 */
7789static struct hda_verb alc882_3ST_ch6_init[] = {
7790 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7791 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7792 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7793 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7794 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7795 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7796 { } /* end */
7797};
7798
4953550a 7799static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7800 { 2, alc882_3ST_ch2_init },
4953550a 7801 { 4, alc882_3ST_ch4_init },
272a527c
KY
7802 { 6, alc882_3ST_ch6_init },
7803};
7804
4953550a
TI
7805#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7806
a65cc60f 7807/*
7808 * 2ch mode
7809 */
7810static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7811 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7812 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7813 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7814 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7815 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7816 { } /* end */
7817};
7818
7819/*
7820 * 4ch mode
7821 */
7822static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7823 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7824 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7825 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7826 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7827 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7828 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7829 { } /* end */
7830};
7831
7832/*
7833 * 6ch mode
7834 */
7835static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7836 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7837 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7838 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7839 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7840 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7841 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7842 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7843 { } /* end */
7844};
7845
7846static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7847 { 2, alc883_3ST_ch2_clevo_init },
7848 { 4, alc883_3ST_ch4_clevo_init },
7849 { 6, alc883_3ST_ch6_clevo_init },
7850};
7851
7852
df694daa
KY
7853/*
7854 * 6ch mode
7855 */
7856static struct hda_verb alc882_sixstack_ch6_init[] = {
7857 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7858 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7859 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7860 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7861 { } /* end */
7862};
7863
7864/*
7865 * 8ch mode
7866 */
7867static struct hda_verb alc882_sixstack_ch8_init[] = {
7868 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7869 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7870 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7871 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7872 { } /* end */
7873};
7874
7875static struct hda_channel_mode alc882_sixstack_modes[2] = {
7876 { 6, alc882_sixstack_ch6_init },
7877 { 8, alc882_sixstack_ch8_init },
7878};
7879
76e6f5a9
RH
7880
7881/* Macbook Air 2,1 */
7882
7883static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7884 { 2, NULL },
7885};
7886
87350ad0 7887/*
def319f9 7888 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7889 */
7890
7891/*
7892 * 2ch mode
7893 */
7894static struct hda_verb alc885_mbp_ch2_init[] = {
7895 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7896 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7897 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7898 { } /* end */
7899};
7900
7901/*
a3f730af 7902 * 4ch mode
87350ad0 7903 */
a3f730af 7904static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7905 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7906 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7907 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7908 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7909 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7910 { } /* end */
7911};
7912
a3f730af 7913static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7914 { 2, alc885_mbp_ch2_init },
a3f730af 7915 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7916};
7917
92b9de83
KS
7918/*
7919 * 2ch
7920 * Speakers/Woofer/HP = Front
7921 * LineIn = Input
7922 */
7923static struct hda_verb alc885_mb5_ch2_init[] = {
7924 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7925 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7926 { } /* end */
7927};
7928
7929/*
7930 * 6ch mode
7931 * Speakers/HP = Front
7932 * Woofer = LFE
7933 * LineIn = Surround
7934 */
7935static struct hda_verb alc885_mb5_ch6_init[] = {
7936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7937 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7938 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7939 { } /* end */
7940};
7941
7942static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7943 { 2, alc885_mb5_ch2_init },
7944 { 6, alc885_mb5_ch6_init },
7945};
87350ad0 7946
d01aecdf 7947#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7948
7949/*
7950 * 2ch mode
7951 */
7952static struct hda_verb alc883_4ST_ch2_init[] = {
7953 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7954 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7955 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7956 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7957 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7958 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7959 { } /* end */
7960};
7961
7962/*
7963 * 4ch mode
7964 */
7965static struct hda_verb alc883_4ST_ch4_init[] = {
7966 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7967 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7968 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7969 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7970 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7971 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7972 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7973 { } /* end */
7974};
7975
7976/*
7977 * 6ch mode
7978 */
7979static struct hda_verb alc883_4ST_ch6_init[] = {
7980 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7981 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7982 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7983 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7984 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7985 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7986 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7987 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7988 { } /* end */
7989};
7990
7991/*
7992 * 8ch mode
7993 */
7994static struct hda_verb alc883_4ST_ch8_init[] = {
7995 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7996 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7997 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7998 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7999 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8000 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8001 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8002 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8003 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8004 { } /* end */
8005};
8006
8007static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
8008 { 2, alc883_4ST_ch2_init },
8009 { 4, alc883_4ST_ch4_init },
8010 { 6, alc883_4ST_ch6_init },
8011 { 8, alc883_4ST_ch8_init },
8012};
8013
8014
8015/*
8016 * 2ch mode
8017 */
8018static struct hda_verb alc883_3ST_ch2_intel_init[] = {
8019 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8020 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8021 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8022 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8023 { } /* end */
8024};
8025
8026/*
8027 * 4ch mode
8028 */
8029static struct hda_verb alc883_3ST_ch4_intel_init[] = {
8030 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8031 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8032 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8033 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8034 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8035 { } /* end */
8036};
8037
8038/*
8039 * 6ch mode
8040 */
8041static struct hda_verb alc883_3ST_ch6_intel_init[] = {
8042 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8043 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8044 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8045 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8046 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8047 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8048 { } /* end */
8049};
8050
8051static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
8052 { 2, alc883_3ST_ch2_intel_init },
8053 { 4, alc883_3ST_ch4_intel_init },
8054 { 6, alc883_3ST_ch6_intel_init },
8055};
8056
dd7714c9
WF
8057/*
8058 * 2ch mode
8059 */
8060static struct hda_verb alc889_ch2_intel_init[] = {
8061 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8062 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8063 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8064 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8065 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8066 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8067 { } /* end */
8068};
8069
87a8c370
JK
8070/*
8071 * 6ch mode
8072 */
8073static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
8074 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8075 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8076 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8077 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8078 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
8079 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8080 { } /* end */
8081};
8082
8083/*
8084 * 8ch mode
8085 */
8086static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
8087 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8088 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8089 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8090 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8091 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
8092 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8093 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
8094 { } /* end */
8095};
8096
dd7714c9
WF
8097static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8098 { 2, alc889_ch2_intel_init },
87a8c370
JK
8099 { 6, alc889_ch6_intel_init },
8100 { 8, alc889_ch8_intel_init },
8101};
8102
4953550a
TI
8103/*
8104 * 6ch mode
8105 */
8106static struct hda_verb alc883_sixstack_ch6_init[] = {
8107 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8108 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8109 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8110 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8111 { } /* end */
8112};
8113
8114/*
8115 * 8ch mode
8116 */
8117static struct hda_verb alc883_sixstack_ch8_init[] = {
8118 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8119 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8120 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8121 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8122 { } /* end */
8123};
8124
8125static struct hda_channel_mode alc883_sixstack_modes[2] = {
8126 { 6, alc883_sixstack_ch6_init },
8127 { 8, alc883_sixstack_ch8_init },
8128};
8129
8130
1da177e4
LT
8131/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8132 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8133 */
c8b6bf9b 8134static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 8135 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 8136 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 8137 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 8138 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
8139 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8140 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
8141 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8142 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 8143 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 8144 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
8145 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8146 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8147 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8148 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8149 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8150 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8151 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
8152 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8153 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8154 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8155 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8156 { } /* end */
8157};
8158
76e6f5a9
RH
8159/* Macbook Air 2,1 same control for HP and internal Speaker */
8160
8161static struct snd_kcontrol_new alc885_mba21_mixer[] = {
8162 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8163 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8164 { }
8165};
8166
8167
87350ad0 8168static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8169 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8170 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8171 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8172 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8173 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8174 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8175 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8177 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8178 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8179 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8180 { } /* end */
8181};
41d5545d
KS
8182
8183static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8184 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8185 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8186 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8187 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8188 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8189 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8190 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8191 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8192 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8193 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8195 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8196 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8197 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8198 { } /* end */
8199};
92b9de83 8200
e458b1fa
LY
8201static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8203 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8204 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8205 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8206 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8207 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8208 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8209 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8210 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8211 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8212 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8213 { } /* end */
8214};
8215
4b7e1803 8216static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8217 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8218 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8219 { } /* end */
8220};
8221
8222
bdd148a3
KY
8223static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8224 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8225 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8226 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8227 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8228 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8229 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8231 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8232 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8233 { } /* end */
8234};
8235
272a527c
KY
8236static struct snd_kcontrol_new alc882_targa_mixer[] = {
8237 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8238 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8239 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8240 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8241 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8242 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8243 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8244 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8245 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8246 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8247 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8248 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8249 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8250 { } /* end */
8251};
8252
8253/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8254 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8255 */
8256static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8257 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8258 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8259 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8260 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8261 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8262 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8263 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8264 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8265 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8266 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8267 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8269 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8270 { } /* end */
8271};
8272
914759b7
TI
8273static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8274 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8275 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8276 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8277 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8278 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8279 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8280 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8281 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8282 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8283 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8284 { } /* end */
8285};
8286
df694daa
KY
8287static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8288 {
8289 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8290 .name = "Channel Mode",
8291 .info = alc_ch_mode_info,
8292 .get = alc_ch_mode_get,
8293 .put = alc_ch_mode_put,
8294 },
8295 { } /* end */
8296};
8297
4953550a 8298static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8299 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8302 /* Rear mixer */
05acb863
TI
8303 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8304 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8305 /* CLFE mixer */
05acb863
TI
8306 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8307 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8308 /* Side mixer */
05acb863
TI
8309 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8310 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8311
e9edcee0 8312 /* Front Pin: output 0 (0x0c) */
05acb863 8313 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8314 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8315 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8316 /* Rear Pin: output 1 (0x0d) */
05acb863 8317 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8318 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8319 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8320 /* CLFE Pin: output 2 (0x0e) */
05acb863 8321 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8322 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8323 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8324 /* Side Pin: output 3 (0x0f) */
05acb863 8325 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8326 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8327 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8328 /* Mic (rear) pin: input vref at 80% */
16ded525 8329 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8330 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8331 /* Front Mic pin: input vref at 80% */
16ded525 8332 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8333 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8334 /* Line In pin: input */
05acb863 8335 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8336 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8337 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8338 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8339 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8340 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8341 /* CD pin widget for input */
05acb863 8342 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8343
8344 /* FIXME: use matrix-type input source selection */
8345 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8346 /* Input mixer2 */
05acb863 8347 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8348 /* Input mixer3 */
05acb863 8349 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8350 /* ADC2: mute amp left and right */
8351 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8352 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8353 /* ADC3: mute amp left and right */
8354 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8355 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8356
8357 { }
8358};
8359
4953550a
TI
8360static struct hda_verb alc882_adc1_init_verbs[] = {
8361 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8362 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8363 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8364 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8365 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8366 /* ADC1: mute amp left and right */
8367 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8368 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8369 { }
8370};
8371
4b146cb0
TI
8372static struct hda_verb alc882_eapd_verbs[] = {
8373 /* change to EAPD mode */
8374 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8375 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8376 { }
4b146cb0
TI
8377};
8378
87a8c370
JK
8379static struct hda_verb alc889_eapd_verbs[] = {
8380 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8381 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8382 { }
8383};
8384
6732bd0d
WF
8385static struct hda_verb alc_hp15_unsol_verbs[] = {
8386 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8387 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8388 {}
8389};
87a8c370
JK
8390
8391static struct hda_verb alc885_init_verbs[] = {
8392 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8395 /* Rear mixer */
88102f3f
KY
8396 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8397 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8398 /* CLFE mixer */
88102f3f
KY
8399 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8400 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8401 /* Side mixer */
88102f3f
KY
8402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8403 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8404
8405 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8406 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8407 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8408 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8409 /* Front Pin: output 0 (0x0c) */
8410 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8411 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8412 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8413 /* Rear Pin: output 1 (0x0d) */
8414 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8415 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8416 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8417 /* CLFE Pin: output 2 (0x0e) */
8418 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8419 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8420 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8421 /* Side Pin: output 3 (0x0f) */
8422 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8423 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8424 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8425 /* Mic (rear) pin: input vref at 80% */
8426 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8427 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8428 /* Front Mic pin: input vref at 80% */
8429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8431 /* Line In pin: input */
8432 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8433 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8434
8435 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8436 /* Input mixer1 */
88102f3f 8437 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8438 /* Input mixer2 */
8439 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8440 /* Input mixer3 */
88102f3f 8441 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8442 /* ADC2: mute amp left and right */
8443 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8444 /* ADC3: mute amp left and right */
8445 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8446
8447 { }
8448};
8449
8450static struct hda_verb alc885_init_input_verbs[] = {
8451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8454 { }
8455};
8456
8457
8458/* Unmute Selector 24h and set the default input to front mic */
8459static struct hda_verb alc889_init_input_verbs[] = {
8460 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8461 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8462 { }
8463};
8464
8465
4953550a
TI
8466#define alc883_init_verbs alc882_base_init_verbs
8467
9102cd1c
TD
8468/* Mac Pro test */
8469static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8470 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8471 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8472 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8473 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8474 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8475 /* FIXME: this looks suspicious...
d355c82a
JK
8476 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8477 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8478 */
9102cd1c
TD
8479 { } /* end */
8480};
8481
8482static struct hda_verb alc882_macpro_init_verbs[] = {
8483 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8484 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8485 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8486 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8487 /* Front Pin: output 0 (0x0c) */
8488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8489 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8490 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8491 /* Front Mic pin: input vref at 80% */
8492 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8493 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8494 /* Speaker: output */
8495 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8496 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8497 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8498 /* Headphone output (output 0 - 0x0c) */
8499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8501 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8502
8503 /* FIXME: use matrix-type input source selection */
8504 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8505 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8508 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8509 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8510 /* Input mixer2 */
8511 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8512 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8515 /* Input mixer3 */
8516 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8517 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8518 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8519 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8520 /* ADC1: mute amp left and right */
8521 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8522 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8523 /* ADC2: mute amp left and right */
8524 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8525 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8526 /* ADC3: mute amp left and right */
8527 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8528 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8529
8530 { }
8531};
f12ab1e0 8532
41d5545d
KS
8533/* Macbook 5,1 */
8534static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8535 /* DACs */
8536 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8537 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8538 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8539 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8540 /* Front mixer */
41d5545d
KS
8541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8542 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8544 /* Surround mixer */
8545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8546 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8547 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8548 /* LFE mixer */
8549 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8550 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8552 /* HP mixer */
8553 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8554 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8555 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8556 /* Front Pin (0x0c) */
41d5545d
KS
8557 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8558 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8559 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8560 /* LFE Pin (0x0e) */
8561 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8562 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8563 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8564 /* HP Pin (0x0f) */
41d5545d
KS
8565 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8566 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8567 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8568 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8569 /* Front Mic pin: input vref at 80% */
8570 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8571 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8572 /* Line In pin */
8573 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8574 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8575
b8f171e7
AM
8576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8579 { }
8580};
8581
e458b1fa
LY
8582/* Macmini 3,1 */
8583static struct hda_verb alc885_macmini3_init_verbs[] = {
8584 /* DACs */
8585 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8586 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8587 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8588 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8589 /* Front mixer */
8590 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8591 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8592 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8593 /* Surround mixer */
8594 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8595 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8596 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8597 /* LFE mixer */
8598 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8599 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8600 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8601 /* HP mixer */
8602 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8603 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8604 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8605 /* Front Pin (0x0c) */
8606 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8607 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8609 /* LFE Pin (0x0e) */
8610 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8611 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8612 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8613 /* HP Pin (0x0f) */
8614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8615 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8616 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8617 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8618 /* Line In pin */
8619 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8620 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8621
8622 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8623 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8624 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8625 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8626 { }
8627};
8628
76e6f5a9
RH
8629
8630static struct hda_verb alc885_mba21_init_verbs[] = {
8631 /*Internal and HP Speaker Mixer*/
8632 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8633 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8635 /*Internal Speaker Pin (0x0c)*/
8636 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8637 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8638 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8639 /* HP Pin: output 0 (0x0e) */
8640 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8641 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8642 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8643 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8644 /* Line in (is hp when jack connected)*/
8645 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8646 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8647
8648 { }
8649 };
8650
8651
87350ad0
TI
8652/* Macbook Pro rev3 */
8653static struct hda_verb alc885_mbp3_init_verbs[] = {
8654 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8655 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8656 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8658 /* Rear mixer */
8659 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8660 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8661 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8662 /* HP mixer */
8663 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8664 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8665 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8666 /* Front Pin: output 0 (0x0c) */
8667 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8668 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8669 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8670 /* HP Pin: output 0 (0x0e) */
87350ad0 8671 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8672 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8673 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8674 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8675 /* Mic (rear) pin: input vref at 80% */
8676 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8677 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8678 /* Front Mic pin: input vref at 80% */
8679 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8680 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8681 /* Line In pin: use output 1 when in LineOut mode */
8682 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8683 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8684 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8685
8686 /* FIXME: use matrix-type input source selection */
8687 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8688 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8689 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8693 /* Input mixer2 */
8694 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8695 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8696 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8697 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8698 /* Input mixer3 */
8699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8700 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8701 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8702 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8703 /* ADC1: mute amp left and right */
8704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8705 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8706 /* ADC2: mute amp left and right */
8707 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8708 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8709 /* ADC3: mute amp left and right */
8710 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8711 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8712
8713 { }
8714};
8715
4b7e1803
JM
8716/* iMac 9,1 */
8717static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8718 /* Internal Speaker Pin (0x0c) */
8719 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8722 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8723 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8724 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8725 /* HP Pin: Rear */
4b7e1803
JM
8726 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8727 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8728 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8729 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8730 /* Line in Rear */
8731 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8732 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8733 /* Front Mic pin: input vref at 80% */
8734 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8735 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8736 /* Rear mixer */
8737 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8738 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8739 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8740 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8741 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8742 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8744 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8745 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8746 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8747 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8748 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8749 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8752 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8754 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8755 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8759 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8760 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8761 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8762 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8763 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8764 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8765 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8766 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8767 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8768 { }
8769};
8770
c54728d8
NF
8771/* iMac 24 mixer. */
8772static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8773 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8774 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8775 { } /* end */
8776};
8777
8778/* iMac 24 init verbs. */
8779static struct hda_verb alc885_imac24_init_verbs[] = {
8780 /* Internal speakers: output 0 (0x0c) */
8781 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8782 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8783 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8784 /* Internal speakers: output 0 (0x0c) */
8785 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8786 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8787 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8788 /* Headphone: output 0 (0x0c) */
8789 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8790 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8791 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8792 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8793 /* Front Mic: input vref at 80% */
8794 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8795 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8796 { }
8797};
8798
8799/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8800static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8801{
a9fd4f3f 8802 struct alc_spec *spec = codec->spec;
c54728d8 8803
a9fd4f3f
TI
8804 spec->autocfg.hp_pins[0] = 0x14;
8805 spec->autocfg.speaker_pins[0] = 0x18;
8806 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8807 spec->automute = 1;
8808 spec->automute_mode = ALC_AUTOMUTE_AMP;
c54728d8
NF
8809}
8810
9d54f08b
TI
8811#define alc885_mb5_setup alc885_imac24_setup
8812#define alc885_macmini3_setup alc885_imac24_setup
8813
76e6f5a9
RH
8814/* Macbook Air 2,1 */
8815static void alc885_mba21_setup(struct hda_codec *codec)
8816{
8817 struct alc_spec *spec = codec->spec;
8818
8819 spec->autocfg.hp_pins[0] = 0x14;
8820 spec->autocfg.speaker_pins[0] = 0x18;
d922b51d
TI
8821 spec->automute = 1;
8822 spec->automute_mode = ALC_AUTOMUTE_AMP;
76e6f5a9
RH
8823}
8824
8825
8826
4f5d1706 8827static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8828{
a9fd4f3f 8829 struct alc_spec *spec = codec->spec;
87350ad0 8830
a9fd4f3f
TI
8831 spec->autocfg.hp_pins[0] = 0x15;
8832 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
8833 spec->automute = 1;
8834 spec->automute_mode = ALC_AUTOMUTE_AMP;
87350ad0
TI
8835}
8836
9d54f08b 8837static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8838{
9d54f08b 8839 struct alc_spec *spec = codec->spec;
4b7e1803 8840
9d54f08b 8841 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8842 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8843 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8844 spec->automute = 1;
8845 spec->automute_mode = ALC_AUTOMUTE_AMP;
4b7e1803 8846}
87350ad0 8847
272a527c
KY
8848static struct hda_verb alc882_targa_verbs[] = {
8849 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8850 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8851
8852 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8853 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8854
272a527c
KY
8855 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8856 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8857 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8858
8859 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8860 { } /* end */
8861};
8862
8863/* toggle speaker-output according to the hp-jack state */
8864static void alc882_targa_automute(struct hda_codec *codec)
8865{
a9fd4f3f 8866 struct alc_spec *spec = codec->spec;
d922b51d 8867 alc_hp_automute(codec);
82beb8fd 8868 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8869 spec->jack_present ? 1 : 3);
8870}
8871
4f5d1706 8872static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8873{
8874 struct alc_spec *spec = codec->spec;
8875
8876 spec->autocfg.hp_pins[0] = 0x14;
8877 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
8878 spec->automute = 1;
8879 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
8880}
8881
8882static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8883{
a9fd4f3f 8884 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8885 alc882_targa_automute(codec);
272a527c
KY
8886}
8887
8888static struct hda_verb alc882_asus_a7j_verbs[] = {
8889 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8890 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8891
8892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8894 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8895
272a527c
KY
8896 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8897 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8898 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8899
8900 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8901 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8902 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8903 { } /* end */
8904};
8905
914759b7
TI
8906static struct hda_verb alc882_asus_a7m_verbs[] = {
8907 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8909
8910 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8911 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8912 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8913
914759b7
TI
8914 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8915 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8916 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8917
8918 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8919 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8920 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8921 { } /* end */
8922};
8923
9102cd1c
TD
8924static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8925{
8926 unsigned int gpiostate, gpiomask, gpiodir;
8927
8928 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8929 AC_VERB_GET_GPIO_DATA, 0);
8930
8931 if (!muted)
8932 gpiostate |= (1 << pin);
8933 else
8934 gpiostate &= ~(1 << pin);
8935
8936 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8937 AC_VERB_GET_GPIO_MASK, 0);
8938 gpiomask |= (1 << pin);
8939
8940 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8941 AC_VERB_GET_GPIO_DIRECTION, 0);
8942 gpiodir |= (1 << pin);
8943
8944
8945 snd_hda_codec_write(codec, codec->afg, 0,
8946 AC_VERB_SET_GPIO_MASK, gpiomask);
8947 snd_hda_codec_write(codec, codec->afg, 0,
8948 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8949
8950 msleep(1);
8951
8952 snd_hda_codec_write(codec, codec->afg, 0,
8953 AC_VERB_SET_GPIO_DATA, gpiostate);
8954}
8955
7debbe51
TI
8956/* set up GPIO at initialization */
8957static void alc885_macpro_init_hook(struct hda_codec *codec)
8958{
8959 alc882_gpio_mute(codec, 0, 0);
8960 alc882_gpio_mute(codec, 1, 0);
8961}
8962
8963/* set up GPIO and update auto-muting at initialization */
8964static void alc885_imac24_init_hook(struct hda_codec *codec)
8965{
8966 alc885_macpro_init_hook(codec);
d922b51d 8967 alc_hp_automute(codec);
7debbe51
TI
8968}
8969
df694daa
KY
8970/*
8971 * generic initialization of ADC, input mixers and output mixers
8972 */
4953550a 8973static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8974 /*
8975 * Unmute ADC0-2 and set the default input to mic-in
8976 */
4953550a
TI
8977 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8978 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8979 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8980 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8981
4953550a
TI
8982 /*
8983 * Set up output mixers (0x0c - 0x0f)
8984 */
8985 /* set vol=0 to output mixers */
8986 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8987 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8988 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8989 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8990 /* set up input amps for analog loopback */
8991 /* Amp Indices: DAC = 0, mixer = 1 */
8992 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8993 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8994 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8995 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8996 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8997 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8998 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8999 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9000 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9001 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 9002
4953550a
TI
9003 /* FIXME: use matrix-type input source selection */
9004 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9005 /* Input mixer2 */
88102f3f 9006 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9007 /* Input mixer3 */
88102f3f 9008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9009 { }
9c7f852e
TI
9010};
9011
eb4c41d3
TS
9012/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
9013static struct hda_verb alc889A_mb31_ch2_init[] = {
9014 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9015 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9016 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9017 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9018 { } /* end */
9019};
9020
9021/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
9022static struct hda_verb alc889A_mb31_ch4_init[] = {
9023 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9024 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9025 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9026 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9027 { } /* end */
9028};
9029
9030/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
9031static struct hda_verb alc889A_mb31_ch5_init[] = {
9032 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9033 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9034 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9035 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9036 { } /* end */
9037};
9038
9039/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
9040static struct hda_verb alc889A_mb31_ch6_init[] = {
9041 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9042 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9043 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9044 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9045 { } /* end */
9046};
9047
9048static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
9049 { 2, alc889A_mb31_ch2_init },
9050 { 4, alc889A_mb31_ch4_init },
9051 { 5, alc889A_mb31_ch5_init },
9052 { 6, alc889A_mb31_ch6_init },
9053};
9054
b373bdeb
AN
9055static struct hda_verb alc883_medion_eapd_verbs[] = {
9056 /* eanable EAPD on medion laptop */
9057 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9058 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9059 { }
9060};
9061
4953550a 9062#define alc883_base_mixer alc882_base_mixer
834be88d 9063
a8848bd6
AS
9064static struct snd_kcontrol_new alc883_mitac_mixer[] = {
9065 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9066 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9067 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9068 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9069 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9070 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9072 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9073 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
9074 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9075 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9076 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 9077 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
9078 { } /* end */
9079};
9080
0c4cc443 9081static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
9082 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9083 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9084 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9085 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9086 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9087 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 9088 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9089 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9090 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9091 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
9092 { } /* end */
9093};
9094
fb97dc67
J
9095static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
9096 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9097 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9098 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9099 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9101 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 9102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9103 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9104 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9105 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
9106 { } /* end */
9107};
9108
9c7f852e
TI
9109static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9110 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9111 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9112 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9113 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9114 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9115 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9116 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9118 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9119 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9120 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9121 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9122 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9123 { } /* end */
9124};
df694daa 9125
9c7f852e
TI
9126static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9127 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9128 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9129 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9130 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9131 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9132 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9133 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9134 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9135 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9136 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9137 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9138 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9139 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9140 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9141 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9142 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9143 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9144 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9145 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9146 { } /* end */
9147};
9148
17bba1b7
J
9149static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9150 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9151 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9152 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9153 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9154 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9155 HDA_OUTPUT),
9156 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9157 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9158 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9160 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9161 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9162 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9163 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9165 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9166 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9167 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9168 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9169 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9170 { } /* end */
9171};
9172
87a8c370
JK
9173static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9174 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9175 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9176 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9177 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9178 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9179 HDA_OUTPUT),
9180 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9181 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9182 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9183 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9184 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9185 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9186 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9187 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9190 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9191 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9192 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9193 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9194 { } /* end */
9195};
9196
d1d985f0 9197static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9199 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9200 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9201 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9202 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9203 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9204 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9205 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9206 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9207 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9208 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9212 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9214 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9215 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9216 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9217 { } /* end */
9218};
9219
c259249f 9220static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9221 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9222 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9223 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9224 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9225 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9226 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9227 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9228 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9229 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9230 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9238 { } /* end */
f12ab1e0 9239};
ccc656ce 9240
c259249f 9241static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9242 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9243 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9244 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9245 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9246 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9247 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9248 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9249 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9251 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9252 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9253 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9254 { } /* end */
f12ab1e0 9255};
ccc656ce 9256
b99dba34
TI
9257static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9258 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9259 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9260 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9261 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9262 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9263 { } /* end */
9264};
9265
bc9f98a9
KY
9266static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9269 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9270 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9271 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9272 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9274 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9275 { } /* end */
f12ab1e0 9276};
bc9f98a9 9277
272a527c
KY
9278static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9279 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9280 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9281 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9282 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9283 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9285 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9286 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9287 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9288 { } /* end */
ea1fb29a 9289};
272a527c 9290
7ad7b218
MC
9291static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9292 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9293 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9294 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9295 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9296 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9297 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9298 { } /* end */
9299};
9300
9301static struct hda_verb alc883_medion_wim2160_verbs[] = {
9302 /* Unmute front mixer */
9303 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9304 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9305
9306 /* Set speaker pin to front mixer */
9307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9308
9309 /* Init headphone pin */
9310 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9311 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9312 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9313 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9314
9315 { } /* end */
9316};
9317
9318/* toggle speaker-output according to the hp-jack state */
9319static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9320{
9321 struct alc_spec *spec = codec->spec;
9322
9323 spec->autocfg.hp_pins[0] = 0x1a;
9324 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9325 spec->automute = 1;
9326 spec->automute_mode = ALC_AUTOMUTE_AMP;
7ad7b218
MC
9327}
9328
2880a867 9329static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9330 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9331 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9336 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9338 { } /* end */
d1a991a6 9339};
2880a867 9340
d2fd4b09
TV
9341static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9342 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9343 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9344 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9345 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9346 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9347 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9348 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9349 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9350 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9351 { } /* end */
9352};
9353
e2757d5e
KY
9354static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9355 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9356 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9357 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9358 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9359 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9360 0x0d, 1, 0x0, HDA_OUTPUT),
9361 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9362 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9363 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9364 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9365 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9366 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9367 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9371 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9372 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9373 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9374 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9375 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9376 { } /* end */
9377};
9378
eb4c41d3
TS
9379static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9380 /* Output mixers */
9381 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9382 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9383 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9384 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9385 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9386 HDA_OUTPUT),
9387 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9388 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9389 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9390 /* Output switches */
9391 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9392 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9393 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9394 /* Boost mixers */
5f99f86a
DH
9395 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9396 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9397 /* Input mixers */
9398 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9399 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9400 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9401 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9402 { } /* end */
9403};
9404
3e1647c5
GG
9405static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9406 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9407 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9408 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9409 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9410 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9411 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9412 { } /* end */
9413};
9414
e2757d5e
KY
9415static struct hda_bind_ctls alc883_bind_cap_vol = {
9416 .ops = &snd_hda_bind_vol,
9417 .values = {
9418 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9419 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9420 0
9421 },
9422};
9423
9424static struct hda_bind_ctls alc883_bind_cap_switch = {
9425 .ops = &snd_hda_bind_sw,
9426 .values = {
9427 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9428 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9429 0
9430 },
9431};
9432
9433static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
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", 0x14, 0x0, HDA_OUTPUT),
9437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9440 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9441 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9442 { } /* end */
9443};
df694daa 9444
4953550a
TI
9445static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9446 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9447 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9448 {
9449 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9450 /* .name = "Capture Source", */
9451 .name = "Input Source",
9452 .count = 1,
9453 .info = alc_mux_enum_info,
9454 .get = alc_mux_enum_get,
9455 .put = alc_mux_enum_put,
9456 },
9457 { } /* end */
9458};
9c7f852e 9459
4953550a
TI
9460static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9461 {
9462 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9463 .name = "Channel Mode",
9464 .info = alc_ch_mode_info,
9465 .get = alc_ch_mode_get,
9466 .put = alc_ch_mode_put,
9467 },
9468 { } /* end */
9c7f852e
TI
9469};
9470
a8848bd6 9471/* toggle speaker-output according to the hp-jack state */
4f5d1706 9472static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9473{
a9fd4f3f 9474 struct alc_spec *spec = codec->spec;
a8848bd6 9475
a9fd4f3f
TI
9476 spec->autocfg.hp_pins[0] = 0x15;
9477 spec->autocfg.speaker_pins[0] = 0x14;
9478 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9479 spec->automute = 1;
9480 spec->automute_mode = ALC_AUTOMUTE_AMP;
a8848bd6
AS
9481}
9482
a8848bd6
AS
9483static struct hda_verb alc883_mitac_verbs[] = {
9484 /* HP */
9485 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9486 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9487 /* Subwoofer */
9488 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9489 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9490
9491 /* enable unsolicited event */
9492 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9493 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9494
9495 { } /* end */
9496};
9497
a65cc60f 9498static struct hda_verb alc883_clevo_m540r_verbs[] = {
9499 /* HP */
9500 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9501 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9502 /* Int speaker */
9503 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9504
9505 /* enable unsolicited event */
9506 /*
9507 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9508 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9509 */
9510
9511 { } /* end */
9512};
9513
0c4cc443 9514static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9515 /* HP */
9516 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9517 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9518 /* Int speaker */
9519 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9521
9522 /* enable unsolicited event */
9523 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9524 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9525
9526 { } /* end */
9527};
9528
fb97dc67
J
9529static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9530 /* HP */
9531 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9533 /* Subwoofer */
9534 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9535 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9536
9537 /* enable unsolicited event */
9538 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9539
9540 { } /* end */
9541};
9542
c259249f 9543static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9545 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9546
9547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9549
64a8be74
DH
9550/* Connect Line-Out side jack (SPDIF) to Side */
9551 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9552 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9553 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9554/* Connect Mic jack to CLFE */
9555 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9556 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9557 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9558/* Connect Line-in jack to Surround */
9559 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9560 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9561 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9562/* Connect HP out jack to Front */
9563 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9564 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9565 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9566
9567 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9568
9569 { } /* end */
9570};
9571
bc9f98a9
KY
9572static struct hda_verb alc883_lenovo_101e_verbs[] = {
9573 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9574 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9575 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9576 { } /* end */
9577};
9578
272a527c
KY
9579static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9580 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9581 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9582 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9584 { } /* end */
9585};
9586
9587static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9588 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9590 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9591 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9592 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9593 { } /* end */
9594};
9595
189609ae
KY
9596static struct hda_verb alc883_haier_w66_verbs[] = {
9597 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9599
9600 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9601
9602 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9603 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9604 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9605 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9606 { } /* end */
9607};
9608
e2757d5e
KY
9609static struct hda_verb alc888_lenovo_sky_verbs[] = {
9610 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9612 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9613 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9614 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9615 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9616 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9617 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9618 { } /* end */
9619};
9620
8718b700
HRK
9621static struct hda_verb alc888_6st_dell_verbs[] = {
9622 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9623 { }
9624};
9625
3e1647c5
GG
9626static struct hda_verb alc883_vaiott_verbs[] = {
9627 /* HP */
9628 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9629 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9630
9631 /* enable unsolicited event */
9632 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9633
9634 { } /* end */
9635};
9636
4f5d1706 9637static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9638{
a9fd4f3f 9639 struct alc_spec *spec = codec->spec;
8718b700 9640
a9fd4f3f
TI
9641 spec->autocfg.hp_pins[0] = 0x1b;
9642 spec->autocfg.speaker_pins[0] = 0x14;
9643 spec->autocfg.speaker_pins[1] = 0x16;
9644 spec->autocfg.speaker_pins[2] = 0x18;
d922b51d
TI
9645 spec->automute = 1;
9646 spec->automute_mode = ALC_AUTOMUTE_AMP;
8718b700
HRK
9647}
9648
4723c022 9649static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9650 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9651 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9652 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9653 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9654 { } /* end */
5795b9e6
CM
9655};
9656
3ea0d7cf
HRK
9657/*
9658 * 2ch mode
9659 */
4723c022 9660static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9661 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9662 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9663 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9664 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9665 { } /* end */
8341de60
CM
9666};
9667
3ea0d7cf
HRK
9668/*
9669 * 4ch mode
9670 */
9671static struct hda_verb alc888_3st_hp_4ch_init[] = {
9672 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9673 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9674 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9675 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9676 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9677 { } /* end */
9678};
9679
9680/*
9681 * 6ch mode
9682 */
4723c022 9683static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9684 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9685 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9686 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9687 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9688 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9689 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9690 { } /* end */
8341de60
CM
9691};
9692
3ea0d7cf 9693static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9694 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9695 { 4, alc888_3st_hp_4ch_init },
4723c022 9696 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9697};
9698
e6a5e1b7 9699static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
272a527c 9700{
e6a5e1b7 9701 struct alc_spec *spec = codec->spec;
47fd830a 9702
e6a5e1b7
TI
9703 spec->autocfg.hp_pins[0] = 0x1b;
9704 spec->autocfg.line_out_pins[0] = 0x14;
9705 spec->autocfg.speaker_pins[0] = 0x15;
9706 spec->automute = 1;
9707 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9708}
9709
272a527c 9710/* toggle speaker-output according to the hp-jack state */
dc427170 9711static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9712{
a9fd4f3f 9713 struct alc_spec *spec = codec->spec;
272a527c 9714
a9fd4f3f
TI
9715 spec->autocfg.hp_pins[0] = 0x14;
9716 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9717 spec->automute = 1;
9718 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9719}
9720
ccc656ce 9721/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9722#define alc883_targa_init_hook alc882_targa_init_hook
9723#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9724
4f5d1706 9725static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9726{
a9fd4f3f
TI
9727 struct alc_spec *spec = codec->spec;
9728
9729 spec->autocfg.hp_pins[0] = 0x15;
9730 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9731 spec->automute = 1;
9732 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
9733}
9734
9735static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9736{
d922b51d 9737 alc_hp_automute(codec);
eeb43387 9738 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9739}
9740
9741static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9742 unsigned int res)
9743{
0c4cc443 9744 switch (res >> 26) {
0c4cc443 9745 case ALC880_MIC_EVENT:
eeb43387 9746 alc88x_simple_mic_automute(codec);
0c4cc443 9747 break;
a9fd4f3f 9748 default:
d922b51d 9749 alc_sku_unsol_event(codec, res);
a9fd4f3f 9750 break;
0c4cc443 9751 }
368c7a95
J
9752}
9753
fb97dc67 9754/* toggle speaker-output according to the hp-jack state */
4f5d1706 9755static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9756{
a9fd4f3f 9757 struct alc_spec *spec = codec->spec;
fb97dc67 9758
a9fd4f3f
TI
9759 spec->autocfg.hp_pins[0] = 0x14;
9760 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9761 spec->automute = 1;
9762 spec->automute_mode = ALC_AUTOMUTE_AMP;
fb97dc67
J
9763}
9764
4f5d1706 9765static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9766{
a9fd4f3f 9767 struct alc_spec *spec = codec->spec;
189609ae 9768
a9fd4f3f
TI
9769 spec->autocfg.hp_pins[0] = 0x1b;
9770 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9771 spec->automute = 1;
9772 spec->automute_mode = ALC_AUTOMUTE_AMP;
189609ae
KY
9773}
9774
e6a5e1b7 9775static void alc883_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 9776{
e6a5e1b7 9777 struct alc_spec *spec = codec->spec;
bc9f98a9 9778
e6a5e1b7
TI
9779 spec->autocfg.hp_pins[0] = 0x1b;
9780 spec->autocfg.line_out_pins[0] = 0x14;
9781 spec->autocfg.speaker_pins[0] = 0x15;
9782 spec->automute = 1;
9783 spec->detect_line = 1;
9784 spec->automute_lines = 1;
9785 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
9786}
9787
676a9b53 9788/* toggle speaker-output according to the hp-jack state */
4f5d1706 9789static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9790{
a9fd4f3f 9791 struct alc_spec *spec = codec->spec;
676a9b53 9792
a9fd4f3f
TI
9793 spec->autocfg.hp_pins[0] = 0x14;
9794 spec->autocfg.speaker_pins[0] = 0x15;
9795 spec->autocfg.speaker_pins[1] = 0x16;
d922b51d
TI
9796 spec->automute = 1;
9797 spec->automute_mode = ALC_AUTOMUTE_AMP;
676a9b53
TI
9798}
9799
d1a991a6
KY
9800static struct hda_verb alc883_acer_eapd_verbs[] = {
9801 /* HP Pin: output 0 (0x0c) */
9802 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9803 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9804 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9805 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9807 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9808 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9809 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9810 /* eanable EAPD on medion laptop */
9811 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9812 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9813 /* enable unsolicited event */
9814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9815 { }
9816};
9817
4f5d1706 9818static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9819{
a9fd4f3f 9820 struct alc_spec *spec = codec->spec;
5795b9e6 9821
a9fd4f3f
TI
9822 spec->autocfg.hp_pins[0] = 0x1b;
9823 spec->autocfg.speaker_pins[0] = 0x14;
9824 spec->autocfg.speaker_pins[1] = 0x15;
9825 spec->autocfg.speaker_pins[2] = 0x16;
9826 spec->autocfg.speaker_pins[3] = 0x17;
d922b51d
TI
9827 spec->automute = 1;
9828 spec->automute_mode = ALC_AUTOMUTE_AMP;
5795b9e6
CM
9829}
9830
4f5d1706 9831static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9832{
a9fd4f3f 9833 struct alc_spec *spec = codec->spec;
e2757d5e 9834
a9fd4f3f
TI
9835 spec->autocfg.hp_pins[0] = 0x1b;
9836 spec->autocfg.speaker_pins[0] = 0x14;
9837 spec->autocfg.speaker_pins[1] = 0x15;
9838 spec->autocfg.speaker_pins[2] = 0x16;
9839 spec->autocfg.speaker_pins[3] = 0x17;
9840 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
9841 spec->automute = 1;
9842 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9843}
9844
4f5d1706 9845static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9846{
9847 struct alc_spec *spec = codec->spec;
9848
9849 spec->autocfg.hp_pins[0] = 0x15;
9850 spec->autocfg.speaker_pins[0] = 0x14;
9851 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9852 spec->automute = 1;
9853 spec->automute_mode = ALC_AUTOMUTE_AMP;
3e1647c5
GG
9854}
9855
e2757d5e
KY
9856static struct hda_verb alc888_asus_m90v_verbs[] = {
9857 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9858 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9859 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9860 /* enable unsolicited event */
9861 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9862 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9863 { } /* end */
9864};
9865
4f5d1706 9866static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9867{
a9fd4f3f 9868 struct alc_spec *spec = codec->spec;
e2757d5e 9869
a9fd4f3f
TI
9870 spec->autocfg.hp_pins[0] = 0x1b;
9871 spec->autocfg.speaker_pins[0] = 0x14;
9872 spec->autocfg.speaker_pins[1] = 0x15;
9873 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9874 spec->ext_mic.pin = 0x18;
9875 spec->int_mic.pin = 0x19;
9876 spec->ext_mic.mux_idx = 0;
9877 spec->int_mic.mux_idx = 1;
9878 spec->auto_mic = 1;
d922b51d
TI
9879 spec->automute = 1;
9880 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9881}
9882
9883static struct hda_verb alc888_asus_eee1601_verbs[] = {
9884 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9885 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9886 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9889 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9890 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9891 /* enable unsolicited event */
9892 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9893 { } /* end */
9894};
9895
e2757d5e
KY
9896static void alc883_eee1601_inithook(struct hda_codec *codec)
9897{
a9fd4f3f
TI
9898 struct alc_spec *spec = codec->spec;
9899
9900 spec->autocfg.hp_pins[0] = 0x14;
9901 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d 9902 alc_hp_automute(codec);
e2757d5e
KY
9903}
9904
eb4c41d3
TS
9905static struct hda_verb alc889A_mb31_verbs[] = {
9906 /* Init rear pin (used as headphone output) */
9907 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9908 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9909 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9910 /* Init line pin (used as output in 4ch and 6ch mode) */
9911 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9912 /* Init line 2 pin (used as headphone out by default) */
9913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9914 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9915 { } /* end */
9916};
9917
9918/* Mute speakers according to the headphone jack state */
9919static void alc889A_mb31_automute(struct hda_codec *codec)
9920{
9921 unsigned int present;
9922
9923 /* Mute only in 2ch or 4ch mode */
9924 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9925 == 0x00) {
864f92be 9926 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9927 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9928 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9929 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9930 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9931 }
9932}
9933
9934static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9935{
9936 if ((res >> 26) == ALC880_HP_EVENT)
9937 alc889A_mb31_automute(codec);
9938}
9939
4953550a 9940
cb53c626 9941#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9942#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9943#endif
9944
def319f9 9945/* pcm configuration: identical with ALC880 */
4953550a
TI
9946#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9947#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9948#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9949#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9950
9951static hda_nid_t alc883_slave_dig_outs[] = {
9952 ALC1200_DIGOUT_NID, 0,
9953};
9954
9955static hda_nid_t alc1200_slave_dig_outs[] = {
9956 ALC883_DIGOUT_NID, 0,
9957};
9c7f852e
TI
9958
9959/*
9960 * configuration and preset
9961 */
ea734963 9962static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9963 [ALC882_3ST_DIG] = "3stack-dig",
9964 [ALC882_6ST_DIG] = "6stack-dig",
9965 [ALC882_ARIMA] = "arima",
9966 [ALC882_W2JC] = "w2jc",
9967 [ALC882_TARGA] = "targa",
9968 [ALC882_ASUS_A7J] = "asus-a7j",
9969 [ALC882_ASUS_A7M] = "asus-a7m",
9970 [ALC885_MACPRO] = "macpro",
9971 [ALC885_MB5] = "mb5",
e458b1fa 9972 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9973 [ALC885_MBA21] = "mba21",
4953550a
TI
9974 [ALC885_MBP3] = "mbp3",
9975 [ALC885_IMAC24] = "imac24",
4b7e1803 9976 [ALC885_IMAC91] = "imac91",
4953550a 9977 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9978 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9979 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9980 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9981 [ALC883_TARGA_DIG] = "targa-dig",
9982 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9983 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9984 [ALC883_ACER] = "acer",
2880a867 9985 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9986 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9987 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9988 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9989 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9990 [ALC883_MEDION] = "medion",
7ad7b218 9991 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9992 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9993 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9994 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9995 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9996 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9997 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9998 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9999 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 10000 [ALC883_MITAC] = "mitac",
a65cc60f 10001 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 10002 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 10003 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 10004 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 10005 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
10006 [ALC889A_INTEL] = "intel-alc889a",
10007 [ALC889_INTEL] = "intel-x58",
3ab90935 10008 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 10009 [ALC889A_MB31] = "mb31",
3e1647c5 10010 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 10011 [ALC882_AUTO] = "auto",
f5fcc13c
TI
10012};
10013
4953550a
TI
10014static struct snd_pci_quirk alc882_cfg_tbl[] = {
10015 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10016
ac3e3741 10017 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 10018 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 10019 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
10020 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10021 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 10022 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
10023 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10024 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 10025 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 10026 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
10027 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10028 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
10029 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10030 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
10031 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10032 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 10033 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 10034 ALC888_ACER_ASPIRE_6530G),
cc374c47 10035 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 10036 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
10037 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10038 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
10039 /* default Acer -- disabled as it causes more problems.
10040 * model=auto should work fine now
10041 */
10042 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 10043
5795b9e6 10044 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 10045
febe3375 10046 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
10047 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10048 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 10049 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 10050 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 10051 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
10052
10053 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10054 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10055 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 10056 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
10057 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10058 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10059 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 10060 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 10061 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 10062 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 10063 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
10064
10065 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 10066 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 10067 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 10068 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
10069 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10070 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 10071 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 10072 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a 10073
6f3bf657 10074 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 10075 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10076 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10077 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 10078 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 10079 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 10080 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 10081 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 10082 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10083 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10084 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10085 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 10086 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 10087 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 10088 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10089 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10090 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10091 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 10092 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 10093 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
10094 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10095 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10096 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 10097 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 10098 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
10099 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10100 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 10101 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 10102 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 10103 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 10104 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10105
ac3e3741 10106 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 10107 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
10108 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10109 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 10110 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 10111 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 10112 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 10113 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 10114 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 10115 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 10116 ALC883_FUJITSU_PI2515),
bfb53037 10117 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 10118 ALC888_FUJITSU_XA3530),
272a527c 10119 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 10120 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
10121 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10122 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 10123 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 10124 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 10125 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 10126 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 10127
17bba1b7
J
10128 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10129 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 10130 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
10131 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10132 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10133 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 10134 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 10135
4953550a 10136 {}
f3cd3f5d
WF
10137};
10138
4953550a
TI
10139/* codec SSID table for Intel Mac */
10140static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10141 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10142 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10143 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10144 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10145 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10146 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10147 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 10148 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 10149 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 10150 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 10151 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
10152 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10153 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10154 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 10155 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 10156 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 10157 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10158 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10159 * so apparently no perfect solution yet
4953550a
TI
10160 */
10161 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10162 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10163 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10164 {} /* terminator */
b25c9da1
WF
10165};
10166
4953550a
TI
10167static struct alc_config_preset alc882_presets[] = {
10168 [ALC882_3ST_DIG] = {
10169 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10170 .init_verbs = { alc882_base_init_verbs,
10171 alc882_adc1_init_verbs },
4953550a
TI
10172 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10173 .dac_nids = alc882_dac_nids,
10174 .dig_out_nid = ALC882_DIGOUT_NID,
10175 .dig_in_nid = ALC882_DIGIN_NID,
10176 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10177 .channel_mode = alc882_ch_modes,
10178 .need_dac_fix = 1,
10179 .input_mux = &alc882_capture_source,
10180 },
10181 [ALC882_6ST_DIG] = {
10182 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10183 .init_verbs = { alc882_base_init_verbs,
10184 alc882_adc1_init_verbs },
4953550a
TI
10185 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10186 .dac_nids = alc882_dac_nids,
10187 .dig_out_nid = ALC882_DIGOUT_NID,
10188 .dig_in_nid = ALC882_DIGIN_NID,
10189 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10190 .channel_mode = alc882_sixstack_modes,
10191 .input_mux = &alc882_capture_source,
10192 },
10193 [ALC882_ARIMA] = {
10194 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10195 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10196 alc882_eapd_verbs },
4953550a
TI
10197 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10198 .dac_nids = alc882_dac_nids,
10199 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10200 .channel_mode = alc882_sixstack_modes,
10201 .input_mux = &alc882_capture_source,
10202 },
10203 [ALC882_W2JC] = {
10204 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10205 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10206 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10207 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10208 .dac_nids = alc882_dac_nids,
10209 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10210 .channel_mode = alc880_threestack_modes,
10211 .need_dac_fix = 1,
10212 .input_mux = &alc882_capture_source,
10213 .dig_out_nid = ALC882_DIGOUT_NID,
10214 },
76e6f5a9
RH
10215 [ALC885_MBA21] = {
10216 .mixers = { alc885_mba21_mixer },
10217 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10218 .num_dacs = 2,
10219 .dac_nids = alc882_dac_nids,
10220 .channel_mode = alc885_mba21_ch_modes,
10221 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10222 .input_mux = &alc882_capture_source,
d922b51d 10223 .unsol_event = alc_sku_unsol_event,
76e6f5a9 10224 .setup = alc885_mba21_setup,
d922b51d 10225 .init_hook = alc_hp_automute,
76e6f5a9 10226 },
4953550a
TI
10227 [ALC885_MBP3] = {
10228 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10229 .init_verbs = { alc885_mbp3_init_verbs,
10230 alc880_gpio1_init_verbs },
be0ae923 10231 .num_dacs = 2,
4953550a 10232 .dac_nids = alc882_dac_nids,
be0ae923
TI
10233 .hp_nid = 0x04,
10234 .channel_mode = alc885_mbp_4ch_modes,
10235 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10236 .input_mux = &alc882_capture_source,
10237 .dig_out_nid = ALC882_DIGOUT_NID,
10238 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10239 .unsol_event = alc_sku_unsol_event,
4f5d1706 10240 .setup = alc885_mbp3_setup,
d922b51d 10241 .init_hook = alc_hp_automute,
4953550a
TI
10242 },
10243 [ALC885_MB5] = {
10244 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10245 .init_verbs = { alc885_mb5_init_verbs,
10246 alc880_gpio1_init_verbs },
10247 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10248 .dac_nids = alc882_dac_nids,
10249 .channel_mode = alc885_mb5_6ch_modes,
10250 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10251 .input_mux = &mb5_capture_source,
10252 .dig_out_nid = ALC882_DIGOUT_NID,
10253 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10254 .unsol_event = alc_sku_unsol_event,
9d54f08b 10255 .setup = alc885_mb5_setup,
d922b51d 10256 .init_hook = alc_hp_automute,
4953550a 10257 },
e458b1fa
LY
10258 [ALC885_MACMINI3] = {
10259 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10260 .init_verbs = { alc885_macmini3_init_verbs,
10261 alc880_gpio1_init_verbs },
10262 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10263 .dac_nids = alc882_dac_nids,
10264 .channel_mode = alc885_macmini3_6ch_modes,
10265 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10266 .input_mux = &macmini3_capture_source,
10267 .dig_out_nid = ALC882_DIGOUT_NID,
10268 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10269 .unsol_event = alc_sku_unsol_event,
9d54f08b 10270 .setup = alc885_macmini3_setup,
d922b51d 10271 .init_hook = alc_hp_automute,
e458b1fa 10272 },
4953550a
TI
10273 [ALC885_MACPRO] = {
10274 .mixers = { alc882_macpro_mixer },
10275 .init_verbs = { alc882_macpro_init_verbs },
10276 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10277 .dac_nids = alc882_dac_nids,
10278 .dig_out_nid = ALC882_DIGOUT_NID,
10279 .dig_in_nid = ALC882_DIGIN_NID,
10280 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10281 .channel_mode = alc882_ch_modes,
10282 .input_mux = &alc882_capture_source,
10283 .init_hook = alc885_macpro_init_hook,
10284 },
10285 [ALC885_IMAC24] = {
10286 .mixers = { alc885_imac24_mixer },
10287 .init_verbs = { alc885_imac24_init_verbs },
10288 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10289 .dac_nids = alc882_dac_nids,
10290 .dig_out_nid = ALC882_DIGOUT_NID,
10291 .dig_in_nid = ALC882_DIGIN_NID,
10292 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10293 .channel_mode = alc882_ch_modes,
10294 .input_mux = &alc882_capture_source,
d922b51d 10295 .unsol_event = alc_sku_unsol_event,
4f5d1706 10296 .setup = alc885_imac24_setup,
4953550a
TI
10297 .init_hook = alc885_imac24_init_hook,
10298 },
4b7e1803 10299 [ALC885_IMAC91] = {
b7cccc52 10300 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10301 .init_verbs = { alc885_imac91_init_verbs,
10302 alc880_gpio1_init_verbs },
10303 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10304 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10305 .channel_mode = alc885_mba21_ch_modes,
10306 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10307 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10308 .dig_out_nid = ALC882_DIGOUT_NID,
10309 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10310 .unsol_event = alc_sku_unsol_event,
9d54f08b 10311 .setup = alc885_imac91_setup,
d922b51d 10312 .init_hook = alc_hp_automute,
4b7e1803 10313 },
4953550a
TI
10314 [ALC882_TARGA] = {
10315 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10316 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10317 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10318 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10319 .dac_nids = alc882_dac_nids,
10320 .dig_out_nid = ALC882_DIGOUT_NID,
10321 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10322 .adc_nids = alc882_adc_nids,
10323 .capsrc_nids = alc882_capsrc_nids,
10324 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10325 .channel_mode = alc882_3ST_6ch_modes,
10326 .need_dac_fix = 1,
10327 .input_mux = &alc882_capture_source,
d922b51d 10328 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
10329 .setup = alc882_targa_setup,
10330 .init_hook = alc882_targa_automute,
4953550a
TI
10331 },
10332 [ALC882_ASUS_A7J] = {
10333 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10334 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10335 alc882_asus_a7j_verbs},
4953550a
TI
10336 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10337 .dac_nids = alc882_dac_nids,
10338 .dig_out_nid = ALC882_DIGOUT_NID,
10339 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10340 .adc_nids = alc882_adc_nids,
10341 .capsrc_nids = alc882_capsrc_nids,
10342 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10343 .channel_mode = alc882_3ST_6ch_modes,
10344 .need_dac_fix = 1,
10345 .input_mux = &alc882_capture_source,
10346 },
10347 [ALC882_ASUS_A7M] = {
10348 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10349 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10350 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10351 alc882_asus_a7m_verbs },
10352 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10353 .dac_nids = alc882_dac_nids,
10354 .dig_out_nid = ALC882_DIGOUT_NID,
10355 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10356 .channel_mode = alc880_threestack_modes,
10357 .need_dac_fix = 1,
10358 .input_mux = &alc882_capture_source,
10359 },
9c7f852e
TI
10360 [ALC883_3ST_2ch_DIG] = {
10361 .mixers = { alc883_3ST_2ch_mixer },
10362 .init_verbs = { alc883_init_verbs },
10363 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10364 .dac_nids = alc883_dac_nids,
10365 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10366 .dig_in_nid = ALC883_DIGIN_NID,
10367 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10368 .channel_mode = alc883_3ST_2ch_modes,
10369 .input_mux = &alc883_capture_source,
10370 },
10371 [ALC883_3ST_6ch_DIG] = {
10372 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10373 .init_verbs = { alc883_init_verbs },
10374 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10375 .dac_nids = alc883_dac_nids,
10376 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10377 .dig_in_nid = ALC883_DIGIN_NID,
10378 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10379 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10380 .need_dac_fix = 1,
9c7f852e 10381 .input_mux = &alc883_capture_source,
f12ab1e0 10382 },
9c7f852e
TI
10383 [ALC883_3ST_6ch] = {
10384 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10385 .init_verbs = { alc883_init_verbs },
10386 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10387 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10388 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10389 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10390 .need_dac_fix = 1,
9c7f852e 10391 .input_mux = &alc883_capture_source,
f12ab1e0 10392 },
17bba1b7
J
10393 [ALC883_3ST_6ch_INTEL] = {
10394 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10395 .init_verbs = { alc883_init_verbs },
10396 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10397 .dac_nids = alc883_dac_nids,
10398 .dig_out_nid = ALC883_DIGOUT_NID,
10399 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10400 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10401 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10402 .channel_mode = alc883_3ST_6ch_intel_modes,
10403 .need_dac_fix = 1,
10404 .input_mux = &alc883_3stack_6ch_intel,
10405 },
87a8c370
JK
10406 [ALC889A_INTEL] = {
10407 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10408 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10409 alc_hp15_unsol_verbs },
87a8c370
JK
10410 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10411 .dac_nids = alc883_dac_nids,
10412 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10413 .adc_nids = alc889_adc_nids,
10414 .dig_out_nid = ALC883_DIGOUT_NID,
10415 .dig_in_nid = ALC883_DIGIN_NID,
10416 .slave_dig_outs = alc883_slave_dig_outs,
10417 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10418 .channel_mode = alc889_8ch_intel_modes,
10419 .capsrc_nids = alc889_capsrc_nids,
10420 .input_mux = &alc889_capture_source,
4f5d1706 10421 .setup = alc889_automute_setup,
d922b51d
TI
10422 .init_hook = alc_hp_automute,
10423 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10424 .need_dac_fix = 1,
10425 },
10426 [ALC889_INTEL] = {
10427 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10428 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10429 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10430 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10431 .dac_nids = alc883_dac_nids,
10432 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10433 .adc_nids = alc889_adc_nids,
10434 .dig_out_nid = ALC883_DIGOUT_NID,
10435 .dig_in_nid = ALC883_DIGIN_NID,
10436 .slave_dig_outs = alc883_slave_dig_outs,
10437 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10438 .channel_mode = alc889_8ch_intel_modes,
10439 .capsrc_nids = alc889_capsrc_nids,
10440 .input_mux = &alc889_capture_source,
4f5d1706 10441 .setup = alc889_automute_setup,
6732bd0d 10442 .init_hook = alc889_intel_init_hook,
d922b51d 10443 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10444 .need_dac_fix = 1,
10445 },
9c7f852e
TI
10446 [ALC883_6ST_DIG] = {
10447 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10448 .init_verbs = { alc883_init_verbs },
10449 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10450 .dac_nids = alc883_dac_nids,
10451 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10452 .dig_in_nid = ALC883_DIGIN_NID,
10453 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10454 .channel_mode = alc883_sixstack_modes,
10455 .input_mux = &alc883_capture_source,
10456 },
ccc656ce 10457 [ALC883_TARGA_DIG] = {
c259249f 10458 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10459 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10460 alc883_targa_verbs},
ccc656ce
KY
10461 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10462 .dac_nids = alc883_dac_nids,
10463 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10464 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10465 .channel_mode = alc883_3ST_6ch_modes,
10466 .need_dac_fix = 1,
10467 .input_mux = &alc883_capture_source,
c259249f 10468 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10469 .setup = alc882_targa_setup,
10470 .init_hook = alc882_targa_automute,
ccc656ce
KY
10471 },
10472 [ALC883_TARGA_2ch_DIG] = {
c259249f 10473 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10474 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10475 alc883_targa_verbs},
ccc656ce
KY
10476 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10477 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10478 .adc_nids = alc883_adc_nids_alt,
10479 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10480 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10481 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10482 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10483 .channel_mode = alc883_3ST_2ch_modes,
10484 .input_mux = &alc883_capture_source,
c259249f 10485 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10486 .setup = alc882_targa_setup,
10487 .init_hook = alc882_targa_automute,
ccc656ce 10488 },
64a8be74 10489 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10490 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10491 alc883_chmode_mixer },
64a8be74 10492 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10493 alc883_targa_verbs },
64a8be74
DH
10494 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10495 .dac_nids = alc883_dac_nids,
10496 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10497 .adc_nids = alc883_adc_nids_rev,
10498 .capsrc_nids = alc883_capsrc_nids_rev,
10499 .dig_out_nid = ALC883_DIGOUT_NID,
10500 .dig_in_nid = ALC883_DIGIN_NID,
10501 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10502 .channel_mode = alc883_4ST_8ch_modes,
10503 .need_dac_fix = 1,
10504 .input_mux = &alc883_capture_source,
c259249f 10505 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10506 .setup = alc882_targa_setup,
10507 .init_hook = alc882_targa_automute,
64a8be74 10508 },
bab282b9 10509 [ALC883_ACER] = {
676a9b53 10510 .mixers = { alc883_base_mixer },
bab282b9
VA
10511 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10512 * and the headphone jack. Turn this on and rely on the
10513 * standard mute methods whenever the user wants to turn
10514 * these outputs off.
10515 */
10516 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10517 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10518 .dac_nids = alc883_dac_nids,
bab282b9
VA
10519 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10520 .channel_mode = alc883_3ST_2ch_modes,
10521 .input_mux = &alc883_capture_source,
10522 },
2880a867 10523 [ALC883_ACER_ASPIRE] = {
676a9b53 10524 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10525 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10526 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10527 .dac_nids = alc883_dac_nids,
10528 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10529 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10530 .channel_mode = alc883_3ST_2ch_modes,
10531 .input_mux = &alc883_capture_source,
d922b51d 10532 .unsol_event = alc_sku_unsol_event,
4f5d1706 10533 .setup = alc883_acer_aspire_setup,
d922b51d 10534 .init_hook = alc_hp_automute,
d1a991a6 10535 },
5b2d1eca 10536 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10537 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10538 alc883_chmode_mixer },
10539 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10540 alc888_acer_aspire_4930g_verbs },
10541 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10542 .dac_nids = alc883_dac_nids,
10543 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10544 .adc_nids = alc883_adc_nids_rev,
10545 .capsrc_nids = alc883_capsrc_nids_rev,
10546 .dig_out_nid = ALC883_DIGOUT_NID,
10547 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10548 .channel_mode = alc883_3ST_6ch_modes,
10549 .need_dac_fix = 1,
973b8cb0 10550 .const_channel_count = 6,
5b2d1eca 10551 .num_mux_defs =
ef8ef5fb
VP
10552 ARRAY_SIZE(alc888_2_capture_sources),
10553 .input_mux = alc888_2_capture_sources,
d922b51d 10554 .unsol_event = alc_sku_unsol_event,
4f5d1706 10555 .setup = alc888_acer_aspire_4930g_setup,
d922b51d 10556 .init_hook = alc_hp_automute,
d2fd4b09
TV
10557 },
10558 [ALC888_ACER_ASPIRE_6530G] = {
10559 .mixers = { alc888_acer_aspire_6530_mixer },
10560 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10561 alc888_acer_aspire_6530g_verbs },
10562 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10563 .dac_nids = alc883_dac_nids,
10564 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10565 .adc_nids = alc883_adc_nids_rev,
10566 .capsrc_nids = alc883_capsrc_nids_rev,
10567 .dig_out_nid = ALC883_DIGOUT_NID,
10568 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10569 .channel_mode = alc883_3ST_2ch_modes,
10570 .num_mux_defs =
10571 ARRAY_SIZE(alc888_2_capture_sources),
10572 .input_mux = alc888_acer_aspire_6530_sources,
d922b51d 10573 .unsol_event = alc_sku_unsol_event,
4f5d1706 10574 .setup = alc888_acer_aspire_6530g_setup,
d922b51d 10575 .init_hook = alc_hp_automute,
5b2d1eca 10576 },
3b315d70 10577 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10578 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10579 alc883_chmode_mixer },
10580 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10581 alc889_acer_aspire_8930g_verbs,
10582 alc889_eapd_verbs},
3b315d70
HM
10583 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10584 .dac_nids = alc883_dac_nids,
018df418
HM
10585 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10586 .adc_nids = alc889_adc_nids,
10587 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10588 .dig_out_nid = ALC883_DIGOUT_NID,
10589 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10590 .channel_mode = alc883_3ST_6ch_modes,
10591 .need_dac_fix = 1,
10592 .const_channel_count = 6,
10593 .num_mux_defs =
018df418
HM
10594 ARRAY_SIZE(alc889_capture_sources),
10595 .input_mux = alc889_capture_sources,
d922b51d 10596 .unsol_event = alc_sku_unsol_event,
4f5d1706 10597 .setup = alc889_acer_aspire_8930g_setup,
d922b51d 10598 .init_hook = alc_hp_automute,
f5de24b0 10599#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10600 .power_hook = alc_power_eapd,
f5de24b0 10601#endif
3b315d70 10602 },
fc86f954
DK
10603 [ALC888_ACER_ASPIRE_7730G] = {
10604 .mixers = { alc883_3ST_6ch_mixer,
10605 alc883_chmode_mixer },
10606 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10607 alc888_acer_aspire_7730G_verbs },
10608 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10609 .dac_nids = alc883_dac_nids,
10610 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10611 .adc_nids = alc883_adc_nids_rev,
10612 .capsrc_nids = alc883_capsrc_nids_rev,
10613 .dig_out_nid = ALC883_DIGOUT_NID,
10614 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10615 .channel_mode = alc883_3ST_6ch_modes,
10616 .need_dac_fix = 1,
10617 .const_channel_count = 6,
10618 .input_mux = &alc883_capture_source,
d922b51d 10619 .unsol_event = alc_sku_unsol_event,
d9477207 10620 .setup = alc888_acer_aspire_7730g_setup,
d922b51d 10621 .init_hook = alc_hp_automute,
fc86f954 10622 },
c07584c8
TD
10623 [ALC883_MEDION] = {
10624 .mixers = { alc883_fivestack_mixer,
10625 alc883_chmode_mixer },
10626 .init_verbs = { alc883_init_verbs,
b373bdeb 10627 alc883_medion_eapd_verbs },
c07584c8
TD
10628 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10629 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10630 .adc_nids = alc883_adc_nids_alt,
10631 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10632 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10633 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10634 .channel_mode = alc883_sixstack_modes,
10635 .input_mux = &alc883_capture_source,
b373bdeb 10636 },
7ad7b218
MC
10637 [ALC883_MEDION_WIM2160] = {
10638 .mixers = { alc883_medion_wim2160_mixer },
10639 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10641 .dac_nids = alc883_dac_nids,
10642 .dig_out_nid = ALC883_DIGOUT_NID,
10643 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10644 .adc_nids = alc883_adc_nids,
10645 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10646 .channel_mode = alc883_3ST_2ch_modes,
10647 .input_mux = &alc883_capture_source,
d922b51d 10648 .unsol_event = alc_sku_unsol_event,
7ad7b218 10649 .setup = alc883_medion_wim2160_setup,
d922b51d 10650 .init_hook = alc_hp_automute,
7ad7b218 10651 },
b373bdeb 10652 [ALC883_LAPTOP_EAPD] = {
676a9b53 10653 .mixers = { alc883_base_mixer },
b373bdeb
AN
10654 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10655 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10656 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10657 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10658 .channel_mode = alc883_3ST_2ch_modes,
10659 .input_mux = &alc883_capture_source,
10660 },
a65cc60f 10661 [ALC883_CLEVO_M540R] = {
10662 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10663 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10664 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10665 .dac_nids = alc883_dac_nids,
10666 .dig_out_nid = ALC883_DIGOUT_NID,
10667 .dig_in_nid = ALC883_DIGIN_NID,
10668 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10669 .channel_mode = alc883_3ST_6ch_clevo_modes,
10670 .need_dac_fix = 1,
10671 .input_mux = &alc883_capture_source,
10672 /* This machine has the hardware HP auto-muting, thus
10673 * we need no software mute via unsol event
10674 */
10675 },
0c4cc443
HRK
10676 [ALC883_CLEVO_M720] = {
10677 .mixers = { alc883_clevo_m720_mixer },
10678 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10679 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10680 .dac_nids = alc883_dac_nids,
10681 .dig_out_nid = ALC883_DIGOUT_NID,
10682 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10683 .channel_mode = alc883_3ST_2ch_modes,
10684 .input_mux = &alc883_capture_source,
0c4cc443 10685 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10686 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10687 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10688 },
bc9f98a9
KY
10689 [ALC883_LENOVO_101E_2ch] = {
10690 .mixers = { alc883_lenovo_101e_2ch_mixer},
10691 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10692 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10693 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10694 .adc_nids = alc883_adc_nids_alt,
10695 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10696 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10697 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10698 .channel_mode = alc883_3ST_2ch_modes,
10699 .input_mux = &alc883_lenovo_101e_capture_source,
e6a5e1b7
TI
10700 .setup = alc883_lenovo_101e_setup,
10701 .unsol_event = alc_sku_unsol_event,
10702 .init_hook = alc_inithook,
bc9f98a9 10703 },
272a527c
KY
10704 [ALC883_LENOVO_NB0763] = {
10705 .mixers = { alc883_lenovo_nb0763_mixer },
10706 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10707 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10708 .dac_nids = alc883_dac_nids,
272a527c
KY
10709 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10710 .channel_mode = alc883_3ST_2ch_modes,
10711 .need_dac_fix = 1,
10712 .input_mux = &alc883_lenovo_nb0763_capture_source,
d922b51d 10713 .unsol_event = alc_sku_unsol_event,
dc427170 10714 .setup = alc883_lenovo_nb0763_setup,
d922b51d 10715 .init_hook = alc_hp_automute,
272a527c
KY
10716 },
10717 [ALC888_LENOVO_MS7195_DIG] = {
10718 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10719 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10720 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10721 .dac_nids = alc883_dac_nids,
10722 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10723 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10724 .channel_mode = alc883_3ST_6ch_modes,
10725 .need_dac_fix = 1,
10726 .input_mux = &alc883_capture_source,
e6a5e1b7
TI
10727 .unsol_event = alc_sku_unsol_event,
10728 .setup = alc888_lenovo_ms7195_setup,
10729 .init_hook = alc_inithook,
189609ae
KY
10730 },
10731 [ALC883_HAIER_W66] = {
c259249f 10732 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10733 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10734 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10735 .dac_nids = alc883_dac_nids,
10736 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10737 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10738 .channel_mode = alc883_3ST_2ch_modes,
10739 .input_mux = &alc883_capture_source,
d922b51d 10740 .unsol_event = alc_sku_unsol_event,
4f5d1706 10741 .setup = alc883_haier_w66_setup,
d922b51d 10742 .init_hook = alc_hp_automute,
eea6419e 10743 },
4723c022 10744 [ALC888_3ST_HP] = {
eea6419e 10745 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10746 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10747 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10748 .dac_nids = alc883_dac_nids,
4723c022
CM
10749 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10750 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10751 .need_dac_fix = 1,
10752 .input_mux = &alc883_capture_source,
d922b51d 10753 .unsol_event = alc_sku_unsol_event,
4f5d1706 10754 .setup = alc888_3st_hp_setup,
d922b51d 10755 .init_hook = alc_hp_automute,
8341de60 10756 },
5795b9e6 10757 [ALC888_6ST_DELL] = {
f24dbdc6 10758 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10759 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10760 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10761 .dac_nids = alc883_dac_nids,
10762 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10763 .dig_in_nid = ALC883_DIGIN_NID,
10764 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10765 .channel_mode = alc883_sixstack_modes,
10766 .input_mux = &alc883_capture_source,
d922b51d 10767 .unsol_event = alc_sku_unsol_event,
4f5d1706 10768 .setup = alc888_6st_dell_setup,
d922b51d 10769 .init_hook = alc_hp_automute,
5795b9e6 10770 },
a8848bd6
AS
10771 [ALC883_MITAC] = {
10772 .mixers = { alc883_mitac_mixer },
10773 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10774 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10775 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10776 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10777 .channel_mode = alc883_3ST_2ch_modes,
10778 .input_mux = &alc883_capture_source,
d922b51d 10779 .unsol_event = alc_sku_unsol_event,
4f5d1706 10780 .setup = alc883_mitac_setup,
d922b51d 10781 .init_hook = alc_hp_automute,
a8848bd6 10782 },
fb97dc67
J
10783 [ALC883_FUJITSU_PI2515] = {
10784 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10785 .init_verbs = { alc883_init_verbs,
10786 alc883_2ch_fujitsu_pi2515_verbs},
10787 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10788 .dac_nids = alc883_dac_nids,
10789 .dig_out_nid = ALC883_DIGOUT_NID,
10790 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10791 .channel_mode = alc883_3ST_2ch_modes,
10792 .input_mux = &alc883_fujitsu_pi2515_capture_source,
d922b51d 10793 .unsol_event = alc_sku_unsol_event,
4f5d1706 10794 .setup = alc883_2ch_fujitsu_pi2515_setup,
d922b51d 10795 .init_hook = alc_hp_automute,
fb97dc67 10796 },
ef8ef5fb
VP
10797 [ALC888_FUJITSU_XA3530] = {
10798 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10799 .init_verbs = { alc883_init_verbs,
10800 alc888_fujitsu_xa3530_verbs },
10801 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10802 .dac_nids = alc883_dac_nids,
10803 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10804 .adc_nids = alc883_adc_nids_rev,
10805 .capsrc_nids = alc883_capsrc_nids_rev,
10806 .dig_out_nid = ALC883_DIGOUT_NID,
10807 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10808 .channel_mode = alc888_4ST_8ch_intel_modes,
10809 .num_mux_defs =
10810 ARRAY_SIZE(alc888_2_capture_sources),
10811 .input_mux = alc888_2_capture_sources,
d922b51d 10812 .unsol_event = alc_sku_unsol_event,
4f5d1706 10813 .setup = alc888_fujitsu_xa3530_setup,
d922b51d 10814 .init_hook = alc_hp_automute,
ef8ef5fb 10815 },
e2757d5e
KY
10816 [ALC888_LENOVO_SKY] = {
10817 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10818 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10819 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10820 .dac_nids = alc883_dac_nids,
10821 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10822 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10823 .channel_mode = alc883_sixstack_modes,
10824 .need_dac_fix = 1,
10825 .input_mux = &alc883_lenovo_sky_capture_source,
d922b51d 10826 .unsol_event = alc_sku_unsol_event,
4f5d1706 10827 .setup = alc888_lenovo_sky_setup,
d922b51d 10828 .init_hook = alc_hp_automute,
e2757d5e
KY
10829 },
10830 [ALC888_ASUS_M90V] = {
10831 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10832 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10833 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10834 .dac_nids = alc883_dac_nids,
10835 .dig_out_nid = ALC883_DIGOUT_NID,
10836 .dig_in_nid = ALC883_DIGIN_NID,
10837 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10838 .channel_mode = alc883_3ST_6ch_modes,
10839 .need_dac_fix = 1,
10840 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10841 .unsol_event = alc_sku_unsol_event,
10842 .setup = alc883_mode2_setup,
10843 .init_hook = alc_inithook,
e2757d5e
KY
10844 },
10845 [ALC888_ASUS_EEE1601] = {
10846 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10847 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10848 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10849 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10850 .dac_nids = alc883_dac_nids,
10851 .dig_out_nid = ALC883_DIGOUT_NID,
10852 .dig_in_nid = ALC883_DIGIN_NID,
10853 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10854 .channel_mode = alc883_3ST_2ch_modes,
10855 .need_dac_fix = 1,
10856 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10857 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10858 .init_hook = alc883_eee1601_inithook,
10859 },
3ab90935
WF
10860 [ALC1200_ASUS_P5Q] = {
10861 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10862 .init_verbs = { alc883_init_verbs },
10863 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10864 .dac_nids = alc883_dac_nids,
10865 .dig_out_nid = ALC1200_DIGOUT_NID,
10866 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10867 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10868 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10869 .channel_mode = alc883_sixstack_modes,
10870 .input_mux = &alc883_capture_source,
10871 },
eb4c41d3
TS
10872 [ALC889A_MB31] = {
10873 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10874 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10875 alc880_gpio1_init_verbs },
10876 .adc_nids = alc883_adc_nids,
10877 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10878 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10879 .dac_nids = alc883_dac_nids,
10880 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10881 .channel_mode = alc889A_mb31_6ch_modes,
10882 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10883 .input_mux = &alc889A_mb31_capture_source,
10884 .dig_out_nid = ALC883_DIGOUT_NID,
10885 .unsol_event = alc889A_mb31_unsol_event,
10886 .init_hook = alc889A_mb31_automute,
10887 },
3e1647c5
GG
10888 [ALC883_SONY_VAIO_TT] = {
10889 .mixers = { alc883_vaiott_mixer },
10890 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10891 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10892 .dac_nids = alc883_dac_nids,
10893 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10894 .channel_mode = alc883_3ST_2ch_modes,
10895 .input_mux = &alc883_capture_source,
d922b51d 10896 .unsol_event = alc_sku_unsol_event,
4f5d1706 10897 .setup = alc883_vaiott_setup,
d922b51d 10898 .init_hook = alc_hp_automute,
3e1647c5 10899 },
9c7f852e
TI
10900};
10901
10902
4953550a
TI
10903/*
10904 * Pin config fixes
10905 */
10906enum {
954a29c8 10907 PINFIX_ABIT_AW9D_MAX,
32eea388 10908 PINFIX_LENOVO_Y530,
954a29c8 10909 PINFIX_PB_M5210,
c3d226ab 10910 PINFIX_ACER_ASPIRE_7736,
c6b35874 10911 PINFIX_GIGABYTE_880GM,
4953550a
TI
10912};
10913
f8f25ba3
TI
10914static const struct alc_fixup alc882_fixups[] = {
10915 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10916 .type = ALC_FIXUP_PINS,
10917 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10918 { 0x15, 0x01080104 }, /* side */
10919 { 0x16, 0x01011012 }, /* rear */
10920 { 0x17, 0x01016011 }, /* clfe */
10921 { }
10922 }
f8f25ba3 10923 },
32eea388
DH
10924 [PINFIX_LENOVO_Y530] = {
10925 .type = ALC_FIXUP_PINS,
10926 .v.pins = (const struct alc_pincfg[]) {
10927 { 0x15, 0x99130112 }, /* rear int speakers */
10928 { 0x16, 0x99130111 }, /* subwoofer */
10929 { }
10930 }
10931 },
954a29c8 10932 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10933 .type = ALC_FIXUP_VERBS,
10934 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10935 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10936 {}
10937 }
954a29c8 10938 },
c3d226ab 10939 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10940 .type = ALC_FIXUP_SKU,
10941 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10942 },
c6b35874
TI
10943 [PINFIX_GIGABYTE_880GM] = {
10944 .type = ALC_FIXUP_PINS,
10945 .v.pins = (const struct alc_pincfg[]) {
10946 { 0x14, 0x1114410 }, /* set as speaker */
10947 { }
10948 }
10949 },
4953550a
TI
10950};
10951
f8f25ba3 10952static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10953 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10954 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10955 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10956 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
c6b35874 10957 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM),
4953550a
TI
10958 {}
10959};
10960
9c7f852e
TI
10961/*
10962 * BIOS auto configuration
10963 */
05f5f477
TI
10964static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10965 const struct auto_pin_cfg *cfg)
10966{
10967 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10968}
10969
4953550a 10970static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10971 hda_nid_t nid, int pin_type,
489008cd 10972 hda_nid_t dac)
9c7f852e 10973{
f12ab1e0
TI
10974 int idx;
10975
489008cd 10976 /* set as output */
f6c7e546 10977 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10978
10979 if (dac == 0x25)
9c7f852e 10980 idx = 4;
489008cd
TI
10981 else if (dac >= 0x02 && dac <= 0x05)
10982 idx = dac - 2;
f9700d5a 10983 else
489008cd 10984 return;
9c7f852e 10985 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10986}
10987
4953550a 10988static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10989{
10990 struct alc_spec *spec = codec->spec;
10991 int i;
10992
10993 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10994 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10995 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10996 if (nid)
4953550a 10997 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10998 spec->multiout.dac_nids[i]);
9c7f852e
TI
10999 }
11000}
11001
4953550a 11002static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
11003{
11004 struct alc_spec *spec = codec->spec;
489008cd 11005 hda_nid_t pin, dac;
5855fb80 11006 int i;
9c7f852e 11007
0a3fabe3
DH
11008 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11009 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11010 pin = spec->autocfg.hp_pins[i];
11011 if (!pin)
11012 break;
11013 dac = spec->multiout.hp_nid;
11014 if (!dac)
11015 dac = spec->multiout.dac_nids[0]; /* to front */
11016 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11017 }
489008cd 11018 }
0a3fabe3
DH
11019
11020 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11021 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11022 pin = spec->autocfg.speaker_pins[i];
11023 if (!pin)
11024 break;
11025 dac = spec->multiout.extra_out_nid[0];
11026 if (!dac)
11027 dac = spec->multiout.dac_nids[0]; /* to front */
11028 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11029 }
489008cd 11030 }
9c7f852e
TI
11031}
11032
4953550a 11033static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
11034{
11035 struct alc_spec *spec = codec->spec;
66ceeb6b 11036 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
11037 int i;
11038
66ceeb6b
TI
11039 for (i = 0; i < cfg->num_inputs; i++) {
11040 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 11041 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
11042 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11043 snd_hda_codec_write(codec, nid, 0,
11044 AC_VERB_SET_AMP_GAIN_MUTE,
11045 AMP_OUT_MUTE);
11046 }
11047}
11048
11049static void alc882_auto_init_input_src(struct hda_codec *codec)
11050{
11051 struct alc_spec *spec = codec->spec;
11052 int c;
11053
11054 for (c = 0; c < spec->num_adc_nids; c++) {
11055 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11056 hda_nid_t nid = spec->capsrc_nids[c];
11057 unsigned int mux_idx;
11058 const struct hda_input_mux *imux;
11059 int conns, mute, idx, item;
11060
10696aa0
TI
11061 /* mute ADC */
11062 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11063 AC_VERB_SET_AMP_GAIN_MUTE,
11064 AMP_IN_MUTE(0));
11065
4953550a
TI
11066 conns = snd_hda_get_connections(codec, nid, conn_list,
11067 ARRAY_SIZE(conn_list));
11068 if (conns < 0)
11069 continue;
11070 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11071 imux = &spec->input_mux[mux_idx];
5311114d
TI
11072 if (!imux->num_items && mux_idx > 0)
11073 imux = &spec->input_mux[0];
4953550a
TI
11074 for (idx = 0; idx < conns; idx++) {
11075 /* if the current connection is the selected one,
11076 * unmute it as default - otherwise mute it
11077 */
11078 mute = AMP_IN_MUTE(idx);
11079 for (item = 0; item < imux->num_items; item++) {
11080 if (imux->items[item].index == idx) {
11081 if (spec->cur_mux[c] == item)
11082 mute = AMP_IN_UNMUTE(idx);
11083 break;
11084 }
11085 }
11086 /* check if we have a selector or mixer
11087 * we could check for the widget type instead, but
11088 * just check for Amp-In presence (in case of mixer
11089 * without amp-in there is something wrong, this
11090 * function shouldn't be used or capsrc nid is wrong)
11091 */
11092 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
11093 snd_hda_codec_write(codec, nid, 0,
11094 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
11095 mute);
11096 else if (mute != AMP_IN_MUTE(idx))
11097 snd_hda_codec_write(codec, nid, 0,
11098 AC_VERB_SET_CONNECT_SEL,
11099 idx);
9c7f852e
TI
11100 }
11101 }
11102}
11103
4953550a
TI
11104/* add mic boosts if needed */
11105static int alc_auto_add_mic_boost(struct hda_codec *codec)
11106{
11107 struct alc_spec *spec = codec->spec;
66ceeb6b 11108 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 11109 int i, err;
53e8c323 11110 int type_idx = 0;
4953550a 11111 hda_nid_t nid;
5322bf27 11112 const char *prev_label = NULL;
4953550a 11113
66ceeb6b 11114 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 11115 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
11116 break;
11117 nid = cfg->inputs[i].pin;
11118 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
11119 const char *label;
11120 char boost_label[32];
11121
11122 label = hda_get_autocfg_input_label(codec, cfg, i);
11123 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
11124 type_idx++;
11125 else
11126 type_idx = 0;
5322bf27
DH
11127 prev_label = label;
11128
11129 snprintf(boost_label, sizeof(boost_label),
11130 "%s Boost Volume", label);
11131 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11132 boost_label, type_idx,
4953550a 11133 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
11134 if (err < 0)
11135 return err;
11136 }
4953550a
TI
11137 }
11138 return 0;
11139}
f511b01c 11140
9c7f852e 11141/* almost identical with ALC880 parser... */
4953550a 11142static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
11143{
11144 struct alc_spec *spec = codec->spec;
05f5f477 11145 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 11146 int err;
9c7f852e 11147
05f5f477
TI
11148 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11149 alc882_ignore);
9c7f852e
TI
11150 if (err < 0)
11151 return err;
05f5f477
TI
11152 if (!spec->autocfg.line_outs)
11153 return 0; /* can't find valid BIOS pin config */
776e184e 11154
05f5f477 11155 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
11156 if (err < 0)
11157 return err;
11158 err = alc_auto_add_multi_channel_mode(codec);
05f5f477
TI
11159 if (err < 0)
11160 return err;
569ed348 11161 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
11162 if (err < 0)
11163 return err;
11164 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11165 "Headphone");
05f5f477
TI
11166 if (err < 0)
11167 return err;
11168 err = alc880_auto_create_extra_out(spec,
11169 spec->autocfg.speaker_pins[0],
11170 "Speaker");
11171 if (err < 0)
11172 return err;
05f5f477 11173 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
11174 if (err < 0)
11175 return err;
11176
05f5f477
TI
11177 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11178
757899ac 11179 alc_auto_parse_digital(codec);
05f5f477
TI
11180
11181 if (spec->kctls.list)
11182 add_mixer(spec, spec->kctls.list);
11183
11184 add_verb(spec, alc883_auto_init_verbs);
4953550a 11185 /* if ADC 0x07 is available, initialize it, too */
05f5f477 11186 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 11187 add_verb(spec, alc882_adc1_init_verbs);
776e184e 11188
05f5f477
TI
11189 spec->num_mux_defs = 1;
11190 spec->input_mux = &spec->private_imux[0];
11191
6227cdce 11192 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
11193
11194 err = alc_auto_add_mic_boost(codec);
11195 if (err < 0)
11196 return err;
61b9b9b1 11197
776e184e 11198 return 1; /* config found */
9c7f852e
TI
11199}
11200
11201/* additional initialization for auto-configuration model */
4953550a 11202static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 11203{
f6c7e546 11204 struct alc_spec *spec = codec->spec;
4953550a
TI
11205 alc882_auto_init_multi_out(codec);
11206 alc882_auto_init_hp_out(codec);
11207 alc882_auto_init_analog_input(codec);
11208 alc882_auto_init_input_src(codec);
757899ac 11209 alc_auto_init_digital(codec);
f6c7e546 11210 if (spec->unsol_event)
7fb0d78f 11211 alc_inithook(codec);
9c7f852e
TI
11212}
11213
4953550a 11214static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
11215{
11216 struct alc_spec *spec;
11217 int err, board_config;
11218
11219 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11220 if (spec == NULL)
11221 return -ENOMEM;
11222
11223 codec->spec = spec;
11224
4953550a
TI
11225 switch (codec->vendor_id) {
11226 case 0x10ec0882:
11227 case 0x10ec0885:
11228 break;
11229 default:
11230 /* ALC883 and variants */
11231 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11232 break;
11233 }
2c3bf9ab 11234
4953550a
TI
11235 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11236 alc882_models,
11237 alc882_cfg_tbl);
11238
11239 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11240 board_config = snd_hda_check_board_codec_sid_config(codec,
11241 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11242
11243 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11244 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11245 codec->chip_name);
11246 board_config = ALC882_AUTO;
9c7f852e
TI
11247 }
11248
b5bfbc67
TI
11249 if (board_config == ALC882_AUTO) {
11250 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11251 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11252 }
4953550a 11253
90622917
DH
11254 alc_auto_parse_customize_define(codec);
11255
4953550a 11256 if (board_config == ALC882_AUTO) {
9c7f852e 11257 /* automatic parse from the BIOS config */
4953550a 11258 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11259 if (err < 0) {
11260 alc_free(codec);
11261 return err;
f12ab1e0 11262 } else if (!err) {
9c7f852e
TI
11263 printk(KERN_INFO
11264 "hda_codec: Cannot set up configuration "
11265 "from BIOS. Using base mode...\n");
4953550a 11266 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11267 }
11268 }
11269
dc1eae25 11270 if (has_cdefine_beep(codec)) {
8af2591d
TI
11271 err = snd_hda_attach_beep_device(codec, 0x1);
11272 if (err < 0) {
11273 alc_free(codec);
11274 return err;
11275 }
680cd536
KK
11276 }
11277
4953550a 11278 if (board_config != ALC882_AUTO)
e9c364c0 11279 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11280
4953550a
TI
11281 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11282 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11283 /* FIXME: setup DAC5 */
11284 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11285 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11286
11287 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11288 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11289
4953550a 11290 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11291 int i, j;
4953550a
TI
11292 spec->num_adc_nids = 0;
11293 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11294 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11295 hda_nid_t cap;
d11f74c6 11296 hda_nid_t items[16];
4953550a
TI
11297 hda_nid_t nid = alc882_adc_nids[i];
11298 unsigned int wcap = get_wcaps(codec, nid);
11299 /* get type */
a22d543a 11300 wcap = get_wcaps_type(wcap);
4953550a
TI
11301 if (wcap != AC_WID_AUD_IN)
11302 continue;
11303 spec->private_adc_nids[spec->num_adc_nids] = nid;
11304 err = snd_hda_get_connections(codec, nid, &cap, 1);
11305 if (err < 0)
11306 continue;
d11f74c6
TI
11307 err = snd_hda_get_connections(codec, cap, items,
11308 ARRAY_SIZE(items));
11309 if (err < 0)
11310 continue;
11311 for (j = 0; j < imux->num_items; j++)
11312 if (imux->items[j].index >= err)
11313 break;
11314 if (j < imux->num_items)
11315 continue;
4953550a
TI
11316 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11317 spec->num_adc_nids++;
61b9b9b1 11318 }
4953550a
TI
11319 spec->adc_nids = spec->private_adc_nids;
11320 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11321 }
11322
b59bdf3b 11323 set_capture_mixer(codec);
da00c244 11324
dc1eae25 11325 if (has_cdefine_beep(codec))
da00c244 11326 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11327
b5bfbc67 11328 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11329
2134ea4f
TI
11330 spec->vmaster_nid = 0x0c;
11331
9c7f852e 11332 codec->patch_ops = alc_patch_ops;
4953550a
TI
11333 if (board_config == ALC882_AUTO)
11334 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11335
11336 alc_init_jacks(codec);
cb53c626
TI
11337#ifdef CONFIG_SND_HDA_POWER_SAVE
11338 if (!spec->loopback.amplist)
4953550a 11339 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11340#endif
9c7f852e
TI
11341
11342 return 0;
11343}
11344
4953550a 11345
9c7f852e
TI
11346/*
11347 * ALC262 support
11348 */
11349
11350#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11351#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11352
11353#define alc262_dac_nids alc260_dac_nids
11354#define alc262_adc_nids alc882_adc_nids
11355#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11356#define alc262_capsrc_nids alc882_capsrc_nids
11357#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11358
11359#define alc262_modes alc260_modes
11360#define alc262_capture_source alc882_capture_source
11361
4e555fe5
KY
11362static hda_nid_t alc262_dmic_adc_nids[1] = {
11363 /* ADC0 */
11364 0x09
11365};
11366
11367static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11368
9c7f852e
TI
11369static struct snd_kcontrol_new alc262_base_mixer[] = {
11370 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11371 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11372 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11373 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11374 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11375 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11376 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11377 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11378 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11379 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11380 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11381 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11382 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11383 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11384 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11385 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11386 { } /* end */
11387};
11388
ce875f07 11389/* update HP, line and mono-out pins according to the master switch */
e9427969 11390#define alc262_hp_master_update alc260_hp_master_update
ce875f07 11391
e9427969 11392static void alc262_hp_bpc_setup(struct hda_codec *codec)
ce875f07
TI
11393{
11394 struct alc_spec *spec = codec->spec;
864f92be 11395
e9427969
TI
11396 spec->autocfg.hp_pins[0] = 0x1b;
11397 spec->autocfg.speaker_pins[0] = 0x16;
11398 spec->automute = 1;
11399 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11400}
11401
e9427969 11402static void alc262_hp_wildwest_setup(struct hda_codec *codec)
ce875f07
TI
11403{
11404 struct alc_spec *spec = codec->spec;
864f92be 11405
e9427969
TI
11406 spec->autocfg.hp_pins[0] = 0x15;
11407 spec->autocfg.speaker_pins[0] = 0x16;
11408 spec->automute = 1;
11409 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11410}
11411
b72519b5 11412#define alc262_hp_master_sw_get alc260_hp_master_sw_get
e9427969 11413#define alc262_hp_master_sw_put alc260_hp_master_sw_put
ce875f07 11414
b72519b5
TI
11415#define ALC262_HP_MASTER_SWITCH \
11416 { \
11417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11418 .name = "Master Playback Switch", \
11419 .info = snd_ctl_boolean_mono_info, \
11420 .get = alc262_hp_master_sw_get, \
11421 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11422 }, \
11423 { \
11424 .iface = NID_MAPPING, \
11425 .name = "Master Playback Switch", \
11426 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11427 }
11428
5b0cb1d8 11429
9c7f852e 11430static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11431 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11432 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11433 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11434 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11435 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11436 HDA_OUTPUT),
11437 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11438 HDA_OUTPUT),
9c7f852e
TI
11439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11440 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11441 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11442 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11443 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11444 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11445 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11446 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11447 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11448 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11449 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11450 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11451 { } /* end */
11452};
11453
cd7509a4 11454static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11455 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11456 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11457 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11458 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11459 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11460 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11461 HDA_OUTPUT),
11462 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11463 HDA_OUTPUT),
cd7509a4
KY
11464 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11465 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11466 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11467 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11468 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11469 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11470 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11471 { } /* end */
11472};
11473
11474static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11475 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11476 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11477 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11478 { } /* end */
11479};
11480
66d2a9d6 11481/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11482static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11483{
11484 struct alc_spec *spec = codec->spec;
66d2a9d6 11485
a9fd4f3f 11486 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11487 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
11488 spec->automute = 1;
11489 spec->automute_mode = ALC_AUTOMUTE_PIN;
66d2a9d6
KY
11490}
11491
66d2a9d6 11492static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11493 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11494 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11495 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11496 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11497 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11498 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11499 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11500 { } /* end */
11501};
11502
11503static struct hda_verb alc262_hp_t5735_verbs[] = {
11504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11505 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11506
11507 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11508 { }
11509};
11510
8c427226 11511static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11512 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11514 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11515 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11516 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11517 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11518 { } /* end */
11519};
11520
11521static struct hda_verb alc262_hp_rp5700_verbs[] = {
11522 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11523 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11524 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11525 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11526 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11527 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11529 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11532 {}
11533};
11534
11535static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11536 .num_items = 1,
11537 .items = {
11538 { "Line", 0x1 },
11539 },
11540};
11541
42171c17 11542/* bind hp and internal speaker mute (with plug check) as master switch */
e9427969 11543#define alc262_hippo_master_update alc262_hp_master_update
42171c17 11544#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
e9427969 11545#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
42171c17
TI
11546
11547#define ALC262_HIPPO_MASTER_SWITCH \
11548 { \
11549 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11550 .name = "Master Playback Switch", \
11551 .info = snd_ctl_boolean_mono_info, \
11552 .get = alc262_hippo_master_sw_get, \
11553 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11554 }, \
11555 { \
11556 .iface = NID_MAPPING, \
11557 .name = "Master Playback Switch", \
11558 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11559 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11560 }
42171c17
TI
11561
11562static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11563 ALC262_HIPPO_MASTER_SWITCH,
11564 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11565 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11566 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11567 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11568 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11569 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11570 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11571 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11572 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11573 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11574 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11575 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11576 { } /* end */
11577};
11578
11579static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11580 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11581 ALC262_HIPPO_MASTER_SWITCH,
11582 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11583 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11584 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11585 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11586 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11588 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11589 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11590 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11591 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11592 { } /* end */
11593};
11594
11595/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11596static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11597{
11598 struct alc_spec *spec = codec->spec;
11599
11600 spec->autocfg.hp_pins[0] = 0x15;
11601 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11602 spec->automute = 1;
11603 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11604}
11605
4f5d1706 11606static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11607{
11608 struct alc_spec *spec = codec->spec;
11609
11610 spec->autocfg.hp_pins[0] = 0x1b;
11611 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11612 spec->automute = 1;
11613 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11614}
11615
11616
272a527c 11617static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11618 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11619 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11620 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11621 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11622 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11623 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11624 { } /* end */
11625};
11626
83c34218 11627static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11628 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11629 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11630 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11632 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11633 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11634 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11635 { } /* end */
11636};
272a527c 11637
ba340e82
TV
11638static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11639 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11640 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11641 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11642 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11643 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11644 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11645 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11646 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11647 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11648 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11649 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11650 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11651 { } /* end */
11652};
11653
11654static struct hda_verb alc262_tyan_verbs[] = {
11655 /* Headphone automute */
11656 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11657 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11658 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11659
11660 /* P11 AUX_IN, white 4-pin connector */
11661 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11662 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11663 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11664 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11665
11666 {}
11667};
11668
11669/* unsolicited event for HP jack sensing */
4f5d1706 11670static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11671{
a9fd4f3f 11672 struct alc_spec *spec = codec->spec;
ba340e82 11673
a9fd4f3f
TI
11674 spec->autocfg.hp_pins[0] = 0x1b;
11675 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
11676 spec->automute = 1;
11677 spec->automute_mode = ALC_AUTOMUTE_AMP;
ba340e82
TV
11678}
11679
ba340e82 11680
9c7f852e
TI
11681#define alc262_capture_mixer alc882_capture_mixer
11682#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11683
11684/*
11685 * generic initialization of ADC, input mixers and output mixers
11686 */
11687static struct hda_verb alc262_init_verbs[] = {
11688 /*
11689 * Unmute ADC0-2 and set the default input to mic-in
11690 */
11691 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11693 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11694 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11695 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11696 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11697
cb53c626 11698 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11699 * mixer widget
f12ab1e0
TI
11700 * Note: PASD motherboards uses the Line In 2 as the input for
11701 * front panel mic (mic 2)
9c7f852e
TI
11702 */
11703 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11704 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11705 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11706 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11707 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11708 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11709
11710 /*
df694daa
KY
11711 * Set up output mixers (0x0c - 0x0e)
11712 */
11713 /* set vol=0 to output mixers */
11714 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11715 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11716 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11717 /* set up input amps for analog loopback */
11718 /* Amp Indices: DAC = 0, mixer = 1 */
11719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11720 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11721 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11722 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11723 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11725
11726 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11727 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11728 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11729 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11730 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11731 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11732
11733 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11735 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11736 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11737 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11738
df694daa
KY
11739 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11740 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11741
df694daa
KY
11742 /* FIXME: use matrix-type input source selection */
11743 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11744 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11745 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11746 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11747 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11748 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11749 /* Input mixer2 */
11750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11752 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11754 /* Input mixer3 */
11755 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11759
11760 { }
11761};
1da177e4 11762
4e555fe5
KY
11763static struct hda_verb alc262_eapd_verbs[] = {
11764 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11765 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11766 { }
11767};
11768
ccc656ce
KY
11769static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11770 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11771 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11772 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11773
11774 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11775 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11776 {}
11777};
11778
272a527c
KY
11779static struct hda_verb alc262_sony_unsol_verbs[] = {
11780 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11781 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11782 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11783
11784 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11785 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11786 {}
272a527c
KY
11787};
11788
4e555fe5
KY
11789static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11790 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11791 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11792 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11795 { } /* end */
11796};
11797
11798static struct hda_verb alc262_toshiba_s06_verbs[] = {
11799 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11800 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11802 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11803 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11804 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11805 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11806 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11807 {}
11808};
11809
4f5d1706 11810static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11811{
a9fd4f3f
TI
11812 struct alc_spec *spec = codec->spec;
11813
11814 spec->autocfg.hp_pins[0] = 0x15;
11815 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11816 spec->ext_mic.pin = 0x18;
11817 spec->ext_mic.mux_idx = 0;
11818 spec->int_mic.pin = 0x12;
11819 spec->int_mic.mux_idx = 9;
11820 spec->auto_mic = 1;
d922b51d
TI
11821 spec->automute = 1;
11822 spec->automute_mode = ALC_AUTOMUTE_PIN;
4e555fe5
KY
11823}
11824
e8f9ae2a
PT
11825/*
11826 * nec model
11827 * 0x15 = headphone
11828 * 0x16 = internal speaker
11829 * 0x18 = external mic
11830 */
11831
11832static struct snd_kcontrol_new alc262_nec_mixer[] = {
11833 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11834 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11835
11836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11837 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11838 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11839
11840 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11842 { } /* end */
11843};
11844
11845static struct hda_verb alc262_nec_verbs[] = {
11846 /* Unmute Speaker */
11847 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11848
11849 /* Headphone */
11850 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11851 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11852
11853 /* External mic to headphone */
11854 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11855 /* External mic to speaker */
11856 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11857 {}
11858};
11859
834be88d
TI
11860/*
11861 * fujitsu model
5d9fab2d
TV
11862 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11863 * 0x1b = port replicator headphone out
834be88d
TI
11864 */
11865
11866#define ALC_HP_EVENT 0x37
11867
11868static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11869 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11870 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11871 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11872 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11873 {}
11874};
11875
0e31daf7
J
11876static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11877 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11878 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11879 {}
11880};
11881
e2595322
DC
11882static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11883 /* Front Mic pin: input vref at 50% */
11884 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11885 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11886 {}
11887};
11888
834be88d 11889static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11890 .num_items = 3,
834be88d
TI
11891 .items = {
11892 { "Mic", 0x0 },
28c4edb7 11893 { "Internal Mic", 0x1 },
834be88d
TI
11894 { "CD", 0x4 },
11895 },
11896};
11897
9c7f852e
TI
11898static struct hda_input_mux alc262_HP_capture_source = {
11899 .num_items = 5,
11900 .items = {
11901 { "Mic", 0x0 },
accbe498 11902 { "Front Mic", 0x1 },
9c7f852e
TI
11903 { "Line", 0x2 },
11904 { "CD", 0x4 },
11905 { "AUX IN", 0x6 },
11906 },
11907};
11908
accbe498 11909static struct hda_input_mux alc262_HP_D7000_capture_source = {
11910 .num_items = 4,
11911 .items = {
11912 { "Mic", 0x0 },
11913 { "Front Mic", 0x2 },
11914 { "Line", 0x1 },
11915 { "CD", 0x4 },
11916 },
11917};
11918
0f0f391c 11919static void alc262_fujitsu_setup(struct hda_codec *codec)
834be88d
TI
11920{
11921 struct alc_spec *spec = codec->spec;
834be88d 11922
0f0f391c
TI
11923 spec->autocfg.hp_pins[0] = 0x14;
11924 spec->autocfg.hp_pins[1] = 0x1b;
11925 spec->autocfg.speaker_pins[0] = 0x15;
11926 spec->automute = 1;
11927 spec->automute_mode = ALC_AUTOMUTE_AMP;
ebc7a406
TI
11928}
11929
834be88d 11930/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11931static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11932 .ops = &snd_hda_bind_vol,
11933 .values = {
11934 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11935 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11936 0
11937 },
11938};
834be88d 11939
834be88d 11940static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11941 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11942 {
11943 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11944 .name = "Master Playback Switch",
0f0f391c
TI
11945 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11946 .info = snd_ctl_boolean_mono_info,
11947 .get = alc262_hp_master_sw_get,
11948 .put = alc262_hp_master_sw_put,
834be88d 11949 },
5b0cb1d8
JK
11950 {
11951 .iface = NID_MAPPING,
11952 .name = "Master Playback Switch",
11953 .private_value = 0x1b,
11954 },
834be88d
TI
11955 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11956 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11957 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11958 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11959 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11960 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11961 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11962 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11963 { } /* end */
11964};
11965
0f0f391c 11966static void alc262_lenovo_3000_setup(struct hda_codec *codec)
0e31daf7 11967{
0f0f391c 11968 struct alc_spec *spec = codec->spec;
0e31daf7 11969
0f0f391c
TI
11970 spec->autocfg.hp_pins[0] = 0x1b;
11971 spec->autocfg.speaker_pins[0] = 0x14;
11972 spec->autocfg.speaker_pins[1] = 0x16;
11973 spec->automute = 1;
11974 spec->automute_mode = ALC_AUTOMUTE_AMP;
0e31daf7
J
11975}
11976
11977static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11978 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11979 {
11980 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11981 .name = "Master Playback Switch",
0f0f391c
TI
11982 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11983 .info = snd_ctl_boolean_mono_info,
11984 .get = alc262_hp_master_sw_get,
11985 .put = alc262_hp_master_sw_put,
0e31daf7
J
11986 },
11987 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11988 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11989 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11990 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11992 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11993 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11994 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11995 { } /* end */
11996};
11997
9f99a638
HM
11998static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11999 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 12000 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
12001 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12003 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
12004 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12005 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 12006 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
12007 { } /* end */
12008};
12009
304dcaac
TI
12010/* additional init verbs for Benq laptops */
12011static struct hda_verb alc262_EAPD_verbs[] = {
12012 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12013 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12014 {}
12015};
12016
83c34218
KY
12017static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12018 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12019 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12020
12021 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12022 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12023 {}
12024};
12025
f651b50b
TD
12026/* Samsung Q1 Ultra Vista model setup */
12027static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
12028 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12029 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
12030 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12031 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
12032 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12033 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
12034 { } /* end */
12035};
12036
12037static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
12038 /* output mixer */
12039 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12040 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12041 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12042 /* speaker */
12043 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12044 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12045 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12046 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12047 /* HP */
f651b50b 12048 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
12049 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12050 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12051 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12052 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12053 /* internal mic */
12054 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12055 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12056 /* ADC, choose mic */
12057 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12058 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12059 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12060 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12061 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12062 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12063 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12064 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12065 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12066 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12067 {}
12068};
12069
f651b50b
TD
12070/* mute/unmute internal speaker according to the hp jack and mute state */
12071static void alc262_ultra_automute(struct hda_codec *codec)
12072{
12073 struct alc_spec *spec = codec->spec;
12074 unsigned int mute;
f651b50b 12075
bb9f76cd
TI
12076 mute = 0;
12077 /* auto-mute only when HP is used as HP */
12078 if (!spec->cur_mux[0]) {
864f92be 12079 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12080 if (spec->jack_present)
12081 mute = HDA_AMP_MUTE;
f651b50b 12082 }
bb9f76cd
TI
12083 /* mute/unmute internal speaker */
12084 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12085 HDA_AMP_MUTE, mute);
12086 /* mute/unmute HP */
12087 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12088 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12089}
12090
12091/* unsolicited event for HP jack sensing */
12092static void alc262_ultra_unsol_event(struct hda_codec *codec,
12093 unsigned int res)
12094{
12095 if ((res >> 26) != ALC880_HP_EVENT)
12096 return;
12097 alc262_ultra_automute(codec);
12098}
12099
bb9f76cd
TI
12100static struct hda_input_mux alc262_ultra_capture_source = {
12101 .num_items = 2,
12102 .items = {
12103 { "Mic", 0x1 },
12104 { "Headphone", 0x7 },
12105 },
12106};
12107
12108static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12109 struct snd_ctl_elem_value *ucontrol)
12110{
12111 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12112 struct alc_spec *spec = codec->spec;
12113 int ret;
12114
54cbc9ab 12115 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12116 if (!ret)
12117 return 0;
12118 /* reprogram the HP pin as mic or HP according to the input source */
12119 snd_hda_codec_write_cache(codec, 0x15, 0,
12120 AC_VERB_SET_PIN_WIDGET_CONTROL,
12121 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12122 alc262_ultra_automute(codec); /* mute/unmute HP */
12123 return ret;
12124}
12125
12126static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12127 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12128 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12129 {
12130 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12131 .name = "Capture Source",
54cbc9ab
TI
12132 .info = alc_mux_enum_info,
12133 .get = alc_mux_enum_get,
bb9f76cd
TI
12134 .put = alc262_ultra_mux_enum_put,
12135 },
5b0cb1d8
JK
12136 {
12137 .iface = NID_MAPPING,
12138 .name = "Capture Source",
12139 .private_value = 0x15,
12140 },
bb9f76cd
TI
12141 { } /* end */
12142};
12143
c3fc1f50
TI
12144/* We use two mixers depending on the output pin; 0x16 is a mono output
12145 * and thus it's bound with a different mixer.
12146 * This function returns which mixer amp should be used.
12147 */
12148static int alc262_check_volbit(hda_nid_t nid)
12149{
12150 if (!nid)
12151 return 0;
12152 else if (nid == 0x16)
12153 return 2;
12154 else
12155 return 1;
12156}
12157
12158static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12159 const char *pfx, int *vbits, int idx)
c3fc1f50 12160{
c3fc1f50
TI
12161 unsigned long val;
12162 int vbit;
12163
12164 vbit = alc262_check_volbit(nid);
12165 if (!vbit)
12166 return 0;
12167 if (*vbits & vbit) /* a volume control for this mixer already there */
12168 return 0;
12169 *vbits |= vbit;
c3fc1f50
TI
12170 if (vbit == 2)
12171 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12172 else
12173 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12174 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12175}
12176
12177static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12178 const char *pfx, int idx)
c3fc1f50 12179{
c3fc1f50
TI
12180 unsigned long val;
12181
12182 if (!nid)
12183 return 0;
c3fc1f50
TI
12184 if (nid == 0x16)
12185 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12186 else
12187 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12188 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12189}
12190
df694daa 12191/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12192static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12193 const struct auto_pin_cfg *cfg)
df694daa 12194{
c3fc1f50
TI
12195 const char *pfx;
12196 int vbits;
033688a5 12197 int i, err;
df694daa
KY
12198
12199 spec->multiout.num_dacs = 1; /* only use one dac */
12200 spec->multiout.dac_nids = spec->private_dac_nids;
12201 spec->multiout.dac_nids[0] = 2;
12202
ce764ab2 12203 pfx = alc_get_line_out_pfx(spec, true);
bcb2f0f5 12204 if (!pfx)
c3fc1f50 12205 pfx = "Front";
033688a5
TI
12206 for (i = 0; i < 2; i++) {
12207 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12208 if (err < 0)
12209 return err;
12210 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12211 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12212 "Speaker", i);
12213 if (err < 0)
12214 return err;
12215 }
12216 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12217 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12218 "Headphone", i);
12219 if (err < 0)
12220 return err;
12221 }
12222 }
df694daa 12223
c3fc1f50
TI
12224 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12225 alc262_check_volbit(cfg->speaker_pins[0]) |
12226 alc262_check_volbit(cfg->hp_pins[0]);
12227 if (vbits == 1 || vbits == 2)
12228 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12229 vbits = 0;
033688a5
TI
12230 for (i = 0; i < 2; i++) {
12231 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12232 &vbits, i);
12233 if (err < 0)
12234 return err;
12235 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12236 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12237 "Speaker", &vbits, i);
12238 if (err < 0)
12239 return err;
12240 }
12241 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12242 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12243 "Headphone", &vbits, i);
12244 if (err < 0)
12245 return err;
12246 }
12247 }
f12ab1e0 12248 return 0;
df694daa
KY
12249}
12250
05f5f477 12251#define alc262_auto_create_input_ctls \
eaa9b3a7 12252 alc882_auto_create_input_ctls
df694daa
KY
12253
12254/*
12255 * generic initialization of ADC, input mixers and output mixers
12256 */
12257static struct hda_verb alc262_volume_init_verbs[] = {
12258 /*
12259 * Unmute ADC0-2 and set the default input to mic-in
12260 */
12261 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12262 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12263 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12264 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12265 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12266 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12267
cb53c626 12268 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12269 * mixer widget
f12ab1e0
TI
12270 * Note: PASD motherboards uses the Line In 2 as the input for
12271 * front panel mic (mic 2)
df694daa
KY
12272 */
12273 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12274 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12275 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12276 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12277 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12278 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12279
12280 /*
12281 * Set up output mixers (0x0c - 0x0f)
12282 */
12283 /* set vol=0 to output mixers */
12284 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12285 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12287
df694daa
KY
12288 /* set up input amps for analog loopback */
12289 /* Amp Indices: DAC = 0, mixer = 1 */
12290 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12291 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12292 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12293 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12294 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12295 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12296
12297 /* FIXME: use matrix-type input source selection */
12298 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12299 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12300 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12303 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12304 /* Input mixer2 */
12305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12309 /* Input mixer3 */
12310 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12314
12315 { }
12316};
12317
9c7f852e
TI
12318static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12319 /*
12320 * Unmute ADC0-2 and set the default input to mic-in
12321 */
12322 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12324 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12326 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12327 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12328
cb53c626 12329 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12330 * mixer widget
f12ab1e0
TI
12331 * Note: PASD motherboards uses the Line In 2 as the input for
12332 * front panel mic (mic 2)
9c7f852e
TI
12333 */
12334 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12335 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12341 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12342
9c7f852e
TI
12343 /*
12344 * Set up output mixers (0x0c - 0x0e)
12345 */
12346 /* set vol=0 to output mixers */
12347 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12348 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12349 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12350
12351 /* set up input amps for analog loopback */
12352 /* Amp Indices: DAC = 0, mixer = 1 */
12353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12355 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12356 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12357 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12358 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12359
ce875f07 12360 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12361 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12362 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12363
12364 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12366
12367 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12368 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12369
12370 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12371 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12372 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12373 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12374 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12375
0e4835c1 12376 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12377 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12378 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12379 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12380 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12381 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12382
12383
12384 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12385 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12386 /* Input mixer1: only unmute Mic */
9c7f852e 12387 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12388 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12389 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12390 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12391 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12392 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12393 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12394 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12395 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12396 /* Input mixer2 */
12397 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12398 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12399 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12400 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12401 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12402 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12403 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12404 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12405 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12406 /* Input mixer3 */
12407 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12408 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12409 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12410 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12411 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12412 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12413 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12414 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12415 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12416
ce875f07
TI
12417 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12418
9c7f852e
TI
12419 { }
12420};
12421
cd7509a4
KY
12422static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12423 /*
12424 * Unmute ADC0-2 and set the default input to mic-in
12425 */
12426 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12427 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12428 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12429 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12430 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12431 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12432
cb53c626 12433 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12434 * mixer widget
12435 * Note: PASD motherboards uses the Line In 2 as the input for front
12436 * panel mic (mic 2)
12437 */
12438 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12439 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12440 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12441 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12442 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12443 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12444 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12445 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12446 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12447 /*
12448 * Set up output mixers (0x0c - 0x0e)
12449 */
12450 /* set vol=0 to output mixers */
12451 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12452 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12453 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12454
12455 /* set up input amps for analog loopback */
12456 /* Amp Indices: DAC = 0, mixer = 1 */
12457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12461 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12462 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12463
12464
12465 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12467 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12471 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12472
12473 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12474 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12475
12476 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12478
12479 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12480 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12481 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12482 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12483 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12484 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12485
12486 /* FIXME: use matrix-type input source selection */
12487 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12488 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12489 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12490 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12491 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12492 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12493 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12494 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12495 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12496 /* Input mixer2 */
12497 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12498 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12499 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12500 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12501 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12502 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12503 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12504 /* Input mixer3 */
12505 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12506 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12507 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12508 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12509 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12510 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12511 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12512
ce875f07
TI
12513 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12514
cd7509a4
KY
12515 { }
12516};
12517
9f99a638
HM
12518static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12519
12520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12521 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12522 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12523
12524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12525 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12526 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12527 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12528
12529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12530 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12531 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12532 {}
12533};
12534
18675e42
TI
12535/*
12536 * Pin config fixes
12537 */
12538enum {
12539 PINFIX_FSC_H270,
12540};
12541
12542static const struct alc_fixup alc262_fixups[] = {
12543 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12544 .type = ALC_FIXUP_PINS,
12545 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12546 { 0x14, 0x99130110 }, /* speaker */
12547 { 0x15, 0x0221142f }, /* front HP */
12548 { 0x1b, 0x0121141f }, /* rear HP */
12549 { }
12550 }
12551 },
18675e42
TI
12552};
12553
12554static struct snd_pci_quirk alc262_fixup_tbl[] = {
12555 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12556 {}
12557};
12558
9f99a638 12559
cb53c626
TI
12560#ifdef CONFIG_SND_HDA_POWER_SAVE
12561#define alc262_loopbacks alc880_loopbacks
12562#endif
12563
def319f9 12564/* pcm configuration: identical with ALC880 */
df694daa
KY
12565#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12566#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12567#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12568#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12569
12570/*
12571 * BIOS auto configuration
12572 */
12573static int alc262_parse_auto_config(struct hda_codec *codec)
12574{
12575 struct alc_spec *spec = codec->spec;
12576 int err;
12577 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12578
f12ab1e0
TI
12579 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12580 alc262_ignore);
12581 if (err < 0)
df694daa 12582 return err;
e64f14f4 12583 if (!spec->autocfg.line_outs) {
0852d7a6 12584 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12585 spec->multiout.max_channels = 2;
12586 spec->no_analog = 1;
12587 goto dig_only;
12588 }
df694daa 12589 return 0; /* can't find valid BIOS pin config */
e64f14f4 12590 }
f12ab1e0
TI
12591 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12592 if (err < 0)
12593 return err;
05f5f477 12594 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12595 if (err < 0)
df694daa
KY
12596 return err;
12597
12598 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12599
e64f14f4 12600 dig_only:
757899ac 12601 alc_auto_parse_digital(codec);
df694daa 12602
603c4019 12603 if (spec->kctls.list)
d88897ea 12604 add_mixer(spec, spec->kctls.list);
df694daa 12605
d88897ea 12606 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12607 spec->num_mux_defs = 1;
61b9b9b1 12608 spec->input_mux = &spec->private_imux[0];
df694daa 12609
776e184e
TI
12610 err = alc_auto_add_mic_boost(codec);
12611 if (err < 0)
12612 return err;
12613
6227cdce 12614 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12615
df694daa
KY
12616 return 1;
12617}
12618
12619#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12620#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12621#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12622#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12623
12624
12625/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12626static void alc262_auto_init(struct hda_codec *codec)
df694daa 12627{
f6c7e546 12628 struct alc_spec *spec = codec->spec;
df694daa
KY
12629 alc262_auto_init_multi_out(codec);
12630 alc262_auto_init_hp_out(codec);
12631 alc262_auto_init_analog_input(codec);
f511b01c 12632 alc262_auto_init_input_src(codec);
757899ac 12633 alc_auto_init_digital(codec);
f6c7e546 12634 if (spec->unsol_event)
7fb0d78f 12635 alc_inithook(codec);
df694daa
KY
12636}
12637
12638/*
12639 * configuration and preset
12640 */
ea734963 12641static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12642 [ALC262_BASIC] = "basic",
12643 [ALC262_HIPPO] = "hippo",
12644 [ALC262_HIPPO_1] = "hippo_1",
12645 [ALC262_FUJITSU] = "fujitsu",
12646 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12647 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12648 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12649 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12650 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12651 [ALC262_BENQ_T31] = "benq-t31",
12652 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12653 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12654 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12655 [ALC262_ULTRA] = "ultra",
0e31daf7 12656 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12657 [ALC262_NEC] = "nec",
ba340e82 12658 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12659 [ALC262_AUTO] = "auto",
12660};
12661
12662static struct snd_pci_quirk alc262_cfg_tbl[] = {
12663 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12664 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12665 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12666 ALC262_HP_BPC),
12667 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12668 ALC262_HP_BPC),
5734a07c
TI
12669 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12670 ALC262_HP_BPC),
53eff7e1
TI
12671 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12672 ALC262_HP_BPC),
cd7509a4 12673 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12674 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12675 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12676 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12677 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12678 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12679 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12680 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12681 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12682 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12683 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12684 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12685 ALC262_HP_TC_T5735),
8c427226 12686 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12687 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12688 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12689 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12690 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12691 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12692 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12693 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12694#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12695 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12696 ALC262_SONY_ASSAMD),
c5b5165c 12697#endif
36ca6e13 12698 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12699 ALC262_TOSHIBA_RX1),
80ffe869 12700 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12701 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12702 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12703 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12704 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12705 ALC262_ULTRA),
3e420e78 12706 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12707 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12708 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12709 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12710 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12711 {}
12712};
12713
12714static struct alc_config_preset alc262_presets[] = {
12715 [ALC262_BASIC] = {
12716 .mixers = { alc262_base_mixer },
12717 .init_verbs = { alc262_init_verbs },
12718 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12719 .dac_nids = alc262_dac_nids,
12720 .hp_nid = 0x03,
12721 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12722 .channel_mode = alc262_modes,
a3bcba38 12723 .input_mux = &alc262_capture_source,
df694daa 12724 },
ccc656ce 12725 [ALC262_HIPPO] = {
42171c17 12726 .mixers = { alc262_hippo_mixer },
6732bd0d 12727 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12728 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12729 .dac_nids = alc262_dac_nids,
12730 .hp_nid = 0x03,
12731 .dig_out_nid = ALC262_DIGOUT_NID,
12732 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12733 .channel_mode = alc262_modes,
12734 .input_mux = &alc262_capture_source,
e9427969 12735 .unsol_event = alc_sku_unsol_event,
4f5d1706 12736 .setup = alc262_hippo_setup,
e9427969 12737 .init_hook = alc_inithook,
ccc656ce
KY
12738 },
12739 [ALC262_HIPPO_1] = {
12740 .mixers = { alc262_hippo1_mixer },
12741 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12742 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12743 .dac_nids = alc262_dac_nids,
12744 .hp_nid = 0x02,
12745 .dig_out_nid = ALC262_DIGOUT_NID,
12746 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12747 .channel_mode = alc262_modes,
12748 .input_mux = &alc262_capture_source,
e9427969 12749 .unsol_event = alc_sku_unsol_event,
4f5d1706 12750 .setup = alc262_hippo1_setup,
e9427969 12751 .init_hook = alc_inithook,
ccc656ce 12752 },
834be88d
TI
12753 [ALC262_FUJITSU] = {
12754 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12755 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12756 alc262_fujitsu_unsol_verbs },
834be88d
TI
12757 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12758 .dac_nids = alc262_dac_nids,
12759 .hp_nid = 0x03,
12760 .dig_out_nid = ALC262_DIGOUT_NID,
12761 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12762 .channel_mode = alc262_modes,
12763 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12764 .unsol_event = alc_sku_unsol_event,
12765 .setup = alc262_fujitsu_setup,
12766 .init_hook = alc_inithook,
834be88d 12767 },
9c7f852e
TI
12768 [ALC262_HP_BPC] = {
12769 .mixers = { alc262_HP_BPC_mixer },
12770 .init_verbs = { alc262_HP_BPC_init_verbs },
12771 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12772 .dac_nids = alc262_dac_nids,
12773 .hp_nid = 0x03,
12774 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12775 .channel_mode = alc262_modes,
12776 .input_mux = &alc262_HP_capture_source,
e9427969
TI
12777 .unsol_event = alc_sku_unsol_event,
12778 .setup = alc262_hp_bpc_setup,
12779 .init_hook = alc_inithook,
f12ab1e0 12780 },
cd7509a4
KY
12781 [ALC262_HP_BPC_D7000_WF] = {
12782 .mixers = { alc262_HP_BPC_WildWest_mixer },
12783 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12784 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12785 .dac_nids = alc262_dac_nids,
12786 .hp_nid = 0x03,
12787 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12788 .channel_mode = alc262_modes,
accbe498 12789 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12790 .unsol_event = alc_sku_unsol_event,
12791 .setup = alc262_hp_wildwest_setup,
12792 .init_hook = alc_inithook,
f12ab1e0 12793 },
cd7509a4
KY
12794 [ALC262_HP_BPC_D7000_WL] = {
12795 .mixers = { alc262_HP_BPC_WildWest_mixer,
12796 alc262_HP_BPC_WildWest_option_mixer },
12797 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12798 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12799 .dac_nids = alc262_dac_nids,
12800 .hp_nid = 0x03,
12801 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12802 .channel_mode = alc262_modes,
accbe498 12803 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12804 .unsol_event = alc_sku_unsol_event,
12805 .setup = alc262_hp_wildwest_setup,
12806 .init_hook = alc_inithook,
f12ab1e0 12807 },
66d2a9d6
KY
12808 [ALC262_HP_TC_T5735] = {
12809 .mixers = { alc262_hp_t5735_mixer },
12810 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12811 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12812 .dac_nids = alc262_dac_nids,
12813 .hp_nid = 0x03,
12814 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12815 .channel_mode = alc262_modes,
12816 .input_mux = &alc262_capture_source,
dc99be47 12817 .unsol_event = alc_sku_unsol_event,
4f5d1706 12818 .setup = alc262_hp_t5735_setup,
dc99be47 12819 .init_hook = alc_inithook,
8c427226
KY
12820 },
12821 [ALC262_HP_RP5700] = {
12822 .mixers = { alc262_hp_rp5700_mixer },
12823 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12824 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12825 .dac_nids = alc262_dac_nids,
12826 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12827 .channel_mode = alc262_modes,
12828 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12829 },
304dcaac
TI
12830 [ALC262_BENQ_ED8] = {
12831 .mixers = { alc262_base_mixer },
12832 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12833 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12834 .dac_nids = alc262_dac_nids,
12835 .hp_nid = 0x03,
12836 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12837 .channel_mode = alc262_modes,
12838 .input_mux = &alc262_capture_source,
f12ab1e0 12839 },
272a527c
KY
12840 [ALC262_SONY_ASSAMD] = {
12841 .mixers = { alc262_sony_mixer },
12842 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12843 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12844 .dac_nids = alc262_dac_nids,
12845 .hp_nid = 0x02,
12846 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12847 .channel_mode = alc262_modes,
12848 .input_mux = &alc262_capture_source,
e9427969 12849 .unsol_event = alc_sku_unsol_event,
4f5d1706 12850 .setup = alc262_hippo_setup,
e9427969 12851 .init_hook = alc_inithook,
83c34218
KY
12852 },
12853 [ALC262_BENQ_T31] = {
12854 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12855 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12856 alc_hp15_unsol_verbs },
83c34218
KY
12857 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12858 .dac_nids = alc262_dac_nids,
12859 .hp_nid = 0x03,
12860 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12861 .channel_mode = alc262_modes,
12862 .input_mux = &alc262_capture_source,
e9427969 12863 .unsol_event = alc_sku_unsol_event,
4f5d1706 12864 .setup = alc262_hippo_setup,
e9427969 12865 .init_hook = alc_inithook,
ea1fb29a 12866 },
f651b50b 12867 [ALC262_ULTRA] = {
f9e336f6
TI
12868 .mixers = { alc262_ultra_mixer },
12869 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12870 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12871 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12872 .dac_nids = alc262_dac_nids,
f651b50b
TD
12873 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12874 .channel_mode = alc262_modes,
12875 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12876 .adc_nids = alc262_adc_nids, /* ADC0 */
12877 .capsrc_nids = alc262_capsrc_nids,
12878 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12879 .unsol_event = alc262_ultra_unsol_event,
12880 .init_hook = alc262_ultra_automute,
12881 },
0e31daf7
J
12882 [ALC262_LENOVO_3000] = {
12883 .mixers = { alc262_lenovo_3000_mixer },
12884 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12885 alc262_lenovo_3000_unsol_verbs,
12886 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12887 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12888 .dac_nids = alc262_dac_nids,
12889 .hp_nid = 0x03,
12890 .dig_out_nid = ALC262_DIGOUT_NID,
12891 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12892 .channel_mode = alc262_modes,
12893 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12894 .unsol_event = alc_sku_unsol_event,
12895 .setup = alc262_lenovo_3000_setup,
12896 .init_hook = alc_inithook,
0e31daf7 12897 },
e8f9ae2a
PT
12898 [ALC262_NEC] = {
12899 .mixers = { alc262_nec_mixer },
12900 .init_verbs = { alc262_nec_verbs },
12901 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12902 .dac_nids = alc262_dac_nids,
12903 .hp_nid = 0x03,
12904 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12905 .channel_mode = alc262_modes,
12906 .input_mux = &alc262_capture_source,
12907 },
4e555fe5
KY
12908 [ALC262_TOSHIBA_S06] = {
12909 .mixers = { alc262_toshiba_s06_mixer },
12910 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12911 alc262_eapd_verbs },
12912 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12913 .capsrc_nids = alc262_dmic_capsrc_nids,
12914 .dac_nids = alc262_dac_nids,
12915 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12916 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12917 .dig_out_nid = ALC262_DIGOUT_NID,
12918 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12919 .channel_mode = alc262_modes,
4f5d1706
TI
12920 .unsol_event = alc_sku_unsol_event,
12921 .setup = alc262_toshiba_s06_setup,
12922 .init_hook = alc_inithook,
4e555fe5 12923 },
9f99a638
HM
12924 [ALC262_TOSHIBA_RX1] = {
12925 .mixers = { alc262_toshiba_rx1_mixer },
12926 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12927 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12928 .dac_nids = alc262_dac_nids,
12929 .hp_nid = 0x03,
12930 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12931 .channel_mode = alc262_modes,
12932 .input_mux = &alc262_capture_source,
e9427969 12933 .unsol_event = alc_sku_unsol_event,
4f5d1706 12934 .setup = alc262_hippo_setup,
e9427969 12935 .init_hook = alc_inithook,
9f99a638 12936 },
ba340e82
TV
12937 [ALC262_TYAN] = {
12938 .mixers = { alc262_tyan_mixer },
12939 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12940 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12941 .dac_nids = alc262_dac_nids,
12942 .hp_nid = 0x02,
12943 .dig_out_nid = ALC262_DIGOUT_NID,
12944 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12945 .channel_mode = alc262_modes,
12946 .input_mux = &alc262_capture_source,
d922b51d 12947 .unsol_event = alc_sku_unsol_event,
4f5d1706 12948 .setup = alc262_tyan_setup,
d922b51d 12949 .init_hook = alc_hp_automute,
ba340e82 12950 },
df694daa
KY
12951};
12952
12953static int patch_alc262(struct hda_codec *codec)
12954{
12955 struct alc_spec *spec;
12956 int board_config;
12957 int err;
12958
dc041e0b 12959 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12960 if (spec == NULL)
12961 return -ENOMEM;
12962
12963 codec->spec = spec;
12964#if 0
f12ab1e0
TI
12965 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12966 * under-run
12967 */
df694daa
KY
12968 {
12969 int tmp;
12970 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12971 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12972 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12973 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12974 }
12975#endif
da00c244 12976 alc_auto_parse_customize_define(codec);
df694daa 12977
2c3bf9ab
TI
12978 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12979
f5fcc13c
TI
12980 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12981 alc262_models,
12982 alc262_cfg_tbl);
cd7509a4 12983
f5fcc13c 12984 if (board_config < 0) {
9a11f1aa
TI
12985 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12986 codec->chip_name);
df694daa
KY
12987 board_config = ALC262_AUTO;
12988 }
12989
b5bfbc67
TI
12990 if (board_config == ALC262_AUTO) {
12991 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12992 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12993 }
18675e42 12994
df694daa
KY
12995 if (board_config == ALC262_AUTO) {
12996 /* automatic parse from the BIOS config */
12997 err = alc262_parse_auto_config(codec);
12998 if (err < 0) {
12999 alc_free(codec);
13000 return err;
f12ab1e0 13001 } else if (!err) {
9c7f852e
TI
13002 printk(KERN_INFO
13003 "hda_codec: Cannot set up configuration "
13004 "from BIOS. Using base mode...\n");
df694daa
KY
13005 board_config = ALC262_BASIC;
13006 }
13007 }
13008
dc1eae25 13009 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
13010 err = snd_hda_attach_beep_device(codec, 0x1);
13011 if (err < 0) {
13012 alc_free(codec);
13013 return err;
13014 }
680cd536
KK
13015 }
13016
df694daa 13017 if (board_config != ALC262_AUTO)
e9c364c0 13018 setup_preset(codec, &alc262_presets[board_config]);
df694daa 13019
df694daa
KY
13020 spec->stream_analog_playback = &alc262_pcm_analog_playback;
13021 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 13022
df694daa
KY
13023 spec->stream_digital_playback = &alc262_pcm_digital_playback;
13024 spec->stream_digital_capture = &alc262_pcm_digital_capture;
13025
f12ab1e0 13026 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
13027 int i;
13028 /* check whether the digital-mic has to be supported */
13029 for (i = 0; i < spec->input_mux->num_items; i++) {
13030 if (spec->input_mux->items[i].index >= 9)
13031 break;
13032 }
13033 if (i < spec->input_mux->num_items) {
13034 /* use only ADC0 */
13035 spec->adc_nids = alc262_dmic_adc_nids;
13036 spec->num_adc_nids = 1;
13037 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 13038 } else {
8c927b4a
TI
13039 /* all analog inputs */
13040 /* check whether NID 0x07 is valid */
13041 unsigned int wcap = get_wcaps(codec, 0x07);
13042
13043 /* get type */
a22d543a 13044 wcap = get_wcaps_type(wcap);
8c927b4a
TI
13045 if (wcap != AC_WID_AUD_IN) {
13046 spec->adc_nids = alc262_adc_nids_alt;
13047 spec->num_adc_nids =
13048 ARRAY_SIZE(alc262_adc_nids_alt);
13049 spec->capsrc_nids = alc262_capsrc_nids_alt;
13050 } else {
13051 spec->adc_nids = alc262_adc_nids;
13052 spec->num_adc_nids =
13053 ARRAY_SIZE(alc262_adc_nids);
13054 spec->capsrc_nids = alc262_capsrc_nids;
13055 }
df694daa
KY
13056 }
13057 }
e64f14f4 13058 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13059 set_capture_mixer(codec);
dc1eae25 13060 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13061 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13062
b5bfbc67 13063 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13064
2134ea4f
TI
13065 spec->vmaster_nid = 0x0c;
13066
df694daa
KY
13067 codec->patch_ops = alc_patch_ops;
13068 if (board_config == ALC262_AUTO)
ae6b813a 13069 spec->init_hook = alc262_auto_init;
1c716153 13070 spec->shutup = alc_eapd_shutup;
bf1b0225
KY
13071
13072 alc_init_jacks(codec);
cb53c626
TI
13073#ifdef CONFIG_SND_HDA_POWER_SAVE
13074 if (!spec->loopback.amplist)
13075 spec->loopback.amplist = alc262_loopbacks;
13076#endif
ea1fb29a 13077
df694daa
KY
13078 return 0;
13079}
13080
a361d84b
KY
13081/*
13082 * ALC268 channel source setting (2 channel)
13083 */
13084#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13085#define alc268_modes alc260_modes
ea1fb29a 13086
a361d84b
KY
13087static hda_nid_t alc268_dac_nids[2] = {
13088 /* front, hp */
13089 0x02, 0x03
13090};
13091
13092static hda_nid_t alc268_adc_nids[2] = {
13093 /* ADC0-1 */
13094 0x08, 0x07
13095};
13096
13097static hda_nid_t alc268_adc_nids_alt[1] = {
13098 /* ADC0 */
13099 0x08
13100};
13101
e1406348
TI
13102static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13103
a361d84b
KY
13104static struct snd_kcontrol_new alc268_base_mixer[] = {
13105 /* output mixer control */
13106 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13107 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13108 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13109 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13110 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13111 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13112 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13113 { }
13114};
13115
42171c17
TI
13116static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13117 /* output mixer control */
13118 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13119 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13120 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13121 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13122 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13123 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13124 { }
13125};
13126
aef9d318
TI
13127/* bind Beep switches of both NID 0x0f and 0x10 */
13128static struct hda_bind_ctls alc268_bind_beep_sw = {
13129 .ops = &snd_hda_bind_sw,
13130 .values = {
13131 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13132 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13133 0
13134 },
13135};
13136
13137static struct snd_kcontrol_new alc268_beep_mixer[] = {
13138 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13139 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13140 { }
13141};
13142
d1a991a6
KY
13143static struct hda_verb alc268_eapd_verbs[] = {
13144 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13145 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13146 { }
13147};
13148
d273809e 13149/* Toshiba specific */
d273809e
TI
13150static struct hda_verb alc268_toshiba_verbs[] = {
13151 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13152 { } /* end */
13153};
13154
13155/* Acer specific */
889c4395 13156/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13157static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13158 .ops = &snd_hda_bind_vol,
13159 .values = {
13160 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13161 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13162 0
13163 },
13164};
13165
0f0f391c 13166static void alc268_acer_setup(struct hda_codec *codec)
889c4395
TI
13167{
13168 struct alc_spec *spec = codec->spec;
889c4395 13169
0f0f391c
TI
13170 spec->autocfg.hp_pins[0] = 0x14;
13171 spec->autocfg.speaker_pins[0] = 0x15;
13172 spec->automute = 1;
13173 spec->automute_mode = ALC_AUTOMUTE_AMP;
889c4395
TI
13174}
13175
0f0f391c
TI
13176#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13177#define alc268_acer_master_sw_put alc262_hp_master_sw_put
d273809e 13178
8ef355da
KY
13179static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13180 /* output mixer control */
13181 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13182 {
13183 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13184 .name = "Master Playback Switch",
0f0f391c
TI
13185 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13186 .info = snd_ctl_boolean_mono_info,
13187 .get = alc268_acer_master_sw_get,
8ef355da 13188 .put = alc268_acer_master_sw_put,
8ef355da
KY
13189 },
13190 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13191 { }
13192};
13193
d273809e
TI
13194static struct snd_kcontrol_new alc268_acer_mixer[] = {
13195 /* output mixer control */
13196 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13197 {
13198 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13199 .name = "Master Playback Switch",
0f0f391c
TI
13200 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13201 .info = snd_ctl_boolean_mono_info,
13202 .get = alc268_acer_master_sw_get,
d273809e 13203 .put = alc268_acer_master_sw_put,
d273809e 13204 },
5f99f86a
DH
13205 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13206 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13207 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13208 { }
13209};
13210
c238b4f4
TI
13211static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13212 /* output mixer control */
13213 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13214 {
13215 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13216 .name = "Master Playback Switch",
0f0f391c
TI
13217 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13218 .info = snd_ctl_boolean_mono_info,
13219 .get = alc268_acer_master_sw_get,
c238b4f4 13220 .put = alc268_acer_master_sw_put,
c238b4f4 13221 },
5f99f86a
DH
13222 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13223 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13224 { }
13225};
13226
8ef355da
KY
13227static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13228 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13229 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13230 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13231 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13232 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13233 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13234 { }
13235};
13236
d273809e 13237static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13238 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13239 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13240 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13241 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13242 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13243 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13244 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13245 { }
13246};
13247
13248/* unsolicited event for HP jack sensing */
4f5d1706 13249#define alc268_toshiba_setup alc262_hippo_setup
d273809e 13250
4f5d1706
TI
13251static void alc268_acer_lc_setup(struct hda_codec *codec)
13252{
13253 struct alc_spec *spec = codec->spec;
3b8510ce
TI
13254 spec->autocfg.hp_pins[0] = 0x15;
13255 spec->autocfg.speaker_pins[0] = 0x14;
13256 spec->automute_mixer_nid[0] = 0x0f;
13257 spec->automute = 1;
13258 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
13259 spec->ext_mic.pin = 0x18;
13260 spec->ext_mic.mux_idx = 0;
13261 spec->int_mic.pin = 0x12;
13262 spec->int_mic.mux_idx = 6;
13263 spec->auto_mic = 1;
8ef355da
KY
13264}
13265
3866f0b0
TI
13266static struct snd_kcontrol_new alc268_dell_mixer[] = {
13267 /* output mixer control */
13268 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13269 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13270 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13271 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, 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),
3866f0b0
TI
13274 { }
13275};
13276
13277static struct hda_verb alc268_dell_verbs[] = {
13278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13279 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13280 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13281 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13282 { }
13283};
13284
13285/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13286static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13287{
a9fd4f3f 13288 struct alc_spec *spec = codec->spec;
3866f0b0 13289
a9fd4f3f
TI
13290 spec->autocfg.hp_pins[0] = 0x15;
13291 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13292 spec->ext_mic.pin = 0x18;
13293 spec->ext_mic.mux_idx = 0;
13294 spec->int_mic.pin = 0x19;
13295 spec->int_mic.mux_idx = 1;
13296 spec->auto_mic = 1;
d922b51d
TI
13297 spec->automute = 1;
13298 spec->automute_mode = ALC_AUTOMUTE_PIN;
3866f0b0
TI
13299}
13300
eb5a6621
HRK
13301static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13302 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13303 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13304 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13305 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13306 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13307 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13308 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13309 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13310 { }
13311};
13312
13313static struct hda_verb alc267_quanta_il1_verbs[] = {
13314 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13315 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13316 { }
13317};
13318
4f5d1706 13319static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13320{
a9fd4f3f 13321 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13322 spec->autocfg.hp_pins[0] = 0x15;
13323 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13324 spec->ext_mic.pin = 0x18;
13325 spec->ext_mic.mux_idx = 0;
13326 spec->int_mic.pin = 0x19;
13327 spec->int_mic.mux_idx = 1;
13328 spec->auto_mic = 1;
d922b51d
TI
13329 spec->automute = 1;
13330 spec->automute_mode = ALC_AUTOMUTE_PIN;
eb5a6621
HRK
13331}
13332
a361d84b
KY
13333/*
13334 * generic initialization of ADC, input mixers and output mixers
13335 */
13336static struct hda_verb alc268_base_init_verbs[] = {
13337 /* Unmute DAC0-1 and set vol = 0 */
13338 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13339 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13340
13341 /*
13342 * Set up output mixers (0x0c - 0x0e)
13343 */
13344 /* set vol=0 to output mixers */
13345 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13346 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13347
13348 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13349 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13350
13351 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13352 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13353 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13354 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13355 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13356 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13357 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13358 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13359
13360 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13361 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13362 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13363 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13364 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13365
13366 /* set PCBEEP vol = 0, mute connections */
13367 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13368 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13369 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13370
a9b3aa8a 13371 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13372
a9b3aa8a
JZ
13373 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13374 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13375 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13377
a361d84b
KY
13378 { }
13379};
13380
13381/*
13382 * generic initialization of ADC, input mixers and output mixers
13383 */
13384static struct hda_verb alc268_volume_init_verbs[] = {
13385 /* set output DAC */
4cfb91c6
TI
13386 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13387 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13388
13389 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13390 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13391 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13392 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13393 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13394
a361d84b 13395 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13396 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13397 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13398
13399 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13400 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13401
aef9d318
TI
13402 /* set PCBEEP vol = 0, mute connections */
13403 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13404 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13405 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13406
13407 { }
13408};
13409
fdbc6626
TI
13410static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13411 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13412 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13413 { } /* end */
13414};
13415
a361d84b
KY
13416static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13417 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13418 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13419 _DEFINE_CAPSRC(1),
a361d84b
KY
13420 { } /* end */
13421};
13422
13423static struct snd_kcontrol_new alc268_capture_mixer[] = {
13424 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13425 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13426 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13427 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13428 _DEFINE_CAPSRC(2),
a361d84b
KY
13429 { } /* end */
13430};
13431
13432static struct hda_input_mux alc268_capture_source = {
13433 .num_items = 4,
13434 .items = {
13435 { "Mic", 0x0 },
13436 { "Front Mic", 0x1 },
13437 { "Line", 0x2 },
13438 { "CD", 0x3 },
13439 },
13440};
13441
0ccb541c 13442static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13443 .num_items = 3,
13444 .items = {
13445 { "Mic", 0x0 },
13446 { "Internal Mic", 0x1 },
13447 { "Line", 0x2 },
13448 },
13449};
13450
13451static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13452 .num_items = 3,
13453 .items = {
13454 { "Mic", 0x0 },
13455 { "Internal Mic", 0x6 },
13456 { "Line", 0x2 },
13457 },
13458};
13459
86c53bd2
JW
13460#ifdef CONFIG_SND_DEBUG
13461static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13462 /* Volume widgets */
13463 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13464 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13465 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13466 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13467 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13468 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13469 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13470 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13471 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13472 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13473 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13474 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13475 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13476 /* The below appears problematic on some hardwares */
13477 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13478 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13479 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13480 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13481 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13482
13483 /* Modes for retasking pin widgets */
13484 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13485 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13486 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13487 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13488
13489 /* Controls for GPIO pins, assuming they are configured as outputs */
13490 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13491 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13492 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13493 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13494
13495 /* Switches to allow the digital SPDIF output pin to be enabled.
13496 * The ALC268 does not have an SPDIF input.
13497 */
13498 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13499
13500 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13501 * this output to turn on an external amplifier.
13502 */
13503 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13504 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13505
13506 { } /* end */
13507};
13508#endif
13509
a361d84b
KY
13510/* create input playback/capture controls for the given pin */
13511static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13512 const char *ctlname, int idx)
13513{
3f3b7c1a 13514 hda_nid_t dac;
a361d84b
KY
13515 int err;
13516
3f3b7c1a
TI
13517 switch (nid) {
13518 case 0x14:
13519 case 0x16:
13520 dac = 0x02;
13521 break;
13522 case 0x15:
b08b1637
TI
13523 case 0x1a: /* ALC259/269 only */
13524 case 0x1b: /* ALC259/269 only */
531d8791 13525 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13526 dac = 0x03;
13527 break;
13528 default:
c7a9434d
TI
13529 snd_printd(KERN_WARNING "hda_codec: "
13530 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13531 return 0;
13532 }
13533 if (spec->multiout.dac_nids[0] != dac &&
13534 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13535 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13536 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13537 HDA_OUTPUT));
13538 if (err < 0)
13539 return err;
3f3b7c1a
TI
13540 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13541 }
13542
3f3b7c1a 13543 if (nid != 0x16)
0afe5f89 13544 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13545 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13546 else /* mono */
0afe5f89 13547 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13548 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13549 if (err < 0)
13550 return err;
13551 return 0;
13552}
13553
13554/* add playback controls from the parsed DAC table */
13555static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13556 const struct auto_pin_cfg *cfg)
13557{
13558 hda_nid_t nid;
13559 int err;
13560
a361d84b 13561 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13562
13563 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13564 if (nid) {
13565 const char *name;
13566 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13567 name = "Speaker";
13568 else
13569 name = "Front";
13570 err = alc268_new_analog_output(spec, nid, name, 0);
13571 if (err < 0)
13572 return err;
13573 }
a361d84b
KY
13574
13575 nid = cfg->speaker_pins[0];
13576 if (nid == 0x1d) {
0afe5f89 13577 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13578 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13579 if (err < 0)
13580 return err;
7bfb9c03 13581 } else if (nid) {
3f3b7c1a
TI
13582 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13583 if (err < 0)
13584 return err;
a361d84b
KY
13585 }
13586 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13587 if (nid) {
13588 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13589 if (err < 0)
13590 return err;
13591 }
a361d84b
KY
13592
13593 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13594 if (nid == 0x16) {
0afe5f89 13595 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13596 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13597 if (err < 0)
13598 return err;
13599 }
ea1fb29a 13600 return 0;
a361d84b
KY
13601}
13602
13603/* create playback/capture controls for input pins */
05f5f477 13604static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13605 const struct auto_pin_cfg *cfg)
13606{
05f5f477 13607 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13608}
13609
e9af4f36
TI
13610static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13611 hda_nid_t nid, int pin_type)
13612{
13613 int idx;
13614
13615 alc_set_pin_output(codec, nid, pin_type);
13616 if (nid == 0x14 || nid == 0x16)
13617 idx = 0;
13618 else
13619 idx = 1;
13620 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13621}
13622
13623static void alc268_auto_init_multi_out(struct hda_codec *codec)
13624{
13625 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13626 int i;
13627
13628 for (i = 0; i < spec->autocfg.line_outs; i++) {
13629 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13630 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13631 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13632 }
13633}
13634
13635static void alc268_auto_init_hp_out(struct hda_codec *codec)
13636{
13637 struct alc_spec *spec = codec->spec;
13638 hda_nid_t pin;
e1ca7b4e 13639 int i;
e9af4f36 13640
e1ca7b4e
TI
13641 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13642 pin = spec->autocfg.hp_pins[i];
e9af4f36 13643 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13644 }
13645 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13646 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13647 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13648 }
13649 if (spec->autocfg.mono_out_pin)
13650 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13651 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13652}
13653
a361d84b
KY
13654static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13655{
13656 struct alc_spec *spec = codec->spec;
13657 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13658 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13659 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13660 unsigned int dac_vol1, dac_vol2;
13661
e9af4f36 13662 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13663 snd_hda_codec_write(codec, speaker_nid, 0,
13664 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13665 /* mute mixer inputs from 0x1d */
a361d84b
KY
13666 snd_hda_codec_write(codec, 0x0f, 0,
13667 AC_VERB_SET_AMP_GAIN_MUTE,
13668 AMP_IN_UNMUTE(1));
13669 snd_hda_codec_write(codec, 0x10, 0,
13670 AC_VERB_SET_AMP_GAIN_MUTE,
13671 AMP_IN_UNMUTE(1));
13672 } else {
e9af4f36 13673 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13674 snd_hda_codec_write(codec, 0x0f, 0,
13675 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13676 snd_hda_codec_write(codec, 0x10, 0,
13677 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13678 }
13679
13680 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13681 if (line_nid == 0x14)
a361d84b
KY
13682 dac_vol2 = AMP_OUT_ZERO;
13683 else if (line_nid == 0x15)
13684 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13685 if (hp_nid == 0x14)
a361d84b
KY
13686 dac_vol2 = AMP_OUT_ZERO;
13687 else if (hp_nid == 0x15)
13688 dac_vol1 = AMP_OUT_ZERO;
13689 if (line_nid != 0x16 || hp_nid != 0x16 ||
13690 spec->autocfg.line_out_pins[1] != 0x16 ||
13691 spec->autocfg.line_out_pins[2] != 0x16)
13692 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13693
13694 snd_hda_codec_write(codec, 0x02, 0,
13695 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13696 snd_hda_codec_write(codec, 0x03, 0,
13697 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13698}
13699
def319f9 13700/* pcm configuration: identical with ALC880 */
a361d84b
KY
13701#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13702#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13703#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13704#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13705
13706/*
13707 * BIOS auto configuration
13708 */
13709static int alc268_parse_auto_config(struct hda_codec *codec)
13710{
13711 struct alc_spec *spec = codec->spec;
13712 int err;
13713 static hda_nid_t alc268_ignore[] = { 0 };
13714
13715 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13716 alc268_ignore);
13717 if (err < 0)
13718 return err;
7e0e44d4
TI
13719 if (!spec->autocfg.line_outs) {
13720 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13721 spec->multiout.max_channels = 2;
13722 spec->no_analog = 1;
13723 goto dig_only;
13724 }
a361d84b 13725 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13726 }
a361d84b
KY
13727 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13728 if (err < 0)
13729 return err;
05f5f477 13730 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13731 if (err < 0)
13732 return err;
13733
13734 spec->multiout.max_channels = 2;
13735
7e0e44d4 13736 dig_only:
a361d84b 13737 /* digital only support output */
757899ac 13738 alc_auto_parse_digital(codec);
603c4019 13739 if (spec->kctls.list)
d88897ea 13740 add_mixer(spec, spec->kctls.list);
a361d84b 13741
892981ff 13742 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13743 add_mixer(spec, alc268_beep_mixer);
aef9d318 13744
d88897ea 13745 add_verb(spec, alc268_volume_init_verbs);
5908589f 13746 spec->num_mux_defs = 2;
61b9b9b1 13747 spec->input_mux = &spec->private_imux[0];
a361d84b 13748
776e184e
TI
13749 err = alc_auto_add_mic_boost(codec);
13750 if (err < 0)
13751 return err;
13752
6227cdce 13753 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13754
a361d84b
KY
13755 return 1;
13756}
13757
a361d84b 13758#define alc268_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 13759#define alc268_auto_init_input_src alc882_auto_init_input_src
a361d84b
KY
13760
13761/* init callback for auto-configuration model -- overriding the default init */
13762static void alc268_auto_init(struct hda_codec *codec)
13763{
f6c7e546 13764 struct alc_spec *spec = codec->spec;
a361d84b
KY
13765 alc268_auto_init_multi_out(codec);
13766 alc268_auto_init_hp_out(codec);
13767 alc268_auto_init_mono_speaker_out(codec);
13768 alc268_auto_init_analog_input(codec);
ae0ebbf7 13769 alc268_auto_init_input_src(codec);
757899ac 13770 alc_auto_init_digital(codec);
f6c7e546 13771 if (spec->unsol_event)
7fb0d78f 13772 alc_inithook(codec);
a361d84b
KY
13773}
13774
13775/*
13776 * configuration and preset
13777 */
ea734963 13778static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13779 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13780 [ALC268_3ST] = "3stack",
983f8ae4 13781 [ALC268_TOSHIBA] = "toshiba",
d273809e 13782 [ALC268_ACER] = "acer",
c238b4f4 13783 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13784 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13785 [ALC268_DELL] = "dell",
f12462c5 13786 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13787#ifdef CONFIG_SND_DEBUG
13788 [ALC268_TEST] = "test",
13789#endif
a361d84b
KY
13790 [ALC268_AUTO] = "auto",
13791};
13792
13793static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13794 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13795 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13796 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13797 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13798 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13799 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13800 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13801 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13802 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13803 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13804 /* almost compatible with toshiba but with optional digital outs;
13805 * auto-probing seems working fine
13806 */
8871e5b9 13807 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13808 ALC268_AUTO),
a361d84b 13809 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13810 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13811 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13812 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13813 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13814 {}
13815};
13816
3abf2f36
TI
13817/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13818static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13819 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13820 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13821 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13822 ALC268_TOSHIBA),
13823 {}
13824};
13825
a361d84b 13826static struct alc_config_preset alc268_presets[] = {
eb5a6621 13827 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13828 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13829 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13830 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13831 alc267_quanta_il1_verbs },
13832 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13833 .dac_nids = alc268_dac_nids,
13834 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13835 .adc_nids = alc268_adc_nids_alt,
13836 .hp_nid = 0x03,
13837 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13838 .channel_mode = alc268_modes,
4f5d1706
TI
13839 .unsol_event = alc_sku_unsol_event,
13840 .setup = alc267_quanta_il1_setup,
13841 .init_hook = alc_inithook,
eb5a6621 13842 },
a361d84b 13843 [ALC268_3ST] = {
aef9d318
TI
13844 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13845 alc268_beep_mixer },
a361d84b
KY
13846 .init_verbs = { alc268_base_init_verbs },
13847 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13848 .dac_nids = alc268_dac_nids,
13849 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13850 .adc_nids = alc268_adc_nids_alt,
e1406348 13851 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13852 .hp_nid = 0x03,
13853 .dig_out_nid = ALC268_DIGOUT_NID,
13854 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13855 .channel_mode = alc268_modes,
13856 .input_mux = &alc268_capture_source,
13857 },
d1a991a6 13858 [ALC268_TOSHIBA] = {
42171c17 13859 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13860 alc268_beep_mixer },
d273809e
TI
13861 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13862 alc268_toshiba_verbs },
d1a991a6
KY
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,
d1a991a6
KY
13868 .hp_nid = 0x03,
13869 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13870 .channel_mode = alc268_modes,
13871 .input_mux = &alc268_capture_source,
e9427969 13872 .unsol_event = alc_sku_unsol_event,
4f5d1706 13873 .setup = alc268_toshiba_setup,
e9427969 13874 .init_hook = alc_inithook,
d273809e
TI
13875 },
13876 [ALC268_ACER] = {
432fd133 13877 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13878 alc268_beep_mixer },
d273809e
TI
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,
e1406348 13885 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13886 .hp_nid = 0x02,
13887 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13888 .channel_mode = alc268_modes,
0ccb541c 13889 .input_mux = &alc268_acer_capture_source,
0f0f391c
TI
13890 .unsol_event = alc_sku_unsol_event,
13891 .setup = alc268_acer_setup,
13892 .init_hook = alc_inithook,
d1a991a6 13893 },
c238b4f4
TI
13894 [ALC268_ACER_DMIC] = {
13895 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13896 alc268_beep_mixer },
13897 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13898 alc268_acer_verbs },
13899 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13900 .dac_nids = alc268_dac_nids,
13901 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13902 .adc_nids = alc268_adc_nids_alt,
13903 .capsrc_nids = alc268_capsrc_nids,
13904 .hp_nid = 0x02,
13905 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13906 .channel_mode = alc268_modes,
13907 .input_mux = &alc268_acer_dmic_capture_source,
0f0f391c
TI
13908 .unsol_event = alc_sku_unsol_event,
13909 .setup = alc268_acer_setup,
13910 .init_hook = alc_inithook,
c238b4f4 13911 },
8ef355da
KY
13912 [ALC268_ACER_ASPIRE_ONE] = {
13913 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13914 alc268_beep_mixer,
fdbc6626 13915 alc268_capture_nosrc_mixer },
8ef355da
KY
13916 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13917 alc268_acer_aspire_one_verbs },
13918 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13919 .dac_nids = alc268_dac_nids,
13920 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13921 .adc_nids = alc268_adc_nids_alt,
13922 .capsrc_nids = alc268_capsrc_nids,
13923 .hp_nid = 0x03,
13924 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13925 .channel_mode = alc268_modes,
3b8510ce 13926 .unsol_event = alc_sku_unsol_event,
4f5d1706 13927 .setup = alc268_acer_lc_setup,
3b8510ce 13928 .init_hook = alc_inithook,
8ef355da 13929 },
3866f0b0 13930 [ALC268_DELL] = {
fdbc6626
TI
13931 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13932 alc268_capture_nosrc_mixer },
3866f0b0
TI
13933 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13934 alc268_dell_verbs },
13935 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13936 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13937 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13938 .adc_nids = alc268_adc_nids_alt,
13939 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13940 .hp_nid = 0x02,
13941 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13942 .channel_mode = alc268_modes,
a9fd4f3f 13943 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13944 .setup = alc268_dell_setup,
13945 .init_hook = alc_inithook,
3866f0b0 13946 },
f12462c5 13947 [ALC268_ZEPTO] = {
aef9d318
TI
13948 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13949 alc268_beep_mixer },
f12462c5
MT
13950 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13951 alc268_toshiba_verbs },
13952 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13953 .dac_nids = alc268_dac_nids,
13954 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13955 .adc_nids = alc268_adc_nids_alt,
e1406348 13956 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13957 .hp_nid = 0x03,
13958 .dig_out_nid = ALC268_DIGOUT_NID,
13959 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13960 .channel_mode = alc268_modes,
13961 .input_mux = &alc268_capture_source,
e9427969 13962 .unsol_event = alc_sku_unsol_event,
4f5d1706 13963 .setup = alc268_toshiba_setup,
e9427969 13964 .init_hook = alc_inithook,
f12462c5 13965 },
86c53bd2
JW
13966#ifdef CONFIG_SND_DEBUG
13967 [ALC268_TEST] = {
13968 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13969 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13970 alc268_volume_init_verbs },
13971 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13972 .dac_nids = alc268_dac_nids,
13973 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13974 .adc_nids = alc268_adc_nids_alt,
e1406348 13975 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13976 .hp_nid = 0x03,
13977 .dig_out_nid = ALC268_DIGOUT_NID,
13978 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13979 .channel_mode = alc268_modes,
13980 .input_mux = &alc268_capture_source,
13981 },
13982#endif
a361d84b
KY
13983};
13984
13985static int patch_alc268(struct hda_codec *codec)
13986{
13987 struct alc_spec *spec;
13988 int board_config;
22971e3a 13989 int i, has_beep, err;
a361d84b 13990
ef86f581 13991 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13992 if (spec == NULL)
13993 return -ENOMEM;
13994
13995 codec->spec = spec;
13996
13997 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13998 alc268_models,
13999 alc268_cfg_tbl);
14000
3abf2f36
TI
14001 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14002 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 14003 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 14004
a361d84b 14005 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
14006 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14007 codec->chip_name);
a361d84b
KY
14008 board_config = ALC268_AUTO;
14009 }
14010
14011 if (board_config == ALC268_AUTO) {
14012 /* automatic parse from the BIOS config */
14013 err = alc268_parse_auto_config(codec);
14014 if (err < 0) {
14015 alc_free(codec);
14016 return err;
14017 } else if (!err) {
14018 printk(KERN_INFO
14019 "hda_codec: Cannot set up configuration "
14020 "from BIOS. Using base mode...\n");
14021 board_config = ALC268_3ST;
14022 }
14023 }
14024
14025 if (board_config != ALC268_AUTO)
e9c364c0 14026 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14027
a361d84b
KY
14028 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14029 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14030 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14031
a361d84b
KY
14032 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14033
22971e3a
TI
14034 has_beep = 0;
14035 for (i = 0; i < spec->num_mixers; i++) {
14036 if (spec->mixers[i] == alc268_beep_mixer) {
14037 has_beep = 1;
14038 break;
14039 }
14040 }
14041
14042 if (has_beep) {
14043 err = snd_hda_attach_beep_device(codec, 0x1);
14044 if (err < 0) {
14045 alc_free(codec);
14046 return err;
14047 }
14048 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14049 /* override the amp caps for beep generator */
14050 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14051 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14052 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14053 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14054 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14055 }
aef9d318 14056
7e0e44d4 14057 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14058 /* check whether NID 0x07 is valid */
14059 unsigned int wcap = get_wcaps(codec, 0x07);
14060
defb5ab2 14061 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14062 /* get type */
a22d543a 14063 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14064 if (spec->auto_mic ||
14065 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14066 spec->adc_nids = alc268_adc_nids_alt;
14067 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14068 if (spec->auto_mic)
14069 fixup_automic_adc(codec);
fdbc6626
TI
14070 if (spec->auto_mic || spec->input_mux->num_items == 1)
14071 add_mixer(spec, alc268_capture_nosrc_mixer);
14072 else
14073 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14074 } else {
14075 spec->adc_nids = alc268_adc_nids;
14076 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14077 add_mixer(spec, alc268_capture_mixer);
a361d84b
KY
14078 }
14079 }
2134ea4f
TI
14080
14081 spec->vmaster_nid = 0x02;
14082
a361d84b
KY
14083 codec->patch_ops = alc_patch_ops;
14084 if (board_config == ALC268_AUTO)
14085 spec->init_hook = alc268_auto_init;
1c716153 14086 spec->shutup = alc_eapd_shutup;
ea1fb29a 14087
bf1b0225
KY
14088 alc_init_jacks(codec);
14089
a361d84b
KY
14090 return 0;
14091}
14092
f6a92248
KY
14093/*
14094 * ALC269 channel source setting (2 channel)
14095 */
14096#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14097
14098#define alc269_dac_nids alc260_dac_nids
14099
14100static hda_nid_t alc269_adc_nids[1] = {
14101 /* ADC1 */
f53281e6
KY
14102 0x08,
14103};
14104
e01bf509
TI
14105static hda_nid_t alc269_capsrc_nids[1] = {
14106 0x23,
14107};
14108
84898e87
KY
14109static hda_nid_t alc269vb_adc_nids[1] = {
14110 /* ADC1 */
14111 0x09,
14112};
14113
14114static hda_nid_t alc269vb_capsrc_nids[1] = {
14115 0x22,
14116};
14117
6694635d 14118static hda_nid_t alc269_adc_candidates[] = {
262ac22d 14119 0x08, 0x09, 0x07, 0x11,
6694635d 14120};
e01bf509 14121
f6a92248
KY
14122#define alc269_modes alc260_modes
14123#define alc269_capture_source alc880_lg_lw_capture_source
14124
14125static struct snd_kcontrol_new alc269_base_mixer[] = {
14126 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14127 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14128 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14129 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14130 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14131 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14132 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14133 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14134 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14135 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14137 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14138 { } /* end */
14139};
14140
60db6b53
KY
14141static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14142 /* output mixer control */
14143 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14144 {
14145 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14146 .name = "Master Playback Switch",
5e26dfd0 14147 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14148 .info = snd_hda_mixer_amp_switch_info,
14149 .get = snd_hda_mixer_amp_switch_get,
14150 .put = alc268_acer_master_sw_put,
14151 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14152 },
14153 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14154 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14155 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14156 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14157 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14158 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14159 { }
14160};
14161
64154835
TV
14162static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14163 /* output mixer control */
14164 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14165 {
14166 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14167 .name = "Master Playback Switch",
5e26dfd0 14168 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14169 .info = snd_hda_mixer_amp_switch_info,
14170 .get = snd_hda_mixer_amp_switch_get,
14171 .put = alc268_acer_master_sw_put,
14172 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14173 },
14174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14175 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14176 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14177 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14178 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14179 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14180 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14181 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14182 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14183 { }
14184};
14185
84898e87 14186static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14187 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14188 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14189 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14190 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14191 { } /* end */
14192};
14193
84898e87
KY
14194static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14195 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14196 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14198 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14199 { } /* end */
14200};
14201
fe3eb0a7
KY
14202static struct snd_kcontrol_new alc269_asus_mixer[] = {
14203 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14204 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14205 { } /* end */
14206};
14207
f53281e6 14208/* capture mixer elements */
84898e87
KY
14209static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14210 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14211 HDA_CODEC_MUTE("Capture Switch", 0x08, 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
14217static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14218 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14219 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14220 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14221 { } /* end */
14222};
14223
84898e87
KY
14224static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14225 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14226 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14227 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14228 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14229 { } /* end */
14230};
14231
14232static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14233 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14234 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14235 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14236 { } /* end */
14237};
14238
26f5df26 14239/* FSC amilo */
84898e87 14240#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14241
60db6b53
KY
14242static struct hda_verb alc269_quanta_fl1_verbs[] = {
14243 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14244 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14245 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14246 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14247 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14248 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14249 { }
14250};
f6a92248 14251
64154835
TV
14252static struct hda_verb alc269_lifebook_verbs[] = {
14253 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14254 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14255 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14256 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14257 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14258 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14259 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14260 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14261 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14262 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14263 { }
14264};
14265
60db6b53
KY
14266/* toggle speaker-output according to the hp-jack state */
14267static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14268{
3b8510ce 14269 alc_hp_automute(codec);
f6a92248 14270
60db6b53
KY
14271 snd_hda_codec_write(codec, 0x20, 0,
14272 AC_VERB_SET_COEF_INDEX, 0x0c);
14273 snd_hda_codec_write(codec, 0x20, 0,
14274 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14275
60db6b53
KY
14276 snd_hda_codec_write(codec, 0x20, 0,
14277 AC_VERB_SET_COEF_INDEX, 0x0c);
14278 snd_hda_codec_write(codec, 0x20, 0,
14279 AC_VERB_SET_PROC_COEF, 0x480);
14280}
f6a92248 14281
3b8510ce
TI
14282#define alc269_lifebook_speaker_automute \
14283 alc269_quanta_fl1_speaker_automute
64154835 14284
64154835
TV
14285static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14286{
14287 unsigned int present_laptop;
14288 unsigned int present_dock;
14289
864f92be
WF
14290 present_laptop = snd_hda_jack_detect(codec, 0x18);
14291 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14292
14293 /* Laptop mic port overrides dock mic port, design decision */
14294 if (present_dock)
14295 snd_hda_codec_write(codec, 0x23, 0,
14296 AC_VERB_SET_CONNECT_SEL, 0x3);
14297 if (present_laptop)
14298 snd_hda_codec_write(codec, 0x23, 0,
14299 AC_VERB_SET_CONNECT_SEL, 0x0);
14300 if (!present_dock && !present_laptop)
14301 snd_hda_codec_write(codec, 0x23, 0,
14302 AC_VERB_SET_CONNECT_SEL, 0x1);
14303}
14304
60db6b53
KY
14305static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14306 unsigned int res)
14307{
4f5d1706
TI
14308 switch (res >> 26) {
14309 case ALC880_HP_EVENT:
60db6b53 14310 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14311 break;
14312 case ALC880_MIC_EVENT:
14313 alc_mic_automute(codec);
14314 break;
14315 }
60db6b53 14316}
f6a92248 14317
64154835
TV
14318static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14319 unsigned int res)
14320{
14321 if ((res >> 26) == ALC880_HP_EVENT)
14322 alc269_lifebook_speaker_automute(codec);
14323 if ((res >> 26) == ALC880_MIC_EVENT)
14324 alc269_lifebook_mic_autoswitch(codec);
14325}
14326
4f5d1706
TI
14327static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14328{
14329 struct alc_spec *spec = codec->spec;
20645d70
TI
14330 spec->autocfg.hp_pins[0] = 0x15;
14331 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14332 spec->automute_mixer_nid[0] = 0x0c;
14333 spec->automute = 1;
14334 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14335 spec->ext_mic.pin = 0x18;
14336 spec->ext_mic.mux_idx = 0;
14337 spec->int_mic.pin = 0x19;
14338 spec->int_mic.mux_idx = 1;
14339 spec->auto_mic = 1;
14340}
14341
60db6b53
KY
14342static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14343{
14344 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14345 alc_mic_automute(codec);
60db6b53 14346}
f6a92248 14347
3b8510ce
TI
14348static void alc269_lifebook_setup(struct hda_codec *codec)
14349{
14350 struct alc_spec *spec = codec->spec;
14351 spec->autocfg.hp_pins[0] = 0x15;
14352 spec->autocfg.hp_pins[1] = 0x1a;
14353 spec->autocfg.speaker_pins[0] = 0x14;
14354 spec->automute_mixer_nid[0] = 0x0c;
14355 spec->automute = 1;
14356 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14357}
14358
64154835
TV
14359static void alc269_lifebook_init_hook(struct hda_codec *codec)
14360{
14361 alc269_lifebook_speaker_automute(codec);
14362 alc269_lifebook_mic_autoswitch(codec);
14363}
14364
84898e87 14365static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14366 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14367 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14368 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14369 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14370 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14371 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14372 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14373 {}
14374};
14375
84898e87 14376static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14377 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14378 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14379 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14380 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14381 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14382 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14383 {}
14384};
14385
84898e87
KY
14386static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14387 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14388 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14389 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14390 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14391 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14392 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14393 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14394 {}
14395};
14396
14397static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14398 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14399 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14400 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14401 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14402 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14403 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14404 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14405 {}
14406};
14407
fe3eb0a7
KY
14408static struct hda_verb alc271_acer_dmic_verbs[] = {
14409 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14410 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14411 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14413 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14414 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14415 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14416 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14417 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14418 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14419 { }
14420};
14421
226b1ec8 14422static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14423{
4f5d1706 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;
4f5d1706
TI
14430 spec->ext_mic.pin = 0x18;
14431 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14432 spec->int_mic.pin = 0x19;
14433 spec->int_mic.mux_idx = 1;
4f5d1706 14434 spec->auto_mic = 1;
f53281e6
KY
14435}
14436
226b1ec8 14437static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14438{
14439 struct alc_spec *spec = codec->spec;
20645d70
TI
14440 spec->autocfg.hp_pins[0] = 0x15;
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;
84898e87
KY
14445 spec->ext_mic.pin = 0x18;
14446 spec->ext_mic.mux_idx = 0;
14447 spec->int_mic.pin = 0x12;
226b1ec8 14448 spec->int_mic.mux_idx = 5;
84898e87
KY
14449 spec->auto_mic = 1;
14450}
14451
226b1ec8 14452static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14453{
4f5d1706 14454 struct alc_spec *spec = codec->spec;
226b1ec8 14455 spec->autocfg.hp_pins[0] = 0x21;
20645d70 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;
4f5d1706
TI
14460 spec->ext_mic.pin = 0x18;
14461 spec->ext_mic.mux_idx = 0;
14462 spec->int_mic.pin = 0x19;
14463 spec->int_mic.mux_idx = 1;
14464 spec->auto_mic = 1;
f53281e6
KY
14465}
14466
226b1ec8
KY
14467static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14468{
14469 struct alc_spec *spec = codec->spec;
14470 spec->autocfg.hp_pins[0] = 0x21;
14471 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14472 spec->automute_mixer_nid[0] = 0x0c;
14473 spec->automute = 1;
14474 spec->automute_mode = ALC_AUTOMUTE_MIXER;
226b1ec8
KY
14475 spec->ext_mic.pin = 0x18;
14476 spec->ext_mic.mux_idx = 0;
14477 spec->int_mic.pin = 0x12;
14478 spec->int_mic.mux_idx = 6;
14479 spec->auto_mic = 1;
14480}
14481
60db6b53
KY
14482/*
14483 * generic initialization of ADC, input mixers and output mixers
14484 */
14485static struct hda_verb alc269_init_verbs[] = {
14486 /*
14487 * Unmute ADC0 and set the default input to mic-in
14488 */
84898e87 14489 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14490
14491 /*
84898e87 14492 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14493 */
14494 /* set vol=0 to output mixers */
14495 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14496 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14497
14498 /* set up input amps for analog loopback */
14499 /* Amp Indices: DAC = 0, mixer = 1 */
14500 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14502 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14503 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14504 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14505 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14506
14507 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14508 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14509 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14510 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14511 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14512 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14513 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14514
14515 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14516 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14517
84898e87
KY
14518 /* FIXME: use Mux-type input source selection */
14519 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14520 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14521 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14522
84898e87
KY
14523 /* set EAPD */
14524 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14525 { }
14526};
14527
14528static struct hda_verb alc269vb_init_verbs[] = {
14529 /*
14530 * Unmute ADC0 and set the default input to mic-in
14531 */
14532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14533
14534 /*
14535 * Set up output mixers (0x02 - 0x03)
14536 */
14537 /* set vol=0 to output mixers */
14538 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14539 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14540
14541 /* set up input amps for analog loopback */
14542 /* Amp Indices: DAC = 0, mixer = 1 */
14543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14546 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14547 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14548 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14549
14550 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14551 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14552 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14553 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14554 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14555 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14556 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14557
14558 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14559 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14560
14561 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14562 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14563 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14564 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14565
14566 /* set EAPD */
14567 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14568 { }
14569};
14570
9d0b71b1
TI
14571#define alc269_auto_create_multi_out_ctls \
14572 alc268_auto_create_multi_out_ctls
05f5f477
TI
14573#define alc269_auto_create_input_ctls \
14574 alc268_auto_create_input_ctls
f6a92248
KY
14575
14576#ifdef CONFIG_SND_HDA_POWER_SAVE
14577#define alc269_loopbacks alc880_loopbacks
14578#endif
14579
def319f9 14580/* pcm configuration: identical with ALC880 */
f6a92248
KY
14581#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14582#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14583#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14584#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14585
f03d3115
TI
14586static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14587 .substreams = 1,
14588 .channels_min = 2,
14589 .channels_max = 8,
14590 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14591 /* NID is set in alc_build_pcms */
14592 .ops = {
14593 .open = alc880_playback_pcm_open,
14594 .prepare = alc880_playback_pcm_prepare,
14595 .cleanup = alc880_playback_pcm_cleanup
14596 },
14597};
14598
14599static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14600 .substreams = 1,
14601 .channels_min = 2,
14602 .channels_max = 2,
14603 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14604 /* NID is set in alc_build_pcms */
14605};
14606
ad35879a
TI
14607#ifdef CONFIG_SND_HDA_POWER_SAVE
14608static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14609{
14610 switch (codec->subsystem_id) {
14611 case 0x103c1586:
14612 return 1;
14613 }
14614 return 0;
14615}
14616
14617static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14618{
14619 /* update mute-LED according to the speaker mute state */
14620 if (nid == 0x01 || nid == 0x14) {
14621 int pinval;
14622 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14623 HDA_AMP_MUTE)
14624 pinval = 0x24;
14625 else
14626 pinval = 0x20;
14627 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14628 snd_hda_codec_update_cache(codec, 0x19, 0,
14629 AC_VERB_SET_PIN_WIDGET_CONTROL,
14630 pinval);
ad35879a
TI
14631 }
14632 return alc_check_power_status(codec, nid);
14633}
14634#endif /* CONFIG_SND_HDA_POWER_SAVE */
14635
840b64c0
TI
14636static int alc275_setup_dual_adc(struct hda_codec *codec)
14637{
14638 struct alc_spec *spec = codec->spec;
14639
14640 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14641 return 0;
14642 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14643 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14644 if (spec->ext_mic.pin <= 0x12) {
14645 spec->private_adc_nids[0] = 0x08;
14646 spec->private_adc_nids[1] = 0x11;
14647 spec->private_capsrc_nids[0] = 0x23;
14648 spec->private_capsrc_nids[1] = 0x22;
14649 } else {
14650 spec->private_adc_nids[0] = 0x11;
14651 spec->private_adc_nids[1] = 0x08;
14652 spec->private_capsrc_nids[0] = 0x22;
14653 spec->private_capsrc_nids[1] = 0x23;
14654 }
14655 spec->adc_nids = spec->private_adc_nids;
14656 spec->capsrc_nids = spec->private_capsrc_nids;
14657 spec->num_adc_nids = 2;
14658 spec->dual_adc_switch = 1;
14659 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14660 spec->adc_nids[0], spec->adc_nids[1]);
14661 return 1;
14662 }
14663 return 0;
14664}
14665
d433a678
TI
14666/* different alc269-variants */
14667enum {
14668 ALC269_TYPE_NORMAL,
48c88e82 14669 ALC269_TYPE_ALC258,
d433a678 14670 ALC269_TYPE_ALC259,
48c88e82
KY
14671 ALC269_TYPE_ALC269VB,
14672 ALC269_TYPE_ALC270,
d433a678
TI
14673 ALC269_TYPE_ALC271X,
14674};
14675
f6a92248
KY
14676/*
14677 * BIOS auto configuration
14678 */
14679static int alc269_parse_auto_config(struct hda_codec *codec)
14680{
14681 struct alc_spec *spec = codec->spec;
cfb9fb55 14682 int err;
f6a92248
KY
14683 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14684
14685 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14686 alc269_ignore);
14687 if (err < 0)
14688 return err;
14689
14690 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14691 if (err < 0)
14692 return err;
f3550d1b
TI
14693 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14694 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14695 else
14696 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14697 0x22, 0);
f6a92248
KY
14698 if (err < 0)
14699 return err;
14700
14701 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14702
757899ac 14703 alc_auto_parse_digital(codec);
f6a92248 14704
603c4019 14705 if (spec->kctls.list)
d88897ea 14706 add_mixer(spec, spec->kctls.list);
f6a92248 14707
d433a678 14708 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14709 add_verb(spec, alc269vb_init_verbs);
6227cdce 14710 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14711 } else {
14712 add_verb(spec, alc269_init_verbs);
6227cdce 14713 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14714 }
14715
f6a92248 14716 spec->num_mux_defs = 1;
61b9b9b1 14717 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14718
14719 if (!alc275_setup_dual_adc(codec))
14720 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14721 sizeof(alc269_adc_candidates));
6694635d 14722
f6a92248
KY
14723 err = alc_auto_add_mic_boost(codec);
14724 if (err < 0)
14725 return err;
14726
7e0e44d4 14727 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14728 set_capture_mixer(codec);
f53281e6 14729
f6a92248
KY
14730 return 1;
14731}
14732
e9af4f36
TI
14733#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14734#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248 14735#define alc269_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 14736#define alc269_auto_init_input_src alc882_auto_init_input_src
f6a92248
KY
14737
14738
14739/* init callback for auto-configuration model -- overriding the default init */
14740static void alc269_auto_init(struct hda_codec *codec)
14741{
f6c7e546 14742 struct alc_spec *spec = codec->spec;
f6a92248
KY
14743 alc269_auto_init_multi_out(codec);
14744 alc269_auto_init_hp_out(codec);
14745 alc269_auto_init_analog_input(codec);
ae0ebbf7
TI
14746 if (!spec->dual_adc_switch)
14747 alc269_auto_init_input_src(codec);
757899ac 14748 alc_auto_init_digital(codec);
f6c7e546 14749 if (spec->unsol_event)
7fb0d78f 14750 alc_inithook(codec);
f6a92248
KY
14751}
14752
0ec33d1f
TI
14753static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14754{
14755 int val = alc_read_coef_idx(codec, 0x04);
14756 if (power_up)
14757 val |= 1 << 11;
14758 else
14759 val &= ~(1 << 11);
14760 alc_write_coef_idx(codec, 0x04, val);
14761}
14762
5402e4cb 14763static void alc269_shutup(struct hda_codec *codec)
977ddd6b 14764{
0ec33d1f
TI
14765 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14766 alc269_toggle_power_output(codec, 0);
977ddd6b 14767 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14768 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14769 msleep(150);
14770 }
977ddd6b 14771}
0ec33d1f 14772
5402e4cb 14773#ifdef SND_HDA_NEEDS_RESUME
977ddd6b
KY
14774static int alc269_resume(struct hda_codec *codec)
14775{
977ddd6b 14776 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14777 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14778 msleep(150);
14779 }
14780
14781 codec->patch_ops.init(codec);
14782
14783 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14784 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14785 msleep(200);
14786 }
14787
0ec33d1f
TI
14788 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14789 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14790
14791 snd_hda_codec_resume_amp(codec);
14792 snd_hda_codec_resume_cache(codec);
9e5341b9 14793 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14794 return 0;
14795}
0ec33d1f 14796#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14797
1a99d4a4 14798static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14799 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14800{
14801 int coef;
14802
58701120 14803 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14804 return;
1a99d4a4
KY
14805 coef = alc_read_coef_idx(codec, 0x1e);
14806 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14807}
14808
6981d184
TI
14809static void alc271_fixup_dmic(struct hda_codec *codec,
14810 const struct alc_fixup *fix, int action)
14811{
14812 static struct hda_verb verbs[] = {
14813 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14814 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14815 {}
14816 };
14817 unsigned int cfg;
14818
14819 if (strcmp(codec->chip_name, "ALC271X"))
14820 return;
14821 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14822 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14823 snd_hda_sequence_write(codec, verbs);
14824}
14825
ff818c24
TI
14826enum {
14827 ALC269_FIXUP_SONY_VAIO,
74dc8909 14828 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14829 ALC269_FIXUP_DELL_M101Z,
022c92be 14830 ALC269_FIXUP_SKU_IGNORE,
ac612407 14831 ALC269_FIXUP_ASUS_G73JW,
357f915e 14832 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14833 ALC275_FIXUP_SONY_HWEQ,
6981d184 14834 ALC271_FIXUP_DMIC,
ff818c24
TI
14835};
14836
ff818c24
TI
14837static const struct alc_fixup alc269_fixups[] = {
14838 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14839 .type = ALC_FIXUP_VERBS,
14840 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14841 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14842 {}
14843 }
ff818c24 14844 },
74dc8909 14845 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14846 .type = ALC_FIXUP_VERBS,
14847 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14848 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14849 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14850 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14851 { }
b5bfbc67
TI
14852 },
14853 .chained = true,
14854 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14855 },
145a902b 14856 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14857 .type = ALC_FIXUP_VERBS,
14858 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14859 /* Enables internal speaker */
14860 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14861 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14862 {}
14863 }
14864 },
022c92be 14865 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14866 .type = ALC_FIXUP_SKU,
14867 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14868 },
ac612407 14869 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14870 .type = ALC_FIXUP_PINS,
14871 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14872 { 0x17, 0x99130111 }, /* subwoofer */
14873 { }
14874 }
14875 },
357f915e 14876 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14877 .type = ALC_FIXUP_VERBS,
14878 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14879 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14880 {}
14881 }
14882 },
1a99d4a4 14883 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14884 .type = ALC_FIXUP_FUNC,
14885 .v.func = alc269_fixup_hweq,
14886 .chained = true,
14887 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6981d184
TI
14888 },
14889 [ALC271_FIXUP_DMIC] = {
14890 .type = ALC_FIXUP_FUNC,
14891 .v.func = alc271_fixup_dmic,
14892 },
ff818c24
TI
14893};
14894
14895static struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14896 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14897 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14898 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14899 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14900 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6981d184 14901 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
022c92be 14902 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14903 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14904 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14905 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14906 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14907 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14908 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14909 {}
14910};
14911
14912
f6a92248
KY
14913/*
14914 * configuration and preset
14915 */
ea734963 14916static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14917 [ALC269_BASIC] = "basic",
2922c9af 14918 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14919 [ALC269_AMIC] = "laptop-amic",
14920 [ALC269_DMIC] = "laptop-dmic",
64154835 14921 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14922 [ALC269_LIFEBOOK] = "lifebook",
14923 [ALC269_AUTO] = "auto",
f6a92248
KY
14924};
14925
14926static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14927 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14928 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14929 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14930 ALC269_AMIC),
14931 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14932 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14933 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14934 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14935 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14936 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14937 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14938 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14939 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14940 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14941 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14942 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14943 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14944 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14945 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14946 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14947 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14948 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14949 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14950 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14951 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14952 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14953 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14954 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14955 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14956 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14957 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14958 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14959 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14960 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14961 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14962 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14963 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14964 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14965 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14966 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14967 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14968 ALC269_DMIC),
60db6b53 14969 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14970 ALC269_DMIC),
14971 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14972 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14973 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14974 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14975 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14976 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14977 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14978 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14979 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14980 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14981 {}
14982};
14983
14984static struct alc_config_preset alc269_presets[] = {
14985 [ALC269_BASIC] = {
f9e336f6 14986 .mixers = { alc269_base_mixer },
f6a92248
KY
14987 .init_verbs = { alc269_init_verbs },
14988 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14989 .dac_nids = alc269_dac_nids,
14990 .hp_nid = 0x03,
14991 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14992 .channel_mode = alc269_modes,
14993 .input_mux = &alc269_capture_source,
14994 },
60db6b53
KY
14995 [ALC269_QUANTA_FL1] = {
14996 .mixers = { alc269_quanta_fl1_mixer },
14997 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14998 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14999 .dac_nids = alc269_dac_nids,
15000 .hp_nid = 0x03,
15001 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15002 .channel_mode = alc269_modes,
15003 .input_mux = &alc269_capture_source,
15004 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15005 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15006 .init_hook = alc269_quanta_fl1_init_hook,
15007 },
84898e87
KY
15008 [ALC269_AMIC] = {
15009 .mixers = { alc269_laptop_mixer },
15010 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15011 .init_verbs = { alc269_init_verbs,
84898e87 15012 alc269_laptop_amic_init_verbs },
f53281e6
KY
15013 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15014 .dac_nids = alc269_dac_nids,
15015 .hp_nid = 0x03,
15016 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15017 .channel_mode = alc269_modes,
3b8510ce 15018 .unsol_event = alc_sku_unsol_event,
84898e87 15019 .setup = alc269_laptop_amic_setup,
3b8510ce 15020 .init_hook = alc_inithook,
f53281e6 15021 },
84898e87
KY
15022 [ALC269_DMIC] = {
15023 .mixers = { alc269_laptop_mixer },
15024 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15025 .init_verbs = { alc269_init_verbs,
84898e87
KY
15026 alc269_laptop_dmic_init_verbs },
15027 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15028 .dac_nids = alc269_dac_nids,
15029 .hp_nid = 0x03,
15030 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15031 .channel_mode = alc269_modes,
3b8510ce 15032 .unsol_event = alc_sku_unsol_event,
84898e87 15033 .setup = alc269_laptop_dmic_setup,
3b8510ce 15034 .init_hook = alc_inithook,
84898e87
KY
15035 },
15036 [ALC269VB_AMIC] = {
15037 .mixers = { alc269vb_laptop_mixer },
15038 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15039 .init_verbs = { alc269vb_init_verbs,
15040 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15041 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15042 .dac_nids = alc269_dac_nids,
15043 .hp_nid = 0x03,
15044 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15045 .channel_mode = alc269_modes,
3b8510ce 15046 .unsol_event = alc_sku_unsol_event,
226b1ec8 15047 .setup = alc269vb_laptop_amic_setup,
3b8510ce 15048 .init_hook = alc_inithook,
84898e87
KY
15049 },
15050 [ALC269VB_DMIC] = {
15051 .mixers = { alc269vb_laptop_mixer },
15052 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15053 .init_verbs = { alc269vb_init_verbs,
15054 alc269vb_laptop_dmic_init_verbs },
15055 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15056 .dac_nids = alc269_dac_nids,
15057 .hp_nid = 0x03,
15058 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15059 .channel_mode = alc269_modes,
3b8510ce 15060 .unsol_event = alc_sku_unsol_event,
84898e87 15061 .setup = alc269vb_laptop_dmic_setup,
3b8510ce 15062 .init_hook = alc_inithook,
f53281e6 15063 },
26f5df26 15064 [ALC269_FUJITSU] = {
45bdd1c1 15065 .mixers = { alc269_fujitsu_mixer },
84898e87 15066 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15067 .init_verbs = { alc269_init_verbs,
84898e87 15068 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15069 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15070 .dac_nids = alc269_dac_nids,
15071 .hp_nid = 0x03,
15072 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15073 .channel_mode = alc269_modes,
3b8510ce 15074 .unsol_event = alc_sku_unsol_event,
84898e87 15075 .setup = alc269_laptop_dmic_setup,
3b8510ce 15076 .init_hook = alc_inithook,
26f5df26 15077 },
64154835
TV
15078 [ALC269_LIFEBOOK] = {
15079 .mixers = { alc269_lifebook_mixer },
15080 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15081 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15082 .dac_nids = alc269_dac_nids,
15083 .hp_nid = 0x03,
15084 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15085 .channel_mode = alc269_modes,
15086 .input_mux = &alc269_capture_source,
15087 .unsol_event = alc269_lifebook_unsol_event,
3b8510ce 15088 .setup = alc269_lifebook_setup,
64154835
TV
15089 .init_hook = alc269_lifebook_init_hook,
15090 },
fe3eb0a7
KY
15091 [ALC271_ACER] = {
15092 .mixers = { alc269_asus_mixer },
15093 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15094 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15095 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15096 .dac_nids = alc269_dac_nids,
15097 .adc_nids = alc262_dmic_adc_nids,
15098 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15099 .capsrc_nids = alc262_dmic_capsrc_nids,
15100 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15101 .channel_mode = alc269_modes,
15102 .input_mux = &alc269_capture_source,
15103 .dig_out_nid = ALC880_DIGOUT_NID,
15104 .unsol_event = alc_sku_unsol_event,
15105 .setup = alc269vb_laptop_dmic_setup,
15106 .init_hook = alc_inithook,
15107 },
f6a92248
KY
15108};
15109
977ddd6b
KY
15110static int alc269_fill_coef(struct hda_codec *codec)
15111{
15112 int val;
15113
15114 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15115 alc_write_coef_idx(codec, 0xf, 0x960b);
15116 alc_write_coef_idx(codec, 0xe, 0x8817);
15117 }
15118
15119 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15120 alc_write_coef_idx(codec, 0xf, 0x960b);
15121 alc_write_coef_idx(codec, 0xe, 0x8814);
15122 }
15123
15124 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15125 val = alc_read_coef_idx(codec, 0x04);
15126 /* Power up output pin */
15127 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15128 }
15129
15130 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15131 val = alc_read_coef_idx(codec, 0xd);
15132 if ((val & 0x0c00) >> 10 != 0x1) {
15133 /* Capless ramp up clock control */
15134 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15135 }
15136 val = alc_read_coef_idx(codec, 0x17);
15137 if ((val & 0x01c0) >> 6 != 0x4) {
15138 /* Class D power on reset */
15139 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15140 }
15141 }
15142 return 0;
15143}
15144
f6a92248
KY
15145static int patch_alc269(struct hda_codec *codec)
15146{
15147 struct alc_spec *spec;
48c88e82 15148 int board_config, coef;
f6a92248
KY
15149 int err;
15150
15151 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15152 if (spec == NULL)
15153 return -ENOMEM;
15154
15155 codec->spec = spec;
15156
da00c244
KY
15157 alc_auto_parse_customize_define(codec);
15158
c793bec5
KY
15159 if (codec->vendor_id == 0x10ec0269) {
15160 coef = alc_read_coef_idx(codec, 0);
15161 if ((coef & 0x00f0) == 0x0010) {
15162 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15163 spec->cdefine.platform_type == 1) {
15164 alc_codec_rename(codec, "ALC271X");
15165 spec->codec_variant = ALC269_TYPE_ALC271X;
15166 } else if ((coef & 0xf000) == 0x1000) {
15167 spec->codec_variant = ALC269_TYPE_ALC270;
15168 } else if ((coef & 0xf000) == 0x2000) {
15169 alc_codec_rename(codec, "ALC259");
15170 spec->codec_variant = ALC269_TYPE_ALC259;
15171 } else if ((coef & 0xf000) == 0x3000) {
15172 alc_codec_rename(codec, "ALC258");
15173 spec->codec_variant = ALC269_TYPE_ALC258;
15174 } else {
15175 alc_codec_rename(codec, "ALC269VB");
15176 spec->codec_variant = ALC269_TYPE_ALC269VB;
15177 }
15178 } else
15179 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15180 alc269_fill_coef(codec);
15181 }
977ddd6b 15182
f6a92248
KY
15183 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15184 alc269_models,
15185 alc269_cfg_tbl);
15186
15187 if (board_config < 0) {
9a11f1aa
TI
15188 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15189 codec->chip_name);
f6a92248
KY
15190 board_config = ALC269_AUTO;
15191 }
15192
b5bfbc67
TI
15193 if (board_config == ALC269_AUTO) {
15194 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15195 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15196 }
ff818c24 15197
f6a92248
KY
15198 if (board_config == ALC269_AUTO) {
15199 /* automatic parse from the BIOS config */
15200 err = alc269_parse_auto_config(codec);
15201 if (err < 0) {
15202 alc_free(codec);
15203 return err;
15204 } else if (!err) {
15205 printk(KERN_INFO
15206 "hda_codec: Cannot set up configuration "
15207 "from BIOS. Using base mode...\n");
15208 board_config = ALC269_BASIC;
15209 }
15210 }
15211
dc1eae25 15212 if (has_cdefine_beep(codec)) {
8af2591d
TI
15213 err = snd_hda_attach_beep_device(codec, 0x1);
15214 if (err < 0) {
15215 alc_free(codec);
15216 return err;
15217 }
680cd536
KK
15218 }
15219
f6a92248 15220 if (board_config != ALC269_AUTO)
e9c364c0 15221 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15222
84898e87 15223 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15224 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15225 * fix the sample rate of analog I/O to 44.1kHz
15226 */
15227 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15228 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15229 } else if (spec->dual_adc_switch) {
15230 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15231 /* switch ADC dynamically */
15232 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15233 } else {
15234 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15235 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15236 }
f6a92248
KY
15237 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15238 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15239
6694635d 15240 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15241 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15242 spec->adc_nids = alc269_adc_nids;
15243 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15244 spec->capsrc_nids = alc269_capsrc_nids;
15245 } else {
15246 spec->adc_nids = alc269vb_adc_nids;
15247 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15248 spec->capsrc_nids = alc269vb_capsrc_nids;
15249 }
84898e87
KY
15250 }
15251
f9e336f6 15252 if (!spec->cap_mixer)
b59bdf3b 15253 set_capture_mixer(codec);
dc1eae25 15254 if (has_cdefine_beep(codec))
da00c244 15255 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15256
b5bfbc67 15257 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15258
100d5eb3
TI
15259 spec->vmaster_nid = 0x02;
15260
f6a92248 15261 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15262#ifdef SND_HDA_NEEDS_RESUME
15263 codec->patch_ops.resume = alc269_resume;
15264#endif
f6a92248
KY
15265 if (board_config == ALC269_AUTO)
15266 spec->init_hook = alc269_auto_init;
5402e4cb 15267 spec->shutup = alc269_shutup;
bf1b0225
KY
15268
15269 alc_init_jacks(codec);
f6a92248
KY
15270#ifdef CONFIG_SND_HDA_POWER_SAVE
15271 if (!spec->loopback.amplist)
15272 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15273 if (alc269_mic2_for_mute_led(codec))
15274 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15275#endif
15276
15277 return 0;
15278}
15279
df694daa
KY
15280/*
15281 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15282 */
15283
15284/*
15285 * set the path ways for 2 channel output
15286 * need to set the codec line out and mic 1 pin widgets to inputs
15287 */
15288static struct hda_verb alc861_threestack_ch2_init[] = {
15289 /* set pin widget 1Ah (line in) for input */
15290 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15291 /* set pin widget 18h (mic1/2) for input, for mic also enable
15292 * the vref
15293 */
df694daa
KY
15294 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15295
9c7f852e
TI
15296 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15297#if 0
15298 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15299 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15300#endif
df694daa
KY
15301 { } /* end */
15302};
15303/*
15304 * 6ch mode
15305 * need to set the codec line out and mic 1 pin widgets to outputs
15306 */
15307static struct hda_verb alc861_threestack_ch6_init[] = {
15308 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15309 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15310 /* set pin widget 18h (mic1) for output (CLFE)*/
15311 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15312
15313 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15314 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15315
9c7f852e
TI
15316 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15317#if 0
15318 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15319 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15320#endif
df694daa
KY
15321 { } /* end */
15322};
15323
15324static struct hda_channel_mode alc861_threestack_modes[2] = {
15325 { 2, alc861_threestack_ch2_init },
15326 { 6, alc861_threestack_ch6_init },
15327};
22309c3e
TI
15328/* Set mic1 as input and unmute the mixer */
15329static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15330 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15331 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15332 { } /* end */
15333};
15334/* Set mic1 as output and mute mixer */
15335static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15336 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15337 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15338 { } /* end */
15339};
15340
15341static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15342 { 2, alc861_uniwill_m31_ch2_init },
15343 { 4, alc861_uniwill_m31_ch4_init },
15344};
df694daa 15345
7cdbff94
MD
15346/* Set mic1 and line-in as input and unmute the mixer */
15347static struct hda_verb alc861_asus_ch2_init[] = {
15348 /* set pin widget 1Ah (line in) for input */
15349 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15350 /* set pin widget 18h (mic1/2) for input, for mic also enable
15351 * the vref
15352 */
7cdbff94
MD
15353 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15354
15355 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15356#if 0
15357 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15358 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15359#endif
15360 { } /* end */
15361};
15362/* Set mic1 nad line-in as output and mute mixer */
15363static struct hda_verb alc861_asus_ch6_init[] = {
15364 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15365 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15366 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15367 /* set pin widget 18h (mic1) for output (CLFE)*/
15368 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15369 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15370 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15371 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15372
15373 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15374#if 0
15375 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15376 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15377#endif
15378 { } /* end */
15379};
15380
15381static struct hda_channel_mode alc861_asus_modes[2] = {
15382 { 2, alc861_asus_ch2_init },
15383 { 6, alc861_asus_ch6_init },
15384};
15385
df694daa
KY
15386/* patch-ALC861 */
15387
15388static struct snd_kcontrol_new alc861_base_mixer[] = {
15389 /* output mixer control */
15390 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15391 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15392 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15393 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15394 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15395
15396 /*Input mixer control */
15397 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15398 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15399 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15400 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15401 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15402 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15404 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15405 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15406 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15407
df694daa
KY
15408 { } /* end */
15409};
15410
15411static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15412 /* output mixer control */
15413 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15414 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15415 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15416 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15417 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15418
15419 /* Input mixer control */
15420 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15421 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15422 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15423 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15424 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15425 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15427 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15428 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15430
df694daa
KY
15431 {
15432 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15433 .name = "Channel Mode",
15434 .info = alc_ch_mode_info,
15435 .get = alc_ch_mode_get,
15436 .put = alc_ch_mode_put,
15437 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15438 },
15439 { } /* end */
a53d1aec
TD
15440};
15441
d1d985f0 15442static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15443 /* output mixer control */
15444 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15446 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15447
a53d1aec 15448 { } /* end */
f12ab1e0 15449};
a53d1aec 15450
22309c3e
TI
15451static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15452 /* output mixer control */
15453 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15454 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15455 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15456 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15457 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15458
15459 /* Input mixer control */
15460 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15462 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15463 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15464 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15465 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15467 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15468 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15469 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15470
22309c3e
TI
15471 {
15472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15473 .name = "Channel Mode",
15474 .info = alc_ch_mode_info,
15475 .get = alc_ch_mode_get,
15476 .put = alc_ch_mode_put,
15477 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15478 },
15479 { } /* end */
f12ab1e0 15480};
7cdbff94
MD
15481
15482static struct snd_kcontrol_new alc861_asus_mixer[] = {
15483 /* output mixer control */
15484 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15485 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15486 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15487 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15488 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15489
15490 /* Input mixer control */
15491 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15492 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15493 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15494 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15495 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15496 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15497 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15498 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15499 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15500 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15501
7cdbff94
MD
15502 {
15503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15504 .name = "Channel Mode",
15505 .info = alc_ch_mode_info,
15506 .get = alc_ch_mode_get,
15507 .put = alc_ch_mode_put,
15508 .private_value = ARRAY_SIZE(alc861_asus_modes),
15509 },
15510 { }
56bb0cab
TI
15511};
15512
15513/* additional mixer */
d1d985f0 15514static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15515 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15516 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15517 { }
15518};
7cdbff94 15519
df694daa
KY
15520/*
15521 * generic initialization of ADC, input mixers and output mixers
15522 */
15523static struct hda_verb alc861_base_init_verbs[] = {
15524 /*
15525 * Unmute ADC0 and set the default input to mic-in
15526 */
15527 /* port-A for surround (rear panel) */
15528 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15529 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15530 /* port-B for mic-in (rear panel) with vref */
15531 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15532 /* port-C for line-in (rear panel) */
15533 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15534 /* port-D for Front */
15535 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15536 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15537 /* port-E for HP out (front panel) */
15538 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15539 /* route front PCM to HP */
9dece1d7 15540 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15541 /* port-F for mic-in (front panel) with vref */
15542 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15543 /* port-G for CLFE (rear panel) */
15544 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15545 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15546 /* port-H for side (rear panel) */
15547 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15548 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15549 /* CD-in */
15550 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15551 /* route front mic to ADC1*/
15552 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15553 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15554
df694daa
KY
15555 /* Unmute DAC0~3 & spdif out*/
15556 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15557 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15558 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15559 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15560 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15561
df694daa
KY
15562 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15563 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15564 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15565 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15566 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15567
df694daa
KY
15568 /* Unmute Stereo Mixer 15 */
15569 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15570 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15571 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15572 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15573
15574 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15575 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15576 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15578 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15579 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15580 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15581 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15582 /* hp used DAC 3 (Front) */
15583 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15585
15586 { }
15587};
15588
15589static struct hda_verb alc861_threestack_init_verbs[] = {
15590 /*
15591 * Unmute ADC0 and set the default input to mic-in
15592 */
15593 /* port-A for surround (rear panel) */
15594 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15595 /* port-B for mic-in (rear panel) with vref */
15596 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15597 /* port-C for line-in (rear panel) */
15598 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15599 /* port-D for Front */
15600 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15601 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15602 /* port-E for HP out (front panel) */
15603 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15604 /* route front PCM to HP */
9dece1d7 15605 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15606 /* port-F for mic-in (front panel) with vref */
15607 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15608 /* port-G for CLFE (rear panel) */
15609 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15610 /* port-H for side (rear panel) */
15611 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15612 /* CD-in */
15613 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15614 /* route front mic to ADC1*/
15615 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15616 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15617 /* Unmute DAC0~3 & spdif out*/
15618 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15619 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15620 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15621 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15623
df694daa
KY
15624 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15625 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15626 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15627 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15628 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15629
df694daa
KY
15630 /* Unmute Stereo Mixer 15 */
15631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15635
15636 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15637 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15638 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15639 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15640 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15641 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15642 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15643 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15644 /* hp used DAC 3 (Front) */
15645 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15647 { }
15648};
22309c3e
TI
15649
15650static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15651 /*
15652 * Unmute ADC0 and set the default input to mic-in
15653 */
15654 /* port-A for surround (rear panel) */
15655 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15656 /* port-B for mic-in (rear panel) with vref */
15657 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15658 /* port-C for line-in (rear panel) */
15659 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15660 /* port-D for Front */
15661 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15662 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15663 /* port-E for HP out (front panel) */
f12ab1e0
TI
15664 /* this has to be set to VREF80 */
15665 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15666 /* route front PCM to HP */
9dece1d7 15667 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15668 /* port-F for mic-in (front panel) with vref */
15669 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15670 /* port-G for CLFE (rear panel) */
15671 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15672 /* port-H for side (rear panel) */
15673 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15674 /* CD-in */
15675 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15676 /* route front mic to ADC1*/
15677 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15678 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15679 /* Unmute DAC0~3 & spdif out*/
15680 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15681 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15682 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15683 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15685
22309c3e
TI
15686 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15687 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15688 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15689 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15690 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15691
22309c3e
TI
15692 /* Unmute Stereo Mixer 15 */
15693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15695 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15696 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15697
15698 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15699 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15700 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15701 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15702 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15703 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15705 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15706 /* hp used DAC 3 (Front) */
15707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15708 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15709 { }
15710};
15711
7cdbff94
MD
15712static struct hda_verb alc861_asus_init_verbs[] = {
15713 /*
15714 * Unmute ADC0 and set the default input to mic-in
15715 */
f12ab1e0
TI
15716 /* port-A for surround (rear panel)
15717 * according to codec#0 this is the HP jack
15718 */
7cdbff94
MD
15719 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15720 /* route front PCM to HP */
15721 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15722 /* port-B for mic-in (rear panel) with vref */
15723 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15724 /* port-C for line-in (rear panel) */
15725 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15726 /* port-D for Front */
15727 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15728 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15729 /* port-E for HP out (front panel) */
f12ab1e0
TI
15730 /* this has to be set to VREF80 */
15731 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15732 /* route front PCM to HP */
9dece1d7 15733 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15734 /* port-F for mic-in (front panel) with vref */
15735 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15736 /* port-G for CLFE (rear panel) */
15737 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15738 /* port-H for side (rear panel) */
15739 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15740 /* CD-in */
15741 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15742 /* route front mic to ADC1*/
15743 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15744 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15745 /* Unmute DAC0~3 & spdif out*/
15746 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15747 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15748 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15749 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15750 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15751 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15752 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15753 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15754 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15755 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15756
7cdbff94
MD
15757 /* Unmute Stereo Mixer 15 */
15758 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15759 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15760 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15761 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15762
15763 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15764 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15765 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15766 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15767 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15768 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15769 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15770 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15771 /* hp used DAC 3 (Front) */
15772 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15773 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15774 { }
15775};
15776
56bb0cab
TI
15777/* additional init verbs for ASUS laptops */
15778static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15779 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15780 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15781 { }
15782};
7cdbff94 15783
df694daa
KY
15784/*
15785 * generic initialization of ADC, input mixers and output mixers
15786 */
15787static struct hda_verb alc861_auto_init_verbs[] = {
15788 /*
15789 * Unmute ADC0 and set the default input to mic-in
15790 */
f12ab1e0 15791 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15792 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15793
df694daa
KY
15794 /* Unmute DAC0~3 & spdif out*/
15795 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15796 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15797 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15798 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15799 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15800
df694daa
KY
15801 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15802 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15803 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15804 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15805 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15806
df694daa
KY
15807 /* Unmute Stereo Mixer 15 */
15808 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15809 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15810 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15812
1c20930a
TI
15813 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15814 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15815 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15816 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15817 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15818 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15819 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15820 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15821
15822 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15823 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15824 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15825 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15826 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15827 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15828 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15829 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15830
f12ab1e0 15831 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15832
15833 { }
15834};
15835
a53d1aec
TD
15836static struct hda_verb alc861_toshiba_init_verbs[] = {
15837 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15838
a53d1aec
TD
15839 { }
15840};
15841
15842/* toggle speaker-output according to the hp-jack state */
15843static void alc861_toshiba_automute(struct hda_codec *codec)
15844{
864f92be 15845 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15846
47fd830a
TI
15847 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15848 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15849 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15850 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15851}
15852
15853static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15854 unsigned int res)
15855{
a53d1aec
TD
15856 if ((res >> 26) == ALC880_HP_EVENT)
15857 alc861_toshiba_automute(codec);
15858}
15859
def319f9 15860/* pcm configuration: identical with ALC880 */
df694daa
KY
15861#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15862#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15863#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15864#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15865
15866
15867#define ALC861_DIGOUT_NID 0x07
15868
15869static struct hda_channel_mode alc861_8ch_modes[1] = {
15870 { 8, NULL }
15871};
15872
15873static hda_nid_t alc861_dac_nids[4] = {
15874 /* front, surround, clfe, side */
15875 0x03, 0x06, 0x05, 0x04
15876};
15877
9c7f852e
TI
15878static hda_nid_t alc660_dac_nids[3] = {
15879 /* front, clfe, surround */
15880 0x03, 0x05, 0x06
15881};
15882
df694daa
KY
15883static hda_nid_t alc861_adc_nids[1] = {
15884 /* ADC0-2 */
15885 0x08,
15886};
15887
15888static struct hda_input_mux alc861_capture_source = {
15889 .num_items = 5,
15890 .items = {
15891 { "Mic", 0x0 },
15892 { "Front Mic", 0x3 },
15893 { "Line", 0x1 },
15894 { "CD", 0x4 },
15895 { "Mixer", 0x5 },
15896 },
15897};
15898
1c20930a
TI
15899static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15900{
15901 struct alc_spec *spec = codec->spec;
15902 hda_nid_t mix, srcs[5];
15903 int i, j, num;
15904
15905 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15906 return 0;
15907 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15908 if (num < 0)
15909 return 0;
15910 for (i = 0; i < num; i++) {
15911 unsigned int type;
a22d543a 15912 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15913 if (type != AC_WID_AUD_OUT)
15914 continue;
15915 for (j = 0; j < spec->multiout.num_dacs; j++)
15916 if (spec->multiout.dac_nids[j] == srcs[i])
15917 break;
15918 if (j >= spec->multiout.num_dacs)
15919 return srcs[i];
15920 }
15921 return 0;
15922}
15923
df694daa 15924/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15925static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15926 const struct auto_pin_cfg *cfg)
df694daa 15927{
1c20930a 15928 struct alc_spec *spec = codec->spec;
df694daa 15929 int i;
1c20930a 15930 hda_nid_t nid, dac;
df694daa
KY
15931
15932 spec->multiout.dac_nids = spec->private_dac_nids;
15933 for (i = 0; i < cfg->line_outs; i++) {
15934 nid = cfg->line_out_pins[i];
1c20930a
TI
15935 dac = alc861_look_for_dac(codec, nid);
15936 if (!dac)
15937 continue;
15938 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15939 }
df694daa
KY
15940 return 0;
15941}
15942
bcb2f0f5
TI
15943static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15944 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15945{
bcb2f0f5 15946 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15947 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15948}
15949
bcb2f0f5
TI
15950#define alc861_create_out_sw(codec, pfx, nid, chs) \
15951 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15952
df694daa 15953/* add playback controls from the parsed DAC table */
1c20930a 15954static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15955 const struct auto_pin_cfg *cfg)
15956{
1c20930a 15957 struct alc_spec *spec = codec->spec;
ea734963 15958 static const char * const chname[4] = {
f12ab1e0
TI
15959 "Front", "Surround", NULL /*CLFE*/, "Side"
15960 };
ce764ab2 15961 const char *pfx = alc_get_line_out_pfx(spec, true);
df694daa 15962 hda_nid_t nid;
ce764ab2 15963 int i, err, noutputs;
1c20930a 15964
ce764ab2
TI
15965 noutputs = cfg->line_outs;
15966 if (spec->multi_ios > 0)
15967 noutputs += spec->multi_ios;
15968
15969 for (i = 0; i < noutputs; i++) {
df694daa 15970 nid = spec->multiout.dac_nids[i];
f12ab1e0 15971 if (!nid)
df694daa 15972 continue;
bcb2f0f5 15973 if (!pfx && i == 2) {
df694daa 15974 /* Center/LFE */
1c20930a 15975 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15976 if (err < 0)
df694daa 15977 return err;
1c20930a 15978 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15979 if (err < 0)
df694daa
KY
15980 return err;
15981 } else {
bcb2f0f5 15982 const char *name = pfx;
5a882646
DH
15983 int index = i;
15984 if (!name) {
bcb2f0f5 15985 name = chname[i];
5a882646
DH
15986 index = 0;
15987 }
15988 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 15989 if (err < 0)
df694daa
KY
15990 return err;
15991 }
15992 }
15993 return 0;
15994}
15995
1c20930a 15996static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15997{
1c20930a 15998 struct alc_spec *spec = codec->spec;
df694daa
KY
15999 int err;
16000 hda_nid_t nid;
16001
f12ab1e0 16002 if (!pin)
df694daa
KY
16003 return 0;
16004
16005 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16006 nid = alc861_look_for_dac(codec, pin);
16007 if (nid) {
16008 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16009 if (err < 0)
16010 return err;
16011 spec->multiout.hp_nid = nid;
16012 }
df694daa
KY
16013 }
16014 return 0;
16015}
16016
16017/* create playback/capture controls for input pins */
05f5f477 16018static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16019 const struct auto_pin_cfg *cfg)
df694daa 16020{
05f5f477 16021 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16022}
16023
f12ab1e0
TI
16024static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16025 hda_nid_t nid,
1c20930a 16026 int pin_type, hda_nid_t dac)
df694daa 16027{
1c20930a
TI
16028 hda_nid_t mix, srcs[5];
16029 int i, num;
16030
564c5bea
JL
16031 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16032 pin_type);
1c20930a 16033 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16034 AMP_OUT_UNMUTE);
1c20930a
TI
16035 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16036 return;
16037 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16038 if (num < 0)
16039 return;
16040 for (i = 0; i < num; i++) {
16041 unsigned int mute;
16042 if (srcs[i] == dac || srcs[i] == 0x15)
16043 mute = AMP_IN_UNMUTE(i);
16044 else
16045 mute = AMP_IN_MUTE(i);
16046 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16047 mute);
16048 }
df694daa
KY
16049}
16050
16051static void alc861_auto_init_multi_out(struct hda_codec *codec)
16052{
16053 struct alc_spec *spec = codec->spec;
16054 int i;
16055
16056 for (i = 0; i < spec->autocfg.line_outs; i++) {
16057 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16058 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16059 if (nid)
baba8ee9 16060 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16061 spec->multiout.dac_nids[i]);
df694daa
KY
16062 }
16063}
16064
16065static void alc861_auto_init_hp_out(struct hda_codec *codec)
16066{
16067 struct alc_spec *spec = codec->spec;
df694daa 16068
15870f05
TI
16069 if (spec->autocfg.hp_outs)
16070 alc861_auto_set_output_and_unmute(codec,
16071 spec->autocfg.hp_pins[0],
16072 PIN_HP,
1c20930a 16073 spec->multiout.hp_nid);
15870f05
TI
16074 if (spec->autocfg.speaker_outs)
16075 alc861_auto_set_output_and_unmute(codec,
16076 spec->autocfg.speaker_pins[0],
16077 PIN_OUT,
1c20930a 16078 spec->multiout.dac_nids[0]);
df694daa
KY
16079}
16080
16081static void alc861_auto_init_analog_input(struct hda_codec *codec)
16082{
16083 struct alc_spec *spec = codec->spec;
66ceeb6b 16084 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16085 int i;
16086
66ceeb6b
TI
16087 for (i = 0; i < cfg->num_inputs; i++) {
16088 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16089 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16090 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16091 }
16092}
16093
16094/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16095/* return 1 if successful, 0 if the proper config is not found,
16096 * or a negative error code
16097 */
df694daa
KY
16098static int alc861_parse_auto_config(struct hda_codec *codec)
16099{
16100 struct alc_spec *spec = codec->spec;
16101 int err;
16102 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16103
f12ab1e0
TI
16104 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16105 alc861_ignore);
16106 if (err < 0)
df694daa 16107 return err;
f12ab1e0 16108 if (!spec->autocfg.line_outs)
df694daa
KY
16109 return 0; /* can't find valid BIOS pin config */
16110
1c20930a 16111 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
16112 if (err < 0)
16113 return err;
16114 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
16115 if (err < 0)
16116 return err;
1c20930a 16117 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16118 if (err < 0)
16119 return err;
1c20930a 16120 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16121 if (err < 0)
16122 return err;
05f5f477 16123 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16124 if (err < 0)
df694daa
KY
16125 return err;
16126
16127 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16128
757899ac 16129 alc_auto_parse_digital(codec);
df694daa 16130
603c4019 16131 if (spec->kctls.list)
d88897ea 16132 add_mixer(spec, spec->kctls.list);
df694daa 16133
d88897ea 16134 add_verb(spec, alc861_auto_init_verbs);
df694daa 16135
a1e8d2da 16136 spec->num_mux_defs = 1;
61b9b9b1 16137 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16138
16139 spec->adc_nids = alc861_adc_nids;
16140 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16141 set_capture_mixer(codec);
df694daa 16142
6227cdce 16143 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16144
df694daa
KY
16145 return 1;
16146}
16147
ae6b813a
TI
16148/* additional initialization for auto-configuration model */
16149static void alc861_auto_init(struct hda_codec *codec)
df694daa 16150{
f6c7e546 16151 struct alc_spec *spec = codec->spec;
df694daa
KY
16152 alc861_auto_init_multi_out(codec);
16153 alc861_auto_init_hp_out(codec);
16154 alc861_auto_init_analog_input(codec);
757899ac 16155 alc_auto_init_digital(codec);
f6c7e546 16156 if (spec->unsol_event)
7fb0d78f 16157 alc_inithook(codec);
df694daa
KY
16158}
16159
cb53c626
TI
16160#ifdef CONFIG_SND_HDA_POWER_SAVE
16161static struct hda_amp_list alc861_loopbacks[] = {
16162 { 0x15, HDA_INPUT, 0 },
16163 { 0x15, HDA_INPUT, 1 },
16164 { 0x15, HDA_INPUT, 2 },
16165 { 0x15, HDA_INPUT, 3 },
16166 { } /* end */
16167};
16168#endif
16169
df694daa
KY
16170
16171/*
16172 * configuration and preset
16173 */
ea734963 16174static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16175 [ALC861_3ST] = "3stack",
16176 [ALC660_3ST] = "3stack-660",
16177 [ALC861_3ST_DIG] = "3stack-dig",
16178 [ALC861_6ST_DIG] = "6stack-dig",
16179 [ALC861_UNIWILL_M31] = "uniwill-m31",
16180 [ALC861_TOSHIBA] = "toshiba",
16181 [ALC861_ASUS] = "asus",
16182 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16183 [ALC861_AUTO] = "auto",
16184};
16185
16186static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16187 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16188 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16189 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16190 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16191 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16192 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16193 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16194 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16195 * Any other models that need this preset?
16196 */
16197 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16198 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16199 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16200 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16201 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16202 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16203 /* FIXME: the below seems conflict */
16204 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16205 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16206 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16207 {}
16208};
16209
16210static struct alc_config_preset alc861_presets[] = {
16211 [ALC861_3ST] = {
16212 .mixers = { alc861_3ST_mixer },
16213 .init_verbs = { alc861_threestack_init_verbs },
16214 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16215 .dac_nids = alc861_dac_nids,
16216 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16217 .channel_mode = alc861_threestack_modes,
4e195a7b 16218 .need_dac_fix = 1,
df694daa
KY
16219 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16220 .adc_nids = alc861_adc_nids,
16221 .input_mux = &alc861_capture_source,
16222 },
16223 [ALC861_3ST_DIG] = {
16224 .mixers = { alc861_base_mixer },
16225 .init_verbs = { alc861_threestack_init_verbs },
16226 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16227 .dac_nids = alc861_dac_nids,
16228 .dig_out_nid = ALC861_DIGOUT_NID,
16229 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16230 .channel_mode = alc861_threestack_modes,
4e195a7b 16231 .need_dac_fix = 1,
df694daa
KY
16232 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16233 .adc_nids = alc861_adc_nids,
16234 .input_mux = &alc861_capture_source,
16235 },
16236 [ALC861_6ST_DIG] = {
16237 .mixers = { alc861_base_mixer },
16238 .init_verbs = { alc861_base_init_verbs },
16239 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16240 .dac_nids = alc861_dac_nids,
16241 .dig_out_nid = ALC861_DIGOUT_NID,
16242 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16243 .channel_mode = alc861_8ch_modes,
16244 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16245 .adc_nids = alc861_adc_nids,
16246 .input_mux = &alc861_capture_source,
16247 },
9c7f852e
TI
16248 [ALC660_3ST] = {
16249 .mixers = { alc861_3ST_mixer },
16250 .init_verbs = { alc861_threestack_init_verbs },
16251 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16252 .dac_nids = alc660_dac_nids,
16253 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16254 .channel_mode = alc861_threestack_modes,
4e195a7b 16255 .need_dac_fix = 1,
9c7f852e
TI
16256 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16257 .adc_nids = alc861_adc_nids,
16258 .input_mux = &alc861_capture_source,
16259 },
22309c3e
TI
16260 [ALC861_UNIWILL_M31] = {
16261 .mixers = { alc861_uniwill_m31_mixer },
16262 .init_verbs = { alc861_uniwill_m31_init_verbs },
16263 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16264 .dac_nids = alc861_dac_nids,
16265 .dig_out_nid = ALC861_DIGOUT_NID,
16266 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16267 .channel_mode = alc861_uniwill_m31_modes,
16268 .need_dac_fix = 1,
16269 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16270 .adc_nids = alc861_adc_nids,
16271 .input_mux = &alc861_capture_source,
16272 },
a53d1aec
TD
16273 [ALC861_TOSHIBA] = {
16274 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16275 .init_verbs = { alc861_base_init_verbs,
16276 alc861_toshiba_init_verbs },
a53d1aec
TD
16277 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16278 .dac_nids = alc861_dac_nids,
16279 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16280 .channel_mode = alc883_3ST_2ch_modes,
16281 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16282 .adc_nids = alc861_adc_nids,
16283 .input_mux = &alc861_capture_source,
16284 .unsol_event = alc861_toshiba_unsol_event,
16285 .init_hook = alc861_toshiba_automute,
16286 },
7cdbff94
MD
16287 [ALC861_ASUS] = {
16288 .mixers = { alc861_asus_mixer },
16289 .init_verbs = { alc861_asus_init_verbs },
16290 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16291 .dac_nids = alc861_dac_nids,
16292 .dig_out_nid = ALC861_DIGOUT_NID,
16293 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16294 .channel_mode = alc861_asus_modes,
16295 .need_dac_fix = 1,
16296 .hp_nid = 0x06,
16297 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16298 .adc_nids = alc861_adc_nids,
16299 .input_mux = &alc861_capture_source,
16300 },
56bb0cab
TI
16301 [ALC861_ASUS_LAPTOP] = {
16302 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16303 .init_verbs = { alc861_asus_init_verbs,
16304 alc861_asus_laptop_init_verbs },
16305 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16306 .dac_nids = alc861_dac_nids,
16307 .dig_out_nid = ALC861_DIGOUT_NID,
16308 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16309 .channel_mode = alc883_3ST_2ch_modes,
16310 .need_dac_fix = 1,
16311 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16312 .adc_nids = alc861_adc_nids,
16313 .input_mux = &alc861_capture_source,
16314 },
16315};
df694daa 16316
cfc9b06f
TI
16317/* Pin config fixes */
16318enum {
16319 PINFIX_FSC_AMILO_PI1505,
16320};
16321
cfc9b06f
TI
16322static const struct alc_fixup alc861_fixups[] = {
16323 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16324 .type = ALC_FIXUP_PINS,
16325 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16326 { 0x0b, 0x0221101f }, /* HP */
16327 { 0x0f, 0x90170310 }, /* speaker */
16328 { }
16329 }
cfc9b06f
TI
16330 },
16331};
16332
16333static struct snd_pci_quirk alc861_fixup_tbl[] = {
16334 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16335 {}
16336};
df694daa
KY
16337
16338static int patch_alc861(struct hda_codec *codec)
16339{
16340 struct alc_spec *spec;
16341 int board_config;
16342 int err;
16343
dc041e0b 16344 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16345 if (spec == NULL)
16346 return -ENOMEM;
16347
f12ab1e0 16348 codec->spec = spec;
df694daa 16349
f5fcc13c
TI
16350 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16351 alc861_models,
16352 alc861_cfg_tbl);
9c7f852e 16353
f5fcc13c 16354 if (board_config < 0) {
9a11f1aa
TI
16355 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16356 codec->chip_name);
df694daa
KY
16357 board_config = ALC861_AUTO;
16358 }
16359
b5bfbc67
TI
16360 if (board_config == ALC861_AUTO) {
16361 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16362 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16363 }
cfc9b06f 16364
df694daa
KY
16365 if (board_config == ALC861_AUTO) {
16366 /* automatic parse from the BIOS config */
16367 err = alc861_parse_auto_config(codec);
16368 if (err < 0) {
16369 alc_free(codec);
16370 return err;
f12ab1e0 16371 } else if (!err) {
9c7f852e
TI
16372 printk(KERN_INFO
16373 "hda_codec: Cannot set up configuration "
16374 "from BIOS. Using base mode...\n");
df694daa
KY
16375 board_config = ALC861_3ST_DIG;
16376 }
16377 }
16378
680cd536
KK
16379 err = snd_hda_attach_beep_device(codec, 0x23);
16380 if (err < 0) {
16381 alc_free(codec);
16382 return err;
16383 }
16384
df694daa 16385 if (board_config != ALC861_AUTO)
e9c364c0 16386 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16387
df694daa
KY
16388 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16389 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16390
df694daa
KY
16391 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16392 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16393
c7a8eb10
TI
16394 if (!spec->cap_mixer)
16395 set_capture_mixer(codec);
45bdd1c1
TI
16396 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16397
2134ea4f
TI
16398 spec->vmaster_nid = 0x03;
16399
b5bfbc67 16400 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16401
df694daa 16402 codec->patch_ops = alc_patch_ops;
c97259df 16403 if (board_config == ALC861_AUTO) {
ae6b813a 16404 spec->init_hook = alc861_auto_init;
c97259df
DC
16405#ifdef CONFIG_SND_HDA_POWER_SAVE
16406 spec->power_hook = alc_power_eapd;
16407#endif
16408 }
cb53c626
TI
16409#ifdef CONFIG_SND_HDA_POWER_SAVE
16410 if (!spec->loopback.amplist)
16411 spec->loopback.amplist = alc861_loopbacks;
16412#endif
ea1fb29a 16413
1da177e4
LT
16414 return 0;
16415}
16416
f32610ed
JS
16417/*
16418 * ALC861-VD support
16419 *
16420 * Based on ALC882
16421 *
16422 * In addition, an independent DAC
16423 */
16424#define ALC861VD_DIGOUT_NID 0x06
16425
16426static hda_nid_t alc861vd_dac_nids[4] = {
16427 /* front, surr, clfe, side surr */
16428 0x02, 0x03, 0x04, 0x05
16429};
16430
16431/* dac_nids for ALC660vd are in a different order - according to
16432 * Realtek's driver.
def319f9 16433 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16434 * of ALC660vd codecs, but for now there is only 3stack mixer
16435 * - and it is the same as in 861vd.
16436 * adc_nids in ALC660vd are (is) the same as in 861vd
16437 */
16438static hda_nid_t alc660vd_dac_nids[3] = {
16439 /* front, rear, clfe, rear_surr */
16440 0x02, 0x04, 0x03
16441};
16442
16443static hda_nid_t alc861vd_adc_nids[1] = {
16444 /* ADC0 */
16445 0x09,
16446};
16447
e1406348
TI
16448static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16449
f32610ed
JS
16450/* input MUX */
16451/* FIXME: should be a matrix-type input source selection */
16452static struct hda_input_mux alc861vd_capture_source = {
16453 .num_items = 4,
16454 .items = {
16455 { "Mic", 0x0 },
16456 { "Front Mic", 0x1 },
16457 { "Line", 0x2 },
16458 { "CD", 0x4 },
16459 },
16460};
16461
272a527c 16462static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16463 .num_items = 2,
272a527c 16464 .items = {
8607f7c4 16465 { "Mic", 0x0 },
28c4edb7 16466 { "Internal Mic", 0x1 },
272a527c
KY
16467 },
16468};
16469
d1a991a6
KY
16470static struct hda_input_mux alc861vd_hp_capture_source = {
16471 .num_items = 2,
16472 .items = {
16473 { "Front Mic", 0x0 },
16474 { "ATAPI Mic", 0x1 },
16475 },
16476};
16477
f32610ed
JS
16478/*
16479 * 2ch mode
16480 */
16481static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16482 { 2, NULL }
16483};
16484
16485/*
16486 * 6ch mode
16487 */
16488static struct hda_verb alc861vd_6stack_ch6_init[] = {
16489 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16490 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16491 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16492 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16493 { } /* end */
16494};
16495
16496/*
16497 * 8ch mode
16498 */
16499static struct hda_verb alc861vd_6stack_ch8_init[] = {
16500 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16501 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16502 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16503 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16504 { } /* end */
16505};
16506
16507static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16508 { 6, alc861vd_6stack_ch6_init },
16509 { 8, alc861vd_6stack_ch8_init },
16510};
16511
16512static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16513 {
16514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16515 .name = "Channel Mode",
16516 .info = alc_ch_mode_info,
16517 .get = alc_ch_mode_get,
16518 .put = alc_ch_mode_put,
16519 },
16520 { } /* end */
16521};
16522
f32610ed
JS
16523/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16524 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16525 */
16526static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16527 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16528 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16529
16530 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16531 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16532
16533 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16534 HDA_OUTPUT),
16535 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16536 HDA_OUTPUT),
16537 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16538 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16539
16540 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16541 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16542
16543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16544
5f99f86a 16545 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16547 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16548
5f99f86a 16549 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16550 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16551 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16552
16553 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16554 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16555
16556 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16557 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16558
f32610ed
JS
16559 { } /* end */
16560};
16561
16562static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16563 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16564 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16565
16566 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16567
5f99f86a 16568 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16569 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16570 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16571
5f99f86a 16572 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16573 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16574 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16575
16576 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16577 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16578
16579 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16580 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16581
f32610ed
JS
16582 { } /* end */
16583};
16584
bdd148a3
KY
16585static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16586 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16587 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16588 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16589
16590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16591
5f99f86a 16592 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16593 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16594 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16595
5f99f86a 16596 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16597 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16598 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16599
16600 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16601 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16602
16603 { } /* end */
16604};
16605
b419f346 16606/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16607 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16608 */
16609static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16610 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16611 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16612 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16613 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16614 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16615 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16616 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16617 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16618 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16619 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16620 { } /* end */
16621};
16622
d1a991a6
KY
16623/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16624 * Front Mic=0x18, ATAPI Mic = 0x19,
16625 */
16626static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16627 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16628 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16629 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16630 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16631 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16632 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16633 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16634 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16635
d1a991a6
KY
16636 { } /* end */
16637};
16638
f32610ed
JS
16639/*
16640 * generic initialization of ADC, input mixers and output mixers
16641 */
16642static struct hda_verb alc861vd_volume_init_verbs[] = {
16643 /*
16644 * Unmute ADC0 and set the default input to mic-in
16645 */
16646 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16647 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16648
16649 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16650 * the analog-loopback mixer widget
16651 */
16652 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16653 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16654 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16655 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16656 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16657 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16658
16659 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16660 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16661 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16662 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16664
16665 /*
16666 * Set up output mixers (0x02 - 0x05)
16667 */
16668 /* set vol=0 to output mixers */
16669 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16670 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16671 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16672 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16673
16674 /* set up input amps for analog loopback */
16675 /* Amp Indices: DAC = 0, mixer = 1 */
16676 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16677 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16678 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16680 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16681 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16682 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16683 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16684
16685 { }
16686};
16687
16688/*
16689 * 3-stack pin configuration:
16690 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16691 */
16692static struct hda_verb alc861vd_3stack_init_verbs[] = {
16693 /*
16694 * Set pin mode and muting
16695 */
16696 /* set front pin widgets 0x14 for output */
16697 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16698 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16699 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16700
16701 /* Mic (rear) pin: input vref at 80% */
16702 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16703 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16704 /* Front Mic pin: input vref at 80% */
16705 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16706 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16707 /* Line In pin: input */
16708 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16709 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16710 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16711 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16712 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16713 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16714 /* CD pin widget for input */
16715 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16716
16717 { }
16718};
16719
16720/*
16721 * 6-stack pin configuration:
16722 */
16723static struct hda_verb alc861vd_6stack_init_verbs[] = {
16724 /*
16725 * Set pin mode and muting
16726 */
16727 /* set front pin widgets 0x14 for output */
16728 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16729 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16730 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16731
16732 /* Rear Pin: output 1 (0x0d) */
16733 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16735 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16736 /* CLFE Pin: output 2 (0x0e) */
16737 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16738 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16739 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16740 /* Side Pin: output 3 (0x0f) */
16741 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16742 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16743 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16744
16745 /* Mic (rear) pin: input vref at 80% */
16746 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16747 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16748 /* Front Mic pin: input vref at 80% */
16749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16751 /* Line In pin: input */
16752 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16754 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16755 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16756 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16757 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16758 /* CD pin widget for input */
16759 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16760
16761 { }
16762};
16763
bdd148a3
KY
16764static struct hda_verb alc861vd_eapd_verbs[] = {
16765 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16766 { }
16767};
16768
f9423e7a
KY
16769static struct hda_verb alc660vd_eapd_verbs[] = {
16770 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16771 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16772 { }
16773};
16774
bdd148a3
KY
16775static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16776 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16777 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16778 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16779 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16780 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16781 {}
16782};
16783
4f5d1706 16784static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16785{
a9fd4f3f 16786 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16787 spec->autocfg.hp_pins[0] = 0x1b;
16788 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16789 spec->automute = 1;
16790 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
16791}
16792
16793static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16794{
d922b51d 16795 alc_hp_automute(codec);
eeb43387 16796 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16797}
16798
16799static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16800 unsigned int res)
16801{
16802 switch (res >> 26) {
bdd148a3 16803 case ALC880_MIC_EVENT:
eeb43387 16804 alc88x_simple_mic_automute(codec);
bdd148a3 16805 break;
a9fd4f3f 16806 default:
d922b51d 16807 alc_sku_unsol_event(codec, res);
a9fd4f3f 16808 break;
bdd148a3
KY
16809 }
16810}
16811
272a527c
KY
16812static struct hda_verb alc861vd_dallas_verbs[] = {
16813 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16814 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16815 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16816 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16817
16818 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16819 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16820 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16821 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16822 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16823 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16824 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16825 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16826
272a527c
KY
16827 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16828 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16829 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16830 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16831 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16832 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16833 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16834 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16835
16836 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16837 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16838 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16839 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16840 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16841 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16842 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16843 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16844
16845 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16847 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16848 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16849
16850 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16851 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16852 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16853
16854 { } /* end */
16855};
16856
16857/* toggle speaker-output according to the hp-jack state */
4f5d1706 16858static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16859{
a9fd4f3f 16860 struct alc_spec *spec = codec->spec;
272a527c 16861
a9fd4f3f
TI
16862 spec->autocfg.hp_pins[0] = 0x15;
16863 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16864 spec->automute = 1;
16865 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
16866}
16867
cb53c626
TI
16868#ifdef CONFIG_SND_HDA_POWER_SAVE
16869#define alc861vd_loopbacks alc880_loopbacks
16870#endif
16871
def319f9 16872/* pcm configuration: identical with ALC880 */
f32610ed
JS
16873#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16874#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16875#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16876#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16877
16878/*
16879 * configuration and preset
16880 */
ea734963 16881static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16882 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16883 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16884 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16885 [ALC861VD_3ST] = "3stack",
16886 [ALC861VD_3ST_DIG] = "3stack-digout",
16887 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16888 [ALC861VD_LENOVO] = "lenovo",
272a527c 16889 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16890 [ALC861VD_HP] = "hp",
f32610ed
JS
16891 [ALC861VD_AUTO] = "auto",
16892};
16893
16894static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16895 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16896 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16897 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16898 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16899 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16900 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16901 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16902 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16903 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16904 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16905 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16906 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16907 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16908 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16909 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16910 {}
16911};
16912
16913static struct alc_config_preset alc861vd_presets[] = {
16914 [ALC660VD_3ST] = {
16915 .mixers = { alc861vd_3st_mixer },
16916 .init_verbs = { alc861vd_volume_init_verbs,
16917 alc861vd_3stack_init_verbs },
16918 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16919 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16920 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16921 .channel_mode = alc861vd_3stack_2ch_modes,
16922 .input_mux = &alc861vd_capture_source,
16923 },
6963f84c
MC
16924 [ALC660VD_3ST_DIG] = {
16925 .mixers = { alc861vd_3st_mixer },
16926 .init_verbs = { alc861vd_volume_init_verbs,
16927 alc861vd_3stack_init_verbs },
16928 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16929 .dac_nids = alc660vd_dac_nids,
16930 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16931 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16932 .channel_mode = alc861vd_3stack_2ch_modes,
16933 .input_mux = &alc861vd_capture_source,
16934 },
f32610ed
JS
16935 [ALC861VD_3ST] = {
16936 .mixers = { alc861vd_3st_mixer },
16937 .init_verbs = { alc861vd_volume_init_verbs,
16938 alc861vd_3stack_init_verbs },
16939 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16940 .dac_nids = alc861vd_dac_nids,
16941 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16942 .channel_mode = alc861vd_3stack_2ch_modes,
16943 .input_mux = &alc861vd_capture_source,
16944 },
16945 [ALC861VD_3ST_DIG] = {
16946 .mixers = { alc861vd_3st_mixer },
16947 .init_verbs = { alc861vd_volume_init_verbs,
16948 alc861vd_3stack_init_verbs },
16949 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16950 .dac_nids = alc861vd_dac_nids,
16951 .dig_out_nid = ALC861VD_DIGOUT_NID,
16952 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16953 .channel_mode = alc861vd_3stack_2ch_modes,
16954 .input_mux = &alc861vd_capture_source,
16955 },
16956 [ALC861VD_6ST_DIG] = {
16957 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16958 .init_verbs = { alc861vd_volume_init_verbs,
16959 alc861vd_6stack_init_verbs },
16960 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16961 .dac_nids = alc861vd_dac_nids,
16962 .dig_out_nid = ALC861VD_DIGOUT_NID,
16963 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16964 .channel_mode = alc861vd_6stack_modes,
16965 .input_mux = &alc861vd_capture_source,
16966 },
bdd148a3
KY
16967 [ALC861VD_LENOVO] = {
16968 .mixers = { alc861vd_lenovo_mixer },
16969 .init_verbs = { alc861vd_volume_init_verbs,
16970 alc861vd_3stack_init_verbs,
16971 alc861vd_eapd_verbs,
16972 alc861vd_lenovo_unsol_verbs },
16973 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16974 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16975 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16976 .channel_mode = alc861vd_3stack_2ch_modes,
16977 .input_mux = &alc861vd_capture_source,
16978 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16979 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16980 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16981 },
272a527c
KY
16982 [ALC861VD_DALLAS] = {
16983 .mixers = { alc861vd_dallas_mixer },
16984 .init_verbs = { alc861vd_dallas_verbs },
16985 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16986 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16987 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16988 .channel_mode = alc861vd_3stack_2ch_modes,
16989 .input_mux = &alc861vd_dallas_capture_source,
d922b51d 16990 .unsol_event = alc_sku_unsol_event,
4f5d1706 16991 .setup = alc861vd_dallas_setup,
d922b51d 16992 .init_hook = alc_hp_automute,
d1a991a6
KY
16993 },
16994 [ALC861VD_HP] = {
16995 .mixers = { alc861vd_hp_mixer },
16996 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16997 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16998 .dac_nids = alc861vd_dac_nids,
d1a991a6 16999 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17000 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17001 .channel_mode = alc861vd_3stack_2ch_modes,
17002 .input_mux = &alc861vd_hp_capture_source,
d922b51d 17003 .unsol_event = alc_sku_unsol_event,
4f5d1706 17004 .setup = alc861vd_dallas_setup,
d922b51d 17005 .init_hook = alc_hp_automute,
ea1fb29a 17006 },
13c94744
TI
17007 [ALC660VD_ASUS_V1S] = {
17008 .mixers = { alc861vd_lenovo_mixer },
17009 .init_verbs = { alc861vd_volume_init_verbs,
17010 alc861vd_3stack_init_verbs,
17011 alc861vd_eapd_verbs,
17012 alc861vd_lenovo_unsol_verbs },
17013 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17014 .dac_nids = alc660vd_dac_nids,
17015 .dig_out_nid = ALC861VD_DIGOUT_NID,
17016 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17017 .channel_mode = alc861vd_3stack_2ch_modes,
17018 .input_mux = &alc861vd_capture_source,
17019 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17020 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17021 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17022 },
f32610ed
JS
17023};
17024
17025/*
17026 * BIOS auto configuration
17027 */
05f5f477
TI
17028static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17029 const struct auto_pin_cfg *cfg)
17030{
7167594a 17031 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17032}
17033
17034
f32610ed
JS
17035static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17036 hda_nid_t nid, int pin_type, int dac_idx)
17037{
f6c7e546 17038 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17039}
17040
17041static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17042{
17043 struct alc_spec *spec = codec->spec;
17044 int i;
17045
17046 for (i = 0; i <= HDA_SIDE; i++) {
17047 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17048 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17049 if (nid)
17050 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17051 pin_type, i);
f32610ed
JS
17052 }
17053}
17054
17055
17056static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17057{
17058 struct alc_spec *spec = codec->spec;
17059 hda_nid_t pin;
17060
17061 pin = spec->autocfg.hp_pins[0];
def319f9 17062 if (pin) /* connect to front and use dac 0 */
f32610ed 17063 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17064 pin = spec->autocfg.speaker_pins[0];
17065 if (pin)
17066 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17067}
17068
f32610ed
JS
17069#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17070
17071static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17072{
17073 struct alc_spec *spec = codec->spec;
66ceeb6b 17074 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17075 int i;
17076
66ceeb6b
TI
17077 for (i = 0; i < cfg->num_inputs; i++) {
17078 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17079 if (alc_is_input_pin(codec, nid)) {
30ea098f 17080 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17081 if (nid != ALC861VD_PIN_CD_NID &&
17082 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17083 snd_hda_codec_write(codec, nid, 0,
17084 AC_VERB_SET_AMP_GAIN_MUTE,
17085 AMP_OUT_MUTE);
17086 }
17087 }
17088}
17089
f511b01c
TI
17090#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17091
f32610ed
JS
17092#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17093#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17094
17095/* add playback controls from the parsed DAC table */
569ed348 17096/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17097 * different NIDs for mute/unmute switch and volume control */
17098static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17099 const struct auto_pin_cfg *cfg)
17100{
ea734963
TI
17101 static const char * const chname[4] = {
17102 "Front", "Surround", "CLFE", "Side"
17103 };
ce764ab2 17104 const char *pfx = alc_get_line_out_pfx(spec, true);
f32610ed 17105 hda_nid_t nid_v, nid_s;
ce764ab2 17106 int i, err, noutputs;
f32610ed 17107
ce764ab2
TI
17108 noutputs = cfg->line_outs;
17109 if (spec->multi_ios > 0)
17110 noutputs += spec->multi_ios;
17111
17112 for (i = 0; i < noutputs; i++) {
f12ab1e0 17113 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17114 continue;
17115 nid_v = alc861vd_idx_to_mixer_vol(
17116 alc880_dac_to_idx(
17117 spec->multiout.dac_nids[i]));
17118 nid_s = alc861vd_idx_to_mixer_switch(
17119 alc880_dac_to_idx(
17120 spec->multiout.dac_nids[i]));
17121
bcb2f0f5 17122 if (!pfx && i == 2) {
f32610ed 17123 /* Center/LFE */
0afe5f89
TI
17124 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17125 "Center",
f12ab1e0
TI
17126 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17127 HDA_OUTPUT));
17128 if (err < 0)
f32610ed 17129 return err;
0afe5f89
TI
17130 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17131 "LFE",
f12ab1e0
TI
17132 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17133 HDA_OUTPUT));
17134 if (err < 0)
f32610ed 17135 return err;
0afe5f89
TI
17136 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17137 "Center",
f12ab1e0
TI
17138 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17139 HDA_INPUT));
17140 if (err < 0)
f32610ed 17141 return err;
0afe5f89
TI
17142 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17143 "LFE",
f12ab1e0
TI
17144 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17145 HDA_INPUT));
17146 if (err < 0)
f32610ed
JS
17147 return err;
17148 } else {
bcb2f0f5 17149 const char *name = pfx;
5a882646
DH
17150 int index = i;
17151 if (!name) {
bcb2f0f5 17152 name = chname[i];
5a882646
DH
17153 index = 0;
17154 }
bcb2f0f5 17155 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 17156 name, index,
f12ab1e0
TI
17157 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17158 HDA_OUTPUT));
17159 if (err < 0)
f32610ed 17160 return err;
bcb2f0f5 17161 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 17162 name, index,
bdd148a3 17163 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17164 HDA_INPUT));
17165 if (err < 0)
f32610ed
JS
17166 return err;
17167 }
17168 }
17169 return 0;
17170}
17171
17172/* add playback controls for speaker and HP outputs */
17173/* Based on ALC880 version. But ALC861VD has separate,
17174 * different NIDs for mute/unmute switch and volume control */
17175static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17176 hda_nid_t pin, const char *pfx)
17177{
17178 hda_nid_t nid_v, nid_s;
17179 int err;
f32610ed 17180
f12ab1e0 17181 if (!pin)
f32610ed
JS
17182 return 0;
17183
17184 if (alc880_is_fixed_pin(pin)) {
17185 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17186 /* specify the DAC as the extra output */
f12ab1e0 17187 if (!spec->multiout.hp_nid)
f32610ed
JS
17188 spec->multiout.hp_nid = nid_v;
17189 else
17190 spec->multiout.extra_out_nid[0] = nid_v;
17191 /* control HP volume/switch on the output mixer amp */
17192 nid_v = alc861vd_idx_to_mixer_vol(
17193 alc880_fixed_pin_idx(pin));
17194 nid_s = alc861vd_idx_to_mixer_switch(
17195 alc880_fixed_pin_idx(pin));
17196
0afe5f89 17197 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17198 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17199 if (err < 0)
f32610ed 17200 return err;
0afe5f89 17201 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17202 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17203 if (err < 0)
f32610ed
JS
17204 return err;
17205 } else if (alc880_is_multi_pin(pin)) {
17206 /* set manual connection */
17207 /* we have only a switch on HP-out PIN */
0afe5f89 17208 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17209 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17210 if (err < 0)
f32610ed
JS
17211 return err;
17212 }
17213 return 0;
17214}
17215
17216/* parse the BIOS configuration and set up the alc_spec
17217 * return 1 if successful, 0 if the proper config is not found,
17218 * or a negative error code
17219 * Based on ALC880 version - had to change it to override
17220 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17221static int alc861vd_parse_auto_config(struct hda_codec *codec)
17222{
17223 struct alc_spec *spec = codec->spec;
17224 int err;
17225 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17226
f12ab1e0
TI
17227 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17228 alc861vd_ignore);
17229 if (err < 0)
f32610ed 17230 return err;
f12ab1e0 17231 if (!spec->autocfg.line_outs)
f32610ed
JS
17232 return 0; /* can't find valid BIOS pin config */
17233
f12ab1e0 17234 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
17235 if (err < 0)
17236 return err;
17237 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
17238 if (err < 0)
17239 return err;
17240 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17241 if (err < 0)
17242 return err;
17243 err = alc861vd_auto_create_extra_out(spec,
17244 spec->autocfg.speaker_pins[0],
17245 "Speaker");
17246 if (err < 0)
17247 return err;
17248 err = alc861vd_auto_create_extra_out(spec,
17249 spec->autocfg.hp_pins[0],
17250 "Headphone");
17251 if (err < 0)
17252 return err;
05f5f477 17253 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17254 if (err < 0)
f32610ed
JS
17255 return err;
17256
17257 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17258
757899ac 17259 alc_auto_parse_digital(codec);
f32610ed 17260
603c4019 17261 if (spec->kctls.list)
d88897ea 17262 add_mixer(spec, spec->kctls.list);
f32610ed 17263
d88897ea 17264 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17265
17266 spec->num_mux_defs = 1;
61b9b9b1 17267 spec->input_mux = &spec->private_imux[0];
f32610ed 17268
776e184e
TI
17269 err = alc_auto_add_mic_boost(codec);
17270 if (err < 0)
17271 return err;
17272
6227cdce 17273 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17274
f32610ed
JS
17275 return 1;
17276}
17277
17278/* additional initialization for auto-configuration model */
17279static void alc861vd_auto_init(struct hda_codec *codec)
17280{
f6c7e546 17281 struct alc_spec *spec = codec->spec;
f32610ed
JS
17282 alc861vd_auto_init_multi_out(codec);
17283 alc861vd_auto_init_hp_out(codec);
17284 alc861vd_auto_init_analog_input(codec);
f511b01c 17285 alc861vd_auto_init_input_src(codec);
757899ac 17286 alc_auto_init_digital(codec);
f6c7e546 17287 if (spec->unsol_event)
7fb0d78f 17288 alc_inithook(codec);
f32610ed
JS
17289}
17290
f8f25ba3
TI
17291enum {
17292 ALC660VD_FIX_ASUS_GPIO1
17293};
17294
17295/* reset GPIO1 */
f8f25ba3
TI
17296static const struct alc_fixup alc861vd_fixups[] = {
17297 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17298 .type = ALC_FIXUP_VERBS,
17299 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17300 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17301 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17302 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17303 { }
17304 }
f8f25ba3
TI
17305 },
17306};
17307
17308static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17309 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17310 {}
17311};
17312
f32610ed
JS
17313static int patch_alc861vd(struct hda_codec *codec)
17314{
17315 struct alc_spec *spec;
17316 int err, board_config;
17317
17318 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17319 if (spec == NULL)
17320 return -ENOMEM;
17321
17322 codec->spec = spec;
17323
17324 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17325 alc861vd_models,
17326 alc861vd_cfg_tbl);
17327
17328 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17329 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17330 codec->chip_name);
f32610ed
JS
17331 board_config = ALC861VD_AUTO;
17332 }
17333
b5bfbc67
TI
17334 if (board_config == ALC861VD_AUTO) {
17335 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17336 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17337 }
f8f25ba3 17338
f32610ed
JS
17339 if (board_config == ALC861VD_AUTO) {
17340 /* automatic parse from the BIOS config */
17341 err = alc861vd_parse_auto_config(codec);
17342 if (err < 0) {
17343 alc_free(codec);
17344 return err;
f12ab1e0 17345 } else if (!err) {
f32610ed
JS
17346 printk(KERN_INFO
17347 "hda_codec: Cannot set up configuration "
17348 "from BIOS. Using base mode...\n");
17349 board_config = ALC861VD_3ST;
17350 }
17351 }
17352
680cd536
KK
17353 err = snd_hda_attach_beep_device(codec, 0x23);
17354 if (err < 0) {
17355 alc_free(codec);
17356 return err;
17357 }
17358
f32610ed 17359 if (board_config != ALC861VD_AUTO)
e9c364c0 17360 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17361
2f893286 17362 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17363 /* always turn on EAPD */
d88897ea 17364 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17365 }
17366
f32610ed
JS
17367 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17368 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17369
f32610ed
JS
17370 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17371 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17372
dd704698
TI
17373 if (!spec->adc_nids) {
17374 spec->adc_nids = alc861vd_adc_nids;
17375 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17376 }
17377 if (!spec->capsrc_nids)
17378 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17379
b59bdf3b 17380 set_capture_mixer(codec);
45bdd1c1 17381 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17382
2134ea4f
TI
17383 spec->vmaster_nid = 0x02;
17384
b5bfbc67 17385 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17386
f32610ed
JS
17387 codec->patch_ops = alc_patch_ops;
17388
17389 if (board_config == ALC861VD_AUTO)
17390 spec->init_hook = alc861vd_auto_init;
1c716153 17391 spec->shutup = alc_eapd_shutup;
cb53c626
TI
17392#ifdef CONFIG_SND_HDA_POWER_SAVE
17393 if (!spec->loopback.amplist)
17394 spec->loopback.amplist = alc861vd_loopbacks;
17395#endif
f32610ed
JS
17396
17397 return 0;
17398}
17399
bc9f98a9
KY
17400/*
17401 * ALC662 support
17402 *
17403 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17404 * configuration. Each pin widget can choose any input DACs and a mixer.
17405 * Each ADC is connected from a mixer of all inputs. This makes possible
17406 * 6-channel independent captures.
17407 *
17408 * In addition, an independent DAC for the multi-playback (not used in this
17409 * driver yet).
17410 */
17411#define ALC662_DIGOUT_NID 0x06
17412#define ALC662_DIGIN_NID 0x0a
17413
4bf4a6c5
RY
17414static hda_nid_t alc662_dac_nids[3] = {
17415 /* front, rear, clfe */
bc9f98a9
KY
17416 0x02, 0x03, 0x04
17417};
17418
622e84cd
KY
17419static hda_nid_t alc272_dac_nids[2] = {
17420 0x02, 0x03
17421};
17422
b59bdf3b 17423static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17424 /* ADC1-2 */
b59bdf3b 17425 0x09, 0x08
bc9f98a9 17426};
e1406348 17427
622e84cd
KY
17428static hda_nid_t alc272_adc_nids[1] = {
17429 /* ADC1-2 */
17430 0x08,
17431};
17432
b59bdf3b 17433static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17434static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17435
e1406348 17436
bc9f98a9
KY
17437/* input MUX */
17438/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17439static struct hda_input_mux alc662_capture_source = {
17440 .num_items = 4,
17441 .items = {
17442 { "Mic", 0x0 },
17443 { "Front Mic", 0x1 },
17444 { "Line", 0x2 },
17445 { "CD", 0x4 },
17446 },
17447};
17448
17449static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17450 .num_items = 2,
17451 .items = {
17452 { "Mic", 0x1 },
17453 { "Line", 0x2 },
17454 },
17455};
291702f0 17456
6dda9f4a
KY
17457static struct hda_input_mux alc663_capture_source = {
17458 .num_items = 3,
17459 .items = {
17460 { "Mic", 0x0 },
17461 { "Front Mic", 0x1 },
17462 { "Line", 0x2 },
17463 },
17464};
17465
4f5d1706 17466#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17467static struct hda_input_mux alc272_nc10_capture_source = {
17468 .num_items = 16,
17469 .items = {
17470 { "Autoselect Mic", 0x0 },
17471 { "Internal Mic", 0x1 },
17472 { "In-0x02", 0x2 },
17473 { "In-0x03", 0x3 },
17474 { "In-0x04", 0x4 },
17475 { "In-0x05", 0x5 },
17476 { "In-0x06", 0x6 },
17477 { "In-0x07", 0x7 },
17478 { "In-0x08", 0x8 },
17479 { "In-0x09", 0x9 },
17480 { "In-0x0a", 0x0a },
17481 { "In-0x0b", 0x0b },
17482 { "In-0x0c", 0x0c },
17483 { "In-0x0d", 0x0d },
17484 { "In-0x0e", 0x0e },
17485 { "In-0x0f", 0x0f },
17486 },
17487};
17488#endif
17489
bc9f98a9
KY
17490/*
17491 * 2ch mode
17492 */
17493static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17494 { 2, NULL }
17495};
17496
17497/*
17498 * 2ch mode
17499 */
17500static struct hda_verb alc662_3ST_ch2_init[] = {
17501 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17502 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17503 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17504 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17505 { } /* end */
17506};
17507
17508/*
17509 * 6ch mode
17510 */
17511static struct hda_verb alc662_3ST_ch6_init[] = {
17512 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17513 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17514 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17515 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17516 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17517 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17518 { } /* end */
17519};
17520
17521static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17522 { 2, alc662_3ST_ch2_init },
17523 { 6, alc662_3ST_ch6_init },
17524};
17525
17526/*
17527 * 2ch mode
17528 */
17529static struct hda_verb alc662_sixstack_ch6_init[] = {
17530 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17531 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17532 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17533 { } /* end */
17534};
17535
17536/*
17537 * 6ch mode
17538 */
17539static struct hda_verb alc662_sixstack_ch8_init[] = {
17540 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17541 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17542 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17543 { } /* end */
17544};
17545
17546static struct hda_channel_mode alc662_5stack_modes[2] = {
17547 { 2, alc662_sixstack_ch6_init },
17548 { 6, alc662_sixstack_ch8_init },
17549};
17550
17551/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17552 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17553 */
17554
17555static struct snd_kcontrol_new alc662_base_mixer[] = {
17556 /* output mixer control */
17557 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17558 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17559 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17560 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17561 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17562 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17563 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17564 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17565 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17566
17567 /*Input mixer control */
17568 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17569 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17570 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17571 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17572 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17573 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17574 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17575 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17576 { } /* end */
17577};
17578
17579static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17580 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17581 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17582 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17583 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17584 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17585 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17586 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
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("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17590 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17591 { } /* end */
17592};
17593
17594static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17595 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17596 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17597 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17598 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17599 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17600 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17601 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17602 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17604 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17605 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17606 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17607 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17609 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17610 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17611 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17612 { } /* end */
17613};
17614
17615static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17616 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17617 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17618 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17619 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17620 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17624 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17625 { } /* end */
17626};
17627
291702f0 17628static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17629 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17630 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17631
5f99f86a 17632 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17633 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17634 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17635
5f99f86a 17636 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17637 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17638 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17639 { } /* end */
17640};
17641
8c427226 17642static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17643 ALC262_HIPPO_MASTER_SWITCH,
17644 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17645 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17646 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17647 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17648 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17649 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17650 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17652 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17653 { } /* end */
17654};
17655
f1d4e28b
KY
17656static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17657 .ops = &snd_hda_bind_vol,
17658 .values = {
17659 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17660 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17661 0
17662 },
17663};
17664
17665static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17666 .ops = &snd_hda_bind_sw,
17667 .values = {
17668 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17669 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17670 0
17671 },
17672};
17673
6dda9f4a 17674static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17675 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17676 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17679 { } /* end */
17680};
17681
17682static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17683 .ops = &snd_hda_bind_sw,
17684 .values = {
17685 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17686 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17687 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17688 0
17689 },
17690};
17691
17692static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17693 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17694 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17695 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17696 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17697 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17698 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17699
17700 { } /* end */
17701};
17702
17703static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17704 .ops = &snd_hda_bind_sw,
17705 .values = {
17706 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17707 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17708 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17709 0
17710 },
17711};
17712
17713static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17714 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17715 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17716 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17717 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17718 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17719 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17720 { } /* end */
17721};
17722
17723static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17724 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17725 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17726 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17729 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17730 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17731 { } /* end */
17732};
17733
17734static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17735 .ops = &snd_hda_bind_vol,
17736 .values = {
17737 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17738 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17739 0
17740 },
17741};
17742
17743static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17744 .ops = &snd_hda_bind_sw,
17745 .values = {
17746 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17747 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17748 0
17749 },
17750};
17751
17752static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17753 HDA_BIND_VOL("Master Playback Volume",
17754 &alc663_asus_two_bind_master_vol),
17755 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17756 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17757 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17759 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17760 { } /* end */
17761};
17762
17763static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17764 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17765 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17766 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17767 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17768 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17769 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17770 { } /* end */
17771};
17772
17773static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17774 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17775 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17776 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17777 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17779
17780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17782 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17783 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17784 { } /* end */
17785};
17786
17787static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17788 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17789 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17790 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17791
17792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17793 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17794 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17795 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17796 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17797 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17798 { } /* end */
17799};
17800
ebb83eeb
KY
17801static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17802 .ops = &snd_hda_bind_sw,
17803 .values = {
17804 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17805 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17806 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17807 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17808 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17809 0
17810 },
17811};
17812
17813static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17814 .ops = &snd_hda_bind_sw,
17815 .values = {
17816 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17817 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17818 0
17819 },
17820};
17821
17822static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17823 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17824 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17825 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17826 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17827 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17828 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17829 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17831 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17832 { } /* end */
17833};
17834
17835static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17836 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17837 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17838 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17839 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17840 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17842 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17843 { } /* end */
17844};
17845
17846
bc9f98a9
KY
17847static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17848 {
17849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17850 .name = "Channel Mode",
17851 .info = alc_ch_mode_info,
17852 .get = alc_ch_mode_get,
17853 .put = alc_ch_mode_put,
17854 },
17855 { } /* end */
17856};
17857
17858static struct hda_verb alc662_init_verbs[] = {
17859 /* ADC: mute amp left and right */
17860 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17861 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17862
b60dd394
KY
17863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17865 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17866 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17867 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17868 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17869
17870 /* Front Pin: output 0 (0x0c) */
17871 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17873
17874 /* Rear Pin: output 1 (0x0d) */
17875 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17876 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17877
17878 /* CLFE Pin: output 2 (0x0e) */
17879 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17880 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17881
17882 /* Mic (rear) pin: input vref at 80% */
17883 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17884 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17885 /* Front Mic pin: input vref at 80% */
17886 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17887 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17888 /* Line In pin: input */
17889 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17890 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17891 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17892 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17893 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17894 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17895 /* CD pin widget for input */
17896 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17897
17898 /* FIXME: use matrix-type input source selection */
17899 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17900 /* Input mixer */
17901 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17902 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a 17903
a7f2371f
TI
17904 { }
17905};
17906
17907static struct hda_verb alc662_eapd_init_verbs[] = {
6dda9f4a
KY
17908 /* always trun on EAPD */
17909 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17910 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
bc9f98a9
KY
17911 { }
17912};
17913
17914static struct hda_verb alc662_sue_init_verbs[] = {
17915 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17916 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17917 {}
17918};
17919
17920static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17921 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17922 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17923 {}
bc9f98a9
KY
17924};
17925
8c427226
KY
17926/* Set Unsolicited Event*/
17927static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17928 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17929 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17930 {}
17931};
17932
6dda9f4a 17933static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17934 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17935 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17936 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17937 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17938 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17939 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17940 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17941 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17942 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17943 {}
17944};
17945
17946static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17947 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17948 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17949 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17950 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17951 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17952 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17953 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17954 {}
17955};
17956
17957static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17958 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17959 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17960 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17961 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17963 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17964 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17965 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17966 {}
17967};
6dda9f4a 17968
f1d4e28b
KY
17969static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17970 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17971 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17972 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17973 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17974 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17975 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17976 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17977 {}
17978};
6dda9f4a 17979
f1d4e28b
KY
17980static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17981 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17982 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17983 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17984 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17985 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17986 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17987 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17989 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17990 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17991 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17992 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17993 {}
17994};
17995
17996static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17997 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17998 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17999 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18000 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18001 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18003 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18004 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18006 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18007 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18008 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18009 {}
18010};
18011
18012static struct hda_verb alc663_g71v_init_verbs[] = {
18013 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18014 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18015 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18016
18017 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18018 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18019 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18020
18021 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18022 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18023 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18024 {}
18025};
18026
18027static struct hda_verb alc663_g50v_init_verbs[] = {
18028 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18029 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18030 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18031
18032 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18033 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18034 {}
18035};
18036
f1d4e28b
KY
18037static struct hda_verb alc662_ecs_init_verbs[] = {
18038 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18039 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18040 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18041 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18042 {}
18043};
18044
622e84cd
KY
18045static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18046 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18047 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18048 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18049 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18050 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18051 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18052 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18054 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18055 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18056 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18057 {}
18058};
18059
18060static struct hda_verb alc272_dell_init_verbs[] = {
18061 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18062 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18063 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18064 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18065 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18066 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18067 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18069 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18070 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18071 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18072 {}
18073};
18074
ebb83eeb
KY
18075static struct hda_verb alc663_mode7_init_verbs[] = {
18076 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18077 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18078 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18079 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18080 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18081 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18082 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18083 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18084 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18085 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18088 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18089 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18090 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18091 {}
18092};
18093
18094static struct hda_verb alc663_mode8_init_verbs[] = {
18095 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18097 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18098 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18099 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18100 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18101 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18102 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18103 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18104 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18105 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18106 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18108 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18109 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18110 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18111 {}
18112};
18113
f1d4e28b
KY
18114static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18115 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18116 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18117 { } /* end */
18118};
18119
622e84cd
KY
18120static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18121 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18122 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18123 { } /* end */
18124};
18125
e6a5e1b7 18126static void alc662_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 18127{
e6a5e1b7 18128 struct alc_spec *spec = codec->spec;
bc9f98a9 18129
e6a5e1b7
TI
18130 spec->autocfg.hp_pins[0] = 0x1b;
18131 spec->autocfg.line_out_pins[0] = 0x14;
18132 spec->autocfg.speaker_pins[0] = 0x15;
18133 spec->automute = 1;
18134 spec->detect_line = 1;
18135 spec->automute_lines = 1;
18136 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
18137}
18138
4f5d1706
TI
18139static void alc662_eeepc_setup(struct hda_codec *codec)
18140{
18141 struct alc_spec *spec = codec->spec;
18142
18143 alc262_hippo1_setup(codec);
18144 spec->ext_mic.pin = 0x18;
18145 spec->ext_mic.mux_idx = 0;
18146 spec->int_mic.pin = 0x19;
18147 spec->int_mic.mux_idx = 1;
18148 spec->auto_mic = 1;
18149}
18150
4f5d1706 18151static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18152{
42171c17
TI
18153 struct alc_spec *spec = codec->spec;
18154
18155 spec->autocfg.hp_pins[0] = 0x14;
18156 spec->autocfg.speaker_pins[0] = 0x1b;
e9427969
TI
18157 spec->automute = 1;
18158 spec->automute_mode = ALC_AUTOMUTE_AMP;
8c427226
KY
18159}
18160
4f5d1706
TI
18161static void alc663_m51va_setup(struct hda_codec *codec)
18162{
18163 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18164 spec->autocfg.hp_pins[0] = 0x21;
18165 spec->autocfg.speaker_pins[0] = 0x14;
18166 spec->automute_mixer_nid[0] = 0x0c;
18167 spec->automute = 1;
18168 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
18169 spec->ext_mic.pin = 0x18;
18170 spec->ext_mic.mux_idx = 0;
18171 spec->int_mic.pin = 0x12;
ebb83eeb 18172 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18173 spec->auto_mic = 1;
18174}
18175
f1d4e28b 18176/* ***************** Mode1 ******************************/
ebb83eeb
KY
18177static void alc663_mode1_setup(struct hda_codec *codec)
18178{
18179 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18180 spec->autocfg.hp_pins[0] = 0x21;
18181 spec->autocfg.speaker_pins[0] = 0x14;
18182 spec->automute_mixer_nid[0] = 0x0c;
18183 spec->automute = 1;
18184 spec->automute_mode = ALC_AUTOMUTE_MIXER;
ebb83eeb
KY
18185 spec->ext_mic.pin = 0x18;
18186 spec->ext_mic.mux_idx = 0;
18187 spec->int_mic.pin = 0x19;
18188 spec->int_mic.mux_idx = 1;
18189 spec->auto_mic = 1;
18190}
18191
f1d4e28b 18192/* ***************** Mode2 ******************************/
3b8510ce 18193static void alc662_mode2_setup(struct hda_codec *codec)
f1d4e28b 18194{
3b8510ce
TI
18195 struct alc_spec *spec = codec->spec;
18196 spec->autocfg.hp_pins[0] = 0x1b;
18197 spec->autocfg.speaker_pins[0] = 0x14;
18198 spec->automute = 1;
18199 spec->automute_mode = ALC_AUTOMUTE_PIN;
18200 spec->ext_mic.pin = 0x18;
18201 spec->ext_mic.mux_idx = 0;
18202 spec->int_mic.pin = 0x19;
18203 spec->int_mic.mux_idx = 1;
18204 spec->auto_mic = 1;
f1d4e28b
KY
18205}
18206
f1d4e28b 18207/* ***************** Mode3 ******************************/
3b8510ce 18208static void alc663_mode3_setup(struct hda_codec *codec)
f1d4e28b 18209{
3b8510ce
TI
18210 struct alc_spec *spec = codec->spec;
18211 spec->autocfg.hp_pins[0] = 0x21;
18212 spec->autocfg.hp_pins[0] = 0x15;
18213 spec->autocfg.speaker_pins[0] = 0x14;
18214 spec->automute = 1;
18215 spec->automute_mode = ALC_AUTOMUTE_PIN;
18216 spec->ext_mic.pin = 0x18;
18217 spec->ext_mic.mux_idx = 0;
18218 spec->int_mic.pin = 0x19;
18219 spec->int_mic.mux_idx = 1;
18220 spec->auto_mic = 1;
f1d4e28b
KY
18221}
18222
f1d4e28b 18223/* ***************** Mode4 ******************************/
3b8510ce 18224static void alc663_mode4_setup(struct hda_codec *codec)
f1d4e28b 18225{
3b8510ce
TI
18226 struct alc_spec *spec = codec->spec;
18227 spec->autocfg.hp_pins[0] = 0x21;
18228 spec->autocfg.speaker_pins[0] = 0x14;
18229 spec->autocfg.speaker_pins[1] = 0x16;
18230 spec->automute_mixer_nid[0] = 0x0c;
18231 spec->automute_mixer_nid[1] = 0x0e;
18232 spec->automute = 1;
18233 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18234 spec->ext_mic.pin = 0x18;
18235 spec->ext_mic.mux_idx = 0;
18236 spec->int_mic.pin = 0x19;
18237 spec->int_mic.mux_idx = 1;
18238 spec->auto_mic = 1;
f1d4e28b
KY
18239}
18240
f1d4e28b 18241/* ***************** Mode5 ******************************/
3b8510ce 18242static void alc663_mode5_setup(struct hda_codec *codec)
f1d4e28b 18243{
3b8510ce
TI
18244 struct alc_spec *spec = codec->spec;
18245 spec->autocfg.hp_pins[0] = 0x15;
18246 spec->autocfg.speaker_pins[0] = 0x14;
18247 spec->autocfg.speaker_pins[1] = 0x16;
18248 spec->automute_mixer_nid[0] = 0x0c;
18249 spec->automute_mixer_nid[1] = 0x0e;
18250 spec->automute = 1;
18251 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18252 spec->ext_mic.pin = 0x18;
18253 spec->ext_mic.mux_idx = 0;
18254 spec->int_mic.pin = 0x19;
18255 spec->int_mic.mux_idx = 1;
18256 spec->auto_mic = 1;
f1d4e28b
KY
18257}
18258
f1d4e28b 18259/* ***************** Mode6 ******************************/
3b8510ce 18260static void alc663_mode6_setup(struct hda_codec *codec)
f1d4e28b 18261{
3b8510ce
TI
18262 struct alc_spec *spec = codec->spec;
18263 spec->autocfg.hp_pins[0] = 0x1b;
18264 spec->autocfg.hp_pins[0] = 0x15;
18265 spec->autocfg.speaker_pins[0] = 0x14;
18266 spec->automute_mixer_nid[0] = 0x0c;
18267 spec->automute = 1;
18268 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18269 spec->ext_mic.pin = 0x18;
18270 spec->ext_mic.mux_idx = 0;
18271 spec->int_mic.pin = 0x19;
18272 spec->int_mic.mux_idx = 1;
18273 spec->auto_mic = 1;
f1d4e28b
KY
18274}
18275
ebb83eeb 18276/* ***************** Mode7 ******************************/
3b8510ce 18277static void alc663_mode7_setup(struct hda_codec *codec)
ebb83eeb 18278{
3b8510ce
TI
18279 struct alc_spec *spec = codec->spec;
18280 spec->autocfg.hp_pins[0] = 0x1b;
18281 spec->autocfg.hp_pins[0] = 0x21;
18282 spec->autocfg.speaker_pins[0] = 0x14;
18283 spec->autocfg.speaker_pins[0] = 0x17;
18284 spec->automute = 1;
18285 spec->automute_mode = ALC_AUTOMUTE_PIN;
18286 spec->ext_mic.pin = 0x18;
18287 spec->ext_mic.mux_idx = 0;
18288 spec->int_mic.pin = 0x19;
18289 spec->int_mic.mux_idx = 1;
18290 spec->auto_mic = 1;
ebb83eeb
KY
18291}
18292
18293/* ***************** Mode8 ******************************/
3b8510ce 18294static void alc663_mode8_setup(struct hda_codec *codec)
ebb83eeb 18295{
3b8510ce
TI
18296 struct alc_spec *spec = codec->spec;
18297 spec->autocfg.hp_pins[0] = 0x21;
18298 spec->autocfg.hp_pins[1] = 0x15;
18299 spec->autocfg.speaker_pins[0] = 0x14;
18300 spec->autocfg.speaker_pins[0] = 0x17;
18301 spec->automute = 1;
18302 spec->automute_mode = ALC_AUTOMUTE_PIN;
18303 spec->ext_mic.pin = 0x18;
18304 spec->ext_mic.mux_idx = 0;
18305 spec->int_mic.pin = 0x12;
18306 spec->int_mic.mux_idx = 9;
18307 spec->auto_mic = 1;
ebb83eeb
KY
18308}
18309
e6a5e1b7 18310static void alc663_g71v_setup(struct hda_codec *codec)
6dda9f4a 18311{
e6a5e1b7
TI
18312 struct alc_spec *spec = codec->spec;
18313 spec->autocfg.hp_pins[0] = 0x21;
18314 spec->autocfg.line_out_pins[0] = 0x15;
18315 spec->autocfg.speaker_pins[0] = 0x14;
18316 spec->automute = 1;
18317 spec->automute_mode = ALC_AUTOMUTE_AMP;
18318 spec->detect_line = 1;
18319 spec->automute_lines = 1;
18320 spec->ext_mic.pin = 0x18;
18321 spec->ext_mic.mux_idx = 0;
18322 spec->int_mic.pin = 0x12;
18323 spec->int_mic.mux_idx = 9;
18324 spec->auto_mic = 1;
6dda9f4a
KY
18325}
18326
4f5d1706
TI
18327#define alc663_g50v_setup alc663_m51va_setup
18328
f1d4e28b
KY
18329static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18330 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18331 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18332
5f99f86a 18333 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18334 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18335 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18336
5f99f86a 18337 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18338 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18339 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18340 { } /* end */
18341};
18342
9541ba1d
CP
18343static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18344 /* Master Playback automatically created from Speaker and Headphone */
18345 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18346 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18347 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18348 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18349
8607f7c4
DH
18350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18351 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18352 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18353
28c4edb7
DH
18354 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18355 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18356 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18357 { } /* end */
18358};
18359
cb53c626
TI
18360#ifdef CONFIG_SND_HDA_POWER_SAVE
18361#define alc662_loopbacks alc880_loopbacks
18362#endif
18363
bc9f98a9 18364
def319f9 18365/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18366#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18367#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18368#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18369#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18370
18371/*
18372 * configuration and preset
18373 */
ea734963 18374static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18375 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18376 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18377 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 18378 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 18379 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18380 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18381 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18382 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18383 [ALC663_ASUS_M51VA] = "m51va",
18384 [ALC663_ASUS_G71V] = "g71v",
18385 [ALC663_ASUS_H13] = "h13",
18386 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18387 [ALC663_ASUS_MODE1] = "asus-mode1",
18388 [ALC662_ASUS_MODE2] = "asus-mode2",
18389 [ALC663_ASUS_MODE3] = "asus-mode3",
18390 [ALC663_ASUS_MODE4] = "asus-mode4",
18391 [ALC663_ASUS_MODE5] = "asus-mode5",
18392 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18393 [ALC663_ASUS_MODE7] = "asus-mode7",
18394 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18395 [ALC272_DELL] = "dell",
18396 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18397 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18398 [ALC662_AUTO] = "auto",
18399};
18400
18401static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18402 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18403 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18404 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18405 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18406 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18407 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18408 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18409 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18410 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18411 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18412 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18413 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18414 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18415 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18416 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18417 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18418 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18419 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18420 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18421 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18422 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18423 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18424 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18425 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18426 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18427 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18428 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18429 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18430 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18431 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18432 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18433 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18434 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18435 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18436 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18437 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18438 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18439 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18440 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18441 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18442 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18443 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18444 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18445 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18446 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18447 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18448 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18449 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18450 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18451 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18452 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18453 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18454 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18455 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18456 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18457 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18458 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18459 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18460 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18461 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18462 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18463 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18464 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18465 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18466 ALC662_3ST_6ch_DIG),
4dee8baa 18467 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18468 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
6227cdce 18469 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18470 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18471 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18472 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18473 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18474 ALC662_3ST_6ch_DIG),
dea0a509
TI
18475 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18476 ALC663_ASUS_H13),
965b76d2 18477 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18478 {}
18479};
18480
18481static struct alc_config_preset alc662_presets[] = {
18482 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18483 .mixers = { alc662_3ST_2ch_mixer },
a7f2371f 18484 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18485 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18486 .dac_nids = alc662_dac_nids,
18487 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18488 .dig_in_nid = ALC662_DIGIN_NID,
18489 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18490 .channel_mode = alc662_3ST_2ch_modes,
18491 .input_mux = &alc662_capture_source,
18492 },
18493 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18494 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18495 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18496 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18497 .dac_nids = alc662_dac_nids,
18498 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18499 .dig_in_nid = ALC662_DIGIN_NID,
18500 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18501 .channel_mode = alc662_3ST_6ch_modes,
18502 .need_dac_fix = 1,
18503 .input_mux = &alc662_capture_source,
f12ab1e0 18504 },
bc9f98a9 18505 [ALC662_3ST_6ch] = {
f9e336f6 18506 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18507 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18508 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18509 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18510 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18511 .channel_mode = alc662_3ST_6ch_modes,
18512 .need_dac_fix = 1,
18513 .input_mux = &alc662_capture_source,
f12ab1e0 18514 },
bc9f98a9 18515 [ALC662_5ST_DIG] = {
f9e336f6 18516 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
a7f2371f 18517 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18518 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18519 .dac_nids = alc662_dac_nids,
18520 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18521 .dig_in_nid = ALC662_DIGIN_NID,
18522 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18523 .channel_mode = alc662_5stack_modes,
18524 .input_mux = &alc662_capture_source,
18525 },
18526 [ALC662_LENOVO_101E] = {
f9e336f6 18527 .mixers = { alc662_lenovo_101e_mixer },
a7f2371f
TI
18528 .init_verbs = { alc662_init_verbs,
18529 alc662_eapd_init_verbs,
18530 alc662_sue_init_verbs },
bc9f98a9
KY
18531 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18532 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18533 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18534 .channel_mode = alc662_3ST_2ch_modes,
18535 .input_mux = &alc662_lenovo_101e_capture_source,
e6a5e1b7
TI
18536 .unsol_event = alc_sku_unsol_event,
18537 .setup = alc662_lenovo_101e_setup,
18538 .init_hook = alc_inithook,
bc9f98a9 18539 },
291702f0 18540 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18541 .mixers = { alc662_eeepc_p701_mixer },
291702f0 18542 .init_verbs = { alc662_init_verbs,
a7f2371f 18543 alc662_eapd_init_verbs,
291702f0
KY
18544 alc662_eeepc_sue_init_verbs },
18545 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18546 .dac_nids = alc662_dac_nids,
291702f0
KY
18547 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18548 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18549 .unsol_event = alc_sku_unsol_event,
4f5d1706 18550 .setup = alc662_eeepc_setup,
e9427969 18551 .init_hook = alc_inithook,
291702f0 18552 },
8c427226 18553 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18554 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18555 alc662_chmode_mixer },
18556 .init_verbs = { alc662_init_verbs,
a7f2371f 18557 alc662_eapd_init_verbs,
8c427226
KY
18558 alc662_eeepc_ep20_sue_init_verbs },
18559 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18560 .dac_nids = alc662_dac_nids,
8c427226
KY
18561 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18562 .channel_mode = alc662_3ST_6ch_modes,
18563 .input_mux = &alc662_lenovo_101e_capture_source,
e9427969 18564 .unsol_event = alc_sku_unsol_event,
4f5d1706 18565 .setup = alc662_eeepc_ep20_setup,
e9427969 18566 .init_hook = alc_inithook,
8c427226 18567 },
f1d4e28b 18568 [ALC662_ECS] = {
f9e336f6 18569 .mixers = { alc662_ecs_mixer },
f1d4e28b 18570 .init_verbs = { alc662_init_verbs,
a7f2371f 18571 alc662_eapd_init_verbs,
f1d4e28b
KY
18572 alc662_ecs_init_verbs },
18573 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18574 .dac_nids = alc662_dac_nids,
18575 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18576 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18577 .unsol_event = alc_sku_unsol_event,
4f5d1706 18578 .setup = alc662_eeepc_setup,
e9427969 18579 .init_hook = alc_inithook,
f1d4e28b 18580 },
6dda9f4a 18581 [ALC663_ASUS_M51VA] = {
f9e336f6 18582 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18583 .init_verbs = { alc662_init_verbs,
18584 alc662_eapd_init_verbs,
18585 alc663_m51va_init_verbs },
6dda9f4a
KY
18586 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18587 .dac_nids = alc662_dac_nids,
18588 .dig_out_nid = ALC662_DIGOUT_NID,
18589 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18590 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18591 .unsol_event = alc_sku_unsol_event,
4f5d1706 18592 .setup = alc663_m51va_setup,
3b8510ce 18593 .init_hook = alc_inithook,
6dda9f4a
KY
18594 },
18595 [ALC663_ASUS_G71V] = {
f9e336f6 18596 .mixers = { alc663_g71v_mixer },
a7f2371f
TI
18597 .init_verbs = { alc662_init_verbs,
18598 alc662_eapd_init_verbs,
18599 alc663_g71v_init_verbs },
6dda9f4a
KY
18600 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18601 .dac_nids = alc662_dac_nids,
18602 .dig_out_nid = ALC662_DIGOUT_NID,
18603 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18604 .channel_mode = alc662_3ST_2ch_modes,
e6a5e1b7 18605 .unsol_event = alc_sku_unsol_event,
4f5d1706 18606 .setup = alc663_g71v_setup,
e6a5e1b7 18607 .init_hook = alc_inithook,
6dda9f4a
KY
18608 },
18609 [ALC663_ASUS_H13] = {
f9e336f6 18610 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18611 .init_verbs = { alc662_init_verbs,
18612 alc662_eapd_init_verbs,
18613 alc663_m51va_init_verbs },
6dda9f4a
KY
18614 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18615 .dac_nids = alc662_dac_nids,
18616 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18617 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce
TI
18618 .setup = alc663_m51va_setup,
18619 .unsol_event = alc_sku_unsol_event,
18620 .init_hook = alc_inithook,
6dda9f4a
KY
18621 },
18622 [ALC663_ASUS_G50V] = {
f9e336f6 18623 .mixers = { alc663_g50v_mixer },
a7f2371f
TI
18624 .init_verbs = { alc662_init_verbs,
18625 alc662_eapd_init_verbs,
18626 alc663_g50v_init_verbs },
6dda9f4a
KY
18627 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18628 .dac_nids = alc662_dac_nids,
18629 .dig_out_nid = ALC662_DIGOUT_NID,
18630 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18631 .channel_mode = alc662_3ST_6ch_modes,
18632 .input_mux = &alc663_capture_source,
3b8510ce 18633 .unsol_event = alc_sku_unsol_event,
4f5d1706 18634 .setup = alc663_g50v_setup,
3b8510ce 18635 .init_hook = alc_inithook,
6dda9f4a 18636 },
f1d4e28b 18637 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18638 .mixers = { alc663_m51va_mixer },
18639 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18640 .init_verbs = { alc662_init_verbs,
a7f2371f 18641 alc662_eapd_init_verbs,
f1d4e28b
KY
18642 alc663_21jd_amic_init_verbs },
18643 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18644 .hp_nid = 0x03,
18645 .dac_nids = alc662_dac_nids,
18646 .dig_out_nid = ALC662_DIGOUT_NID,
18647 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18648 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18649 .unsol_event = alc_sku_unsol_event,
4f5d1706 18650 .setup = alc663_mode1_setup,
3b8510ce 18651 .init_hook = alc_inithook,
f1d4e28b
KY
18652 },
18653 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18654 .mixers = { alc662_1bjd_mixer },
18655 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18656 .init_verbs = { alc662_init_verbs,
a7f2371f 18657 alc662_eapd_init_verbs,
f1d4e28b
KY
18658 alc662_1bjd_amic_init_verbs },
18659 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18660 .dac_nids = alc662_dac_nids,
18661 .dig_out_nid = ALC662_DIGOUT_NID,
18662 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18663 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18664 .unsol_event = alc_sku_unsol_event,
4f5d1706 18665 .setup = alc662_mode2_setup,
3b8510ce 18666 .init_hook = alc_inithook,
f1d4e28b
KY
18667 },
18668 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18669 .mixers = { alc663_two_hp_m1_mixer },
18670 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18671 .init_verbs = { alc662_init_verbs,
a7f2371f 18672 alc662_eapd_init_verbs,
f1d4e28b
KY
18673 alc663_two_hp_amic_m1_init_verbs },
18674 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18675 .hp_nid = 0x03,
18676 .dac_nids = alc662_dac_nids,
18677 .dig_out_nid = ALC662_DIGOUT_NID,
18678 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18679 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18680 .unsol_event = alc_sku_unsol_event,
4f5d1706 18681 .setup = alc663_mode3_setup,
3b8510ce 18682 .init_hook = alc_inithook,
f1d4e28b
KY
18683 },
18684 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18685 .mixers = { alc663_asus_21jd_clfe_mixer },
18686 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18687 .init_verbs = { alc662_init_verbs,
a7f2371f 18688 alc662_eapd_init_verbs,
f1d4e28b
KY
18689 alc663_21jd_amic_init_verbs},
18690 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18691 .hp_nid = 0x03,
18692 .dac_nids = alc662_dac_nids,
18693 .dig_out_nid = ALC662_DIGOUT_NID,
18694 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18695 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18696 .unsol_event = alc_sku_unsol_event,
4f5d1706 18697 .setup = alc663_mode4_setup,
3b8510ce 18698 .init_hook = alc_inithook,
f1d4e28b
KY
18699 },
18700 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18701 .mixers = { alc663_asus_15jd_clfe_mixer },
18702 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18703 .init_verbs = { alc662_init_verbs,
a7f2371f 18704 alc662_eapd_init_verbs,
f1d4e28b
KY
18705 alc663_15jd_amic_init_verbs },
18706 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18707 .hp_nid = 0x03,
18708 .dac_nids = alc662_dac_nids,
18709 .dig_out_nid = ALC662_DIGOUT_NID,
18710 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18711 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18712 .unsol_event = alc_sku_unsol_event,
4f5d1706 18713 .setup = alc663_mode5_setup,
3b8510ce 18714 .init_hook = alc_inithook,
f1d4e28b
KY
18715 },
18716 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18717 .mixers = { alc663_two_hp_m2_mixer },
18718 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18719 .init_verbs = { alc662_init_verbs,
a7f2371f 18720 alc662_eapd_init_verbs,
f1d4e28b
KY
18721 alc663_two_hp_amic_m2_init_verbs },
18722 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18723 .hp_nid = 0x03,
18724 .dac_nids = alc662_dac_nids,
18725 .dig_out_nid = ALC662_DIGOUT_NID,
18726 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18727 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18728 .unsol_event = alc_sku_unsol_event,
4f5d1706 18729 .setup = alc663_mode6_setup,
3b8510ce 18730 .init_hook = alc_inithook,
f1d4e28b 18731 },
ebb83eeb
KY
18732 [ALC663_ASUS_MODE7] = {
18733 .mixers = { alc663_mode7_mixer },
18734 .cap_mixer = alc662_auto_capture_mixer,
18735 .init_verbs = { alc662_init_verbs,
a7f2371f 18736 alc662_eapd_init_verbs,
ebb83eeb
KY
18737 alc663_mode7_init_verbs },
18738 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18739 .hp_nid = 0x03,
18740 .dac_nids = alc662_dac_nids,
18741 .dig_out_nid = ALC662_DIGOUT_NID,
18742 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18743 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18744 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18745 .setup = alc663_mode7_setup,
3b8510ce 18746 .init_hook = alc_inithook,
ebb83eeb
KY
18747 },
18748 [ALC663_ASUS_MODE8] = {
18749 .mixers = { alc663_mode8_mixer },
18750 .cap_mixer = alc662_auto_capture_mixer,
18751 .init_verbs = { alc662_init_verbs,
a7f2371f 18752 alc662_eapd_init_verbs,
ebb83eeb
KY
18753 alc663_mode8_init_verbs },
18754 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18755 .hp_nid = 0x03,
18756 .dac_nids = alc662_dac_nids,
18757 .dig_out_nid = ALC662_DIGOUT_NID,
18758 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18759 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18760 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18761 .setup = alc663_mode8_setup,
3b8510ce 18762 .init_hook = alc_inithook,
ebb83eeb 18763 },
622e84cd
KY
18764 [ALC272_DELL] = {
18765 .mixers = { alc663_m51va_mixer },
18766 .cap_mixer = alc272_auto_capture_mixer,
a7f2371f
TI
18767 .init_verbs = { alc662_init_verbs,
18768 alc662_eapd_init_verbs,
18769 alc272_dell_init_verbs },
622e84cd 18770 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18771 .dac_nids = alc272_dac_nids,
622e84cd
KY
18772 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18773 .adc_nids = alc272_adc_nids,
18774 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18775 .capsrc_nids = alc272_capsrc_nids,
18776 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18777 .unsol_event = alc_sku_unsol_event,
4f5d1706 18778 .setup = alc663_m51va_setup,
3b8510ce 18779 .init_hook = alc_inithook,
622e84cd
KY
18780 },
18781 [ALC272_DELL_ZM1] = {
18782 .mixers = { alc663_m51va_mixer },
18783 .cap_mixer = alc662_auto_capture_mixer,
a7f2371f
TI
18784 .init_verbs = { alc662_init_verbs,
18785 alc662_eapd_init_verbs,
18786 alc272_dell_zm1_init_verbs },
622e84cd 18787 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18788 .dac_nids = alc272_dac_nids,
622e84cd
KY
18789 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18790 .adc_nids = alc662_adc_nids,
b59bdf3b 18791 .num_adc_nids = 1,
622e84cd
KY
18792 .capsrc_nids = alc662_capsrc_nids,
18793 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18794 .unsol_event = alc_sku_unsol_event,
4f5d1706 18795 .setup = alc663_m51va_setup,
3b8510ce 18796 .init_hook = alc_inithook,
622e84cd 18797 },
9541ba1d
CP
18798 [ALC272_SAMSUNG_NC10] = {
18799 .mixers = { alc272_nc10_mixer },
18800 .init_verbs = { alc662_init_verbs,
a7f2371f 18801 alc662_eapd_init_verbs,
9541ba1d
CP
18802 alc663_21jd_amic_init_verbs },
18803 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18804 .dac_nids = alc272_dac_nids,
18805 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18806 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18807 /*.input_mux = &alc272_nc10_capture_source,*/
3b8510ce 18808 .unsol_event = alc_sku_unsol_event,
4f5d1706 18809 .setup = alc663_mode4_setup,
3b8510ce 18810 .init_hook = alc_inithook,
9541ba1d 18811 },
bc9f98a9
KY
18812};
18813
18814
18815/*
18816 * BIOS auto configuration
18817 */
18818
7085ec12 18819/* convert from MIX nid to DAC */
604401a9 18820static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
1304ac89 18821{
604401a9 18822 hda_nid_t list[5];
1304ac89
TI
18823 int i, num;
18824
18825 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18826 for (i = 0; i < num; i++) {
18827 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18828 return list[i];
18829 }
18830 return 0;
7085ec12
TI
18831}
18832
604401a9
TI
18833/* go down to the selector widget before the mixer */
18834static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18835{
18836 hda_nid_t srcs[5];
18837 int num = snd_hda_get_connections(codec, pin, srcs,
18838 ARRAY_SIZE(srcs));
18839 if (num != 1 ||
18840 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18841 return pin;
18842 return srcs[0];
18843}
18844
7085ec12 18845/* get MIX nid connected to the given pin targeted to DAC */
604401a9 18846static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
7085ec12
TI
18847 hda_nid_t dac)
18848{
cc1c452e 18849 hda_nid_t mix[5];
7085ec12
TI
18850 int i, num;
18851
604401a9 18852 pin = alc_go_down_to_selector(codec, pin);
7085ec12
TI
18853 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18854 for (i = 0; i < num; i++) {
604401a9 18855 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
18856 return mix[i];
18857 }
18858 return 0;
18859}
18860
ce764ab2
TI
18861/* select the connection from pin to DAC if needed */
18862static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18863 hda_nid_t dac)
18864{
18865 hda_nid_t mix[5];
18866 int i, num;
18867
18868 pin = alc_go_down_to_selector(codec, pin);
18869 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18870 if (num < 2)
18871 return 0;
18872 for (i = 0; i < num; i++) {
18873 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18874 snd_hda_codec_update_cache(codec, pin, 0,
18875 AC_VERB_SET_CONNECT_SEL, i);
18876 return 0;
18877 }
18878 }
18879 return 0;
18880}
18881
7085ec12 18882/* look for an empty DAC slot */
604401a9 18883static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
7085ec12
TI
18884{
18885 struct alc_spec *spec = codec->spec;
18886 hda_nid_t srcs[5];
18887 int i, j, num;
18888
604401a9 18889 pin = alc_go_down_to_selector(codec, pin);
7085ec12 18890 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
7085ec12 18891 for (i = 0; i < num; i++) {
604401a9 18892 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
7085ec12
TI
18893 if (!nid)
18894 continue;
18895 for (j = 0; j < spec->multiout.num_dacs; j++)
18896 if (spec->multiout.dac_nids[j] == nid)
18897 break;
18898 if (j >= spec->multiout.num_dacs)
18899 return nid;
18900 }
18901 return 0;
18902}
18903
18904/* fill in the dac_nids table from the parsed pin configuration */
18905static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18906 const struct auto_pin_cfg *cfg)
18907{
18908 struct alc_spec *spec = codec->spec;
18909 int i;
18910 hda_nid_t dac;
18911
18912 spec->multiout.dac_nids = spec->private_dac_nids;
18913 for (i = 0; i < cfg->line_outs; i++) {
604401a9 18914 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
7085ec12
TI
18915 if (!dac)
18916 continue;
18917 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18918 }
18919 return 0;
18920}
18921
bcb2f0f5
TI
18922static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18923 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18924{
bcb2f0f5 18925 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
18926 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18927}
18928
bcb2f0f5
TI
18929static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18930 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18931{
bcb2f0f5 18932 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
18933 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18934}
18935
bcb2f0f5
TI
18936#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
18937 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
18938#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
18939 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
18940#define alc662_add_stereo_vol(spec, pfx, nid) \
18941 alc662_add_vol_ctl(spec, pfx, nid, 3)
18942#define alc662_add_stereo_sw(spec, pfx, nid) \
18943 alc662_add_sw_ctl(spec, pfx, nid, 3)
18944
bc9f98a9 18945/* add playback controls from the parsed DAC table */
7085ec12 18946static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18947 const struct auto_pin_cfg *cfg)
18948{
7085ec12 18949 struct alc_spec *spec = codec->spec;
ea734963 18950 static const char * const chname[4] = {
bc9f98a9
KY
18951 "Front", "Surround", NULL /*CLFE*/, "Side"
18952 };
ce764ab2
TI
18953 const char *pfx = alc_get_line_out_pfx(spec, true);
18954 hda_nid_t nid, mix, pin;
18955 int i, err, noutputs;
bc9f98a9 18956
ce764ab2
TI
18957 noutputs = cfg->line_outs;
18958 if (spec->multi_ios > 0)
18959 noutputs += spec->multi_ios;
18960
18961 for (i = 0; i < noutputs; i++) {
7085ec12
TI
18962 nid = spec->multiout.dac_nids[i];
18963 if (!nid)
18964 continue;
ce764ab2
TI
18965 if (i >= cfg->line_outs)
18966 pin = spec->multi_io[i - 1].pin;
18967 else
18968 pin = cfg->line_out_pins[i];
18969 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12 18970 if (!mix)
bc9f98a9 18971 continue;
bcb2f0f5 18972 if (!pfx && i == 2) {
bc9f98a9 18973 /* Center/LFE */
7085ec12 18974 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18975 if (err < 0)
18976 return err;
7085ec12 18977 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18978 if (err < 0)
18979 return err;
7085ec12 18980 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18981 if (err < 0)
18982 return err;
7085ec12 18983 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18984 if (err < 0)
18985 return err;
18986 } else {
bcb2f0f5 18987 const char *name = pfx;
5a882646
DH
18988 int index = i;
18989 if (!name) {
bcb2f0f5 18990 name = chname[i];
5a882646
DH
18991 index = 0;
18992 }
18993 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
bc9f98a9
KY
18994 if (err < 0)
18995 return err;
5a882646 18996 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
bc9f98a9
KY
18997 if (err < 0)
18998 return err;
18999 }
19000 }
19001 return 0;
19002}
19003
19004/* add playback controls for speaker and HP outputs */
7085ec12
TI
19005/* return DAC nid if any new DAC is assigned */
19006static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19007 const char *pfx)
19008{
7085ec12
TI
19009 struct alc_spec *spec = codec->spec;
19010 hda_nid_t nid, mix;
bc9f98a9 19011 int err;
bc9f98a9
KY
19012
19013 if (!pin)
19014 return 0;
604401a9 19015 nid = alc_auto_look_for_dac(codec, pin);
7085ec12 19016 if (!nid) {
7085ec12
TI
19017 /* the corresponding DAC is already occupied */
19018 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19019 return 0; /* no way */
19020 /* create a switch only */
0afe5f89 19021 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19022 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19023 }
19024
604401a9 19025 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12
TI
19026 if (!mix)
19027 return 0;
19028 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19029 if (err < 0)
19030 return err;
19031 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19032 if (err < 0)
19033 return err;
19034 return nid;
bc9f98a9
KY
19035}
19036
19037/* create playback/capture controls for input pins */
05f5f477 19038#define alc662_auto_create_input_ctls \
4b7348a1 19039 alc882_auto_create_input_ctls
bc9f98a9
KY
19040
19041static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19042 hda_nid_t nid, int pin_type,
7085ec12 19043 hda_nid_t dac)
bc9f98a9 19044{
7085ec12 19045 int i, num;
ce503f38 19046 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19047
f6c7e546 19048 alc_set_pin_output(codec, nid, pin_type);
7085ec12 19049 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
7085ec12 19050 for (i = 0; i < num; i++) {
604401a9 19051 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
7085ec12 19052 continue;
0e53f344
TI
19053 /* need the manual connection? */
19054 if (num > 1)
19055 snd_hda_codec_write(codec, nid, 0,
19056 AC_VERB_SET_CONNECT_SEL, i);
19057 /* unmute mixer widget inputs */
19058 snd_hda_codec_write(codec, srcs[i], 0,
19059 AC_VERB_SET_AMP_GAIN_MUTE,
19060 AMP_IN_UNMUTE(0));
19061 snd_hda_codec_write(codec, srcs[i], 0,
19062 AC_VERB_SET_AMP_GAIN_MUTE,
19063 AMP_IN_UNMUTE(1));
7085ec12 19064 return;
bc9f98a9
KY
19065 }
19066}
19067
19068static void alc662_auto_init_multi_out(struct hda_codec *codec)
19069{
19070 struct alc_spec *spec = codec->spec;
7085ec12 19071 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19072 int i;
19073
19074 for (i = 0; i <= HDA_SIDE; i++) {
19075 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19076 if (nid)
baba8ee9 19077 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19078 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19079 }
19080}
19081
19082static void alc662_auto_init_hp_out(struct hda_codec *codec)
19083{
19084 struct alc_spec *spec = codec->spec;
19085 hda_nid_t pin;
19086
19087 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19088 if (pin)
19089 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19090 spec->multiout.hp_nid);
f6c7e546
TI
19091 pin = spec->autocfg.speaker_pins[0];
19092 if (pin)
7085ec12
TI
19093 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19094 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19095}
19096
bc9f98a9
KY
19097#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19098
19099static void alc662_auto_init_analog_input(struct hda_codec *codec)
19100{
19101 struct alc_spec *spec = codec->spec;
66ceeb6b 19102 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19103 int i;
19104
66ceeb6b
TI
19105 for (i = 0; i < cfg->num_inputs; i++) {
19106 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19107 if (alc_is_input_pin(codec, nid)) {
30ea098f 19108 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19109 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19110 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19111 snd_hda_codec_write(codec, nid, 0,
19112 AC_VERB_SET_AMP_GAIN_MUTE,
19113 AMP_OUT_MUTE);
19114 }
19115 }
19116}
19117
f511b01c
TI
19118#define alc662_auto_init_input_src alc882_auto_init_input_src
19119
ce764ab2
TI
19120/*
19121 * multi-io helper
19122 */
19123static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19124 unsigned int location)
19125{
19126 struct alc_spec *spec = codec->spec;
19127 struct auto_pin_cfg *cfg = &spec->autocfg;
19128 int type, i, num_pins = 0;
19129
19130 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19131 for (i = 0; i < cfg->num_inputs; i++) {
19132 hda_nid_t nid = cfg->inputs[i].pin;
19133 hda_nid_t dac;
19134 unsigned int defcfg, caps;
19135 if (cfg->inputs[i].type != type)
19136 continue;
19137 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19138 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19139 continue;
19140 if (location && get_defcfg_location(defcfg) != location)
19141 continue;
19142 caps = snd_hda_query_pin_caps(codec, nid);
19143 if (!(caps & AC_PINCAP_OUT))
19144 continue;
19145 dac = alc_auto_look_for_dac(codec, nid);
19146 if (!dac)
19147 continue;
19148 spec->multi_io[num_pins].pin = nid;
19149 spec->multi_io[num_pins].dac = dac;
19150 num_pins++;
19151 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19152 }
19153 }
19154 spec->multiout.num_dacs = 1;
19155 if (num_pins < 2)
19156 return 0;
19157 return num_pins;
19158}
19159
19160static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19161 struct snd_ctl_elem_info *uinfo)
19162{
19163 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19164 struct alc_spec *spec = codec->spec;
19165
19166 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19167 uinfo->count = 1;
19168 uinfo->value.enumerated.items = spec->multi_ios + 1;
19169 if (uinfo->value.enumerated.item > spec->multi_ios)
19170 uinfo->value.enumerated.item = spec->multi_ios;
19171 sprintf(uinfo->value.enumerated.name, "%dch",
19172 (uinfo->value.enumerated.item + 1) * 2);
19173 return 0;
19174}
19175
19176static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19177 struct snd_ctl_elem_value *ucontrol)
19178{
19179 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19180 struct alc_spec *spec = codec->spec;
19181 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19182 return 0;
19183}
19184
19185static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19186{
19187 struct alc_spec *spec = codec->spec;
19188 hda_nid_t nid = spec->multi_io[idx].pin;
19189
19190 if (!spec->multi_io[idx].ctl_in)
19191 spec->multi_io[idx].ctl_in =
19192 snd_hda_codec_read(codec, nid, 0,
19193 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19194 if (output) {
19195 snd_hda_codec_update_cache(codec, nid, 0,
19196 AC_VERB_SET_PIN_WIDGET_CONTROL,
19197 PIN_OUT);
19198 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19199 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19200 HDA_AMP_MUTE, 0);
19201 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19202 } else {
19203 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19204 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19205 HDA_AMP_MUTE, HDA_AMP_MUTE);
19206 snd_hda_codec_update_cache(codec, nid, 0,
19207 AC_VERB_SET_PIN_WIDGET_CONTROL,
19208 spec->multi_io[idx].ctl_in);
19209 }
19210 return 0;
19211}
19212
19213static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19214 struct snd_ctl_elem_value *ucontrol)
19215{
19216 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19217 struct alc_spec *spec = codec->spec;
19218 int i, ch;
19219
19220 ch = ucontrol->value.enumerated.item[0];
19221 if (ch < 0 || ch > spec->multi_ios)
19222 return -EINVAL;
19223 if (ch == (spec->ext_channel_count - 1) / 2)
19224 return 0;
19225 spec->ext_channel_count = (ch + 1) * 2;
19226 for (i = 0; i < spec->multi_ios; i++)
19227 alc_set_multi_io(codec, i, i < ch);
19228 spec->multiout.max_channels = spec->ext_channel_count;
19229 return 1;
19230}
19231
19232static struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19234 .name = "Channel Mode",
19235 .info = alc_auto_ch_mode_info,
19236 .get = alc_auto_ch_mode_get,
19237 .put = alc_auto_ch_mode_put,
19238};
19239
19240static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19241{
19242 struct alc_spec *spec = codec->spec;
19243 struct auto_pin_cfg *cfg = &spec->autocfg;
19244 unsigned int location, defcfg;
19245 int num_pins;
19246
19247 if (cfg->line_outs != 1 ||
19248 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19249 return 0;
19250
19251 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19252 location = get_defcfg_location(defcfg);
19253
19254 num_pins = alc_auto_fill_multi_ios(codec, location);
19255 if (num_pins > 0) {
19256 struct snd_kcontrol_new *knew;
19257
19258 knew = alc_kcontrol_new(spec);
19259 if (!knew)
19260 return -ENOMEM;
19261 *knew = alc_auto_channel_mode_enum;
19262 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19263 if (!knew->name)
19264 return -ENOMEM;
19265
19266 spec->multi_ios = num_pins;
19267 spec->ext_channel_count = 2;
19268 spec->multiout.num_dacs = num_pins + 1;
19269 }
19270 return 0;
19271}
19272
bc9f98a9
KY
19273static int alc662_parse_auto_config(struct hda_codec *codec)
19274{
19275 struct alc_spec *spec = codec->spec;
19276 int err;
19277 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19278
19279 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19280 alc662_ignore);
19281 if (err < 0)
19282 return err;
19283 if (!spec->autocfg.line_outs)
19284 return 0; /* can't find valid BIOS pin config */
19285
7085ec12 19286 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
19287 if (err < 0)
19288 return err;
19289 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
19290 if (err < 0)
19291 return err;
7085ec12 19292 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19293 if (err < 0)
19294 return err;
7085ec12 19295 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19296 spec->autocfg.speaker_pins[0],
19297 "Speaker");
19298 if (err < 0)
19299 return err;
7085ec12
TI
19300 if (err)
19301 spec->multiout.extra_out_nid[0] = err;
19302 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19303 "Headphone");
19304 if (err < 0)
19305 return err;
7085ec12
TI
19306 if (err)
19307 spec->multiout.hp_nid = err;
05f5f477 19308 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19309 if (err < 0)
bc9f98a9
KY
19310 return err;
19311
19312 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19313
757899ac 19314 alc_auto_parse_digital(codec);
bc9f98a9 19315
603c4019 19316 if (spec->kctls.list)
d88897ea 19317 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19318
19319 spec->num_mux_defs = 1;
61b9b9b1 19320 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19321
ee979a14
TI
19322 err = alc_auto_add_mic_boost(codec);
19323 if (err < 0)
19324 return err;
19325
6227cdce
KY
19326 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19327 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19328 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19329 else
19330 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19331
8c87286f 19332 return 1;
bc9f98a9
KY
19333}
19334
19335/* additional initialization for auto-configuration model */
19336static void alc662_auto_init(struct hda_codec *codec)
19337{
f6c7e546 19338 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19339 alc662_auto_init_multi_out(codec);
19340 alc662_auto_init_hp_out(codec);
19341 alc662_auto_init_analog_input(codec);
f511b01c 19342 alc662_auto_init_input_src(codec);
757899ac 19343 alc_auto_init_digital(codec);
f6c7e546 19344 if (spec->unsol_event)
7fb0d78f 19345 alc_inithook(codec);
bc9f98a9
KY
19346}
19347
6be7948f 19348static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19349 const struct alc_fixup *fix, int action)
6fc398cb 19350{
b5bfbc67 19351 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19352 return;
6be7948f
TB
19353 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19354 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19355 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19356 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19357 (0 << AC_AMPCAP_MUTE_SHIFT)))
19358 printk(KERN_WARNING
19359 "hda_codec: failed to override amp caps for NID 0x2\n");
19360}
19361
6cb3b707 19362enum {
2df03514 19363 ALC662_FIXUP_ASPIRE,
6cb3b707 19364 ALC662_FIXUP_IDEAPAD,
6be7948f 19365 ALC272_FIXUP_MARIO,
d2ebd479 19366 ALC662_FIXUP_CZC_P10T,
c6b35874 19367 ALC662_FIXUP_GIGABYTE,
6cb3b707
DH
19368};
19369
19370static const struct alc_fixup alc662_fixups[] = {
2df03514 19371 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19372 .type = ALC_FIXUP_PINS,
19373 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19374 { 0x15, 0x99130112 }, /* subwoofer */
19375 { }
19376 }
19377 },
6cb3b707 19378 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19379 .type = ALC_FIXUP_PINS,
19380 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19381 { 0x17, 0x99130112 }, /* subwoofer */
19382 { }
19383 }
19384 },
6be7948f 19385 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19386 .type = ALC_FIXUP_FUNC,
19387 .v.func = alc272_fixup_mario,
d2ebd479
AA
19388 },
19389 [ALC662_FIXUP_CZC_P10T] = {
19390 .type = ALC_FIXUP_VERBS,
19391 .v.verbs = (const struct hda_verb[]) {
19392 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19393 {}
19394 }
19395 },
c6b35874
TI
19396 [ALC662_FIXUP_GIGABYTE] = {
19397 .type = ALC_FIXUP_PINS,
19398 .v.pins = (const struct alc_pincfg[]) {
19399 { 0x14, 0x1114410 }, /* set as speaker */
19400 { }
19401 }
19402 },
6cb3b707
DH
19403};
19404
19405static struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19406 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
2df03514 19407 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19408 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
c6b35874 19409 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE),
d4118588 19410 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19411 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19412 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19413 {}
19414};
19415
6be7948f
TB
19416static const struct alc_model_fixup alc662_fixup_models[] = {
19417 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19418 {}
19419};
6cb3b707
DH
19420
19421
bc9f98a9
KY
19422static int patch_alc662(struct hda_codec *codec)
19423{
19424 struct alc_spec *spec;
19425 int err, board_config;
693194f3 19426 int coef;
bc9f98a9
KY
19427
19428 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19429 if (!spec)
19430 return -ENOMEM;
19431
19432 codec->spec = spec;
19433
da00c244
KY
19434 alc_auto_parse_customize_define(codec);
19435
2c3bf9ab
TI
19436 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19437
693194f3
KY
19438 coef = alc_read_coef_idx(codec, 0);
19439 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19440 alc_codec_rename(codec, "ALC661");
693194f3
KY
19441 else if (coef & (1 << 14) &&
19442 codec->bus->pci->subsystem_vendor == 0x1025 &&
19443 spec->cdefine.platform_type == 1)
c027ddcd 19444 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19445 else if (coef == 0x4011)
19446 alc_codec_rename(codec, "ALC656");
274693f3 19447
bc9f98a9
KY
19448 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19449 alc662_models,
19450 alc662_cfg_tbl);
19451 if (board_config < 0) {
9a11f1aa
TI
19452 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19453 codec->chip_name);
bc9f98a9
KY
19454 board_config = ALC662_AUTO;
19455 }
19456
19457 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19458 alc_pick_fixup(codec, alc662_fixup_models,
19459 alc662_fixup_tbl, alc662_fixups);
19460 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19461 /* automatic parse from the BIOS config */
19462 err = alc662_parse_auto_config(codec);
19463 if (err < 0) {
19464 alc_free(codec);
19465 return err;
8c87286f 19466 } else if (!err) {
bc9f98a9
KY
19467 printk(KERN_INFO
19468 "hda_codec: Cannot set up configuration "
19469 "from BIOS. Using base mode...\n");
19470 board_config = ALC662_3ST_2ch_DIG;
19471 }
19472 }
19473
dc1eae25 19474 if (has_cdefine_beep(codec)) {
8af2591d
TI
19475 err = snd_hda_attach_beep_device(codec, 0x1);
19476 if (err < 0) {
19477 alc_free(codec);
19478 return err;
19479 }
680cd536
KK
19480 }
19481
bc9f98a9 19482 if (board_config != ALC662_AUTO)
e9c364c0 19483 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19484
bc9f98a9
KY
19485 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19486 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19487
bc9f98a9
KY
19488 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19489 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19490
dd704698
TI
19491 if (!spec->adc_nids) {
19492 spec->adc_nids = alc662_adc_nids;
19493 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19494 }
19495 if (!spec->capsrc_nids)
19496 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19497
f9e336f6 19498 if (!spec->cap_mixer)
b59bdf3b 19499 set_capture_mixer(codec);
cec27c89 19500
dc1eae25 19501 if (has_cdefine_beep(codec)) {
da00c244
KY
19502 switch (codec->vendor_id) {
19503 case 0x10ec0662:
19504 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19505 break;
19506 case 0x10ec0272:
19507 case 0x10ec0663:
19508 case 0x10ec0665:
19509 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19510 break;
19511 case 0x10ec0273:
19512 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19513 break;
19514 }
cec27c89 19515 }
2134ea4f
TI
19516 spec->vmaster_nid = 0x02;
19517
b5bfbc67
TI
19518 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19519
bc9f98a9 19520 codec->patch_ops = alc_patch_ops;
b5bfbc67 19521 if (board_config == ALC662_AUTO)
bc9f98a9 19522 spec->init_hook = alc662_auto_init;
1c716153 19523 spec->shutup = alc_eapd_shutup;
6cb3b707 19524
bf1b0225
KY
19525 alc_init_jacks(codec);
19526
cb53c626
TI
19527#ifdef CONFIG_SND_HDA_POWER_SAVE
19528 if (!spec->loopback.amplist)
19529 spec->loopback.amplist = alc662_loopbacks;
19530#endif
bc9f98a9
KY
19531
19532 return 0;
19533}
19534
274693f3
KY
19535static int patch_alc888(struct hda_codec *codec)
19536{
19537 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19538 kfree(codec->chip_name);
01e0f137
KY
19539 if (codec->vendor_id == 0x10ec0887)
19540 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19541 else
19542 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19543 if (!codec->chip_name) {
19544 alc_free(codec);
274693f3 19545 return -ENOMEM;
ac2c92e0
TI
19546 }
19547 return patch_alc662(codec);
274693f3 19548 }
ac2c92e0 19549 return patch_alc882(codec);
274693f3
KY
19550}
19551
d1eb57f4
KY
19552/*
19553 * ALC680 support
19554 */
c69aefab 19555#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19556#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19557#define alc680_modes alc260_modes
19558
19559static hda_nid_t alc680_dac_nids[3] = {
19560 /* Lout1, Lout2, hp */
19561 0x02, 0x03, 0x04
19562};
19563
19564static hda_nid_t alc680_adc_nids[3] = {
19565 /* ADC0-2 */
19566 /* DMIC, MIC, Line-in*/
19567 0x07, 0x08, 0x09
19568};
19569
c69aefab
KY
19570/*
19571 * Analog capture ADC cgange
19572 */
66ceeb6b
TI
19573static void alc680_rec_autoswitch(struct hda_codec *codec)
19574{
19575 struct alc_spec *spec = codec->spec;
19576 struct auto_pin_cfg *cfg = &spec->autocfg;
19577 int pin_found = 0;
19578 int type_found = AUTO_PIN_LAST;
19579 hda_nid_t nid;
19580 int i;
19581
19582 for (i = 0; i < cfg->num_inputs; i++) {
19583 nid = cfg->inputs[i].pin;
19584 if (!(snd_hda_query_pin_caps(codec, nid) &
19585 AC_PINCAP_PRES_DETECT))
19586 continue;
19587 if (snd_hda_jack_detect(codec, nid)) {
19588 if (cfg->inputs[i].type < type_found) {
19589 type_found = cfg->inputs[i].type;
19590 pin_found = nid;
19591 }
19592 }
19593 }
19594
19595 nid = 0x07;
19596 if (pin_found)
19597 snd_hda_get_connections(codec, pin_found, &nid, 1);
19598
19599 if (nid != spec->cur_adc)
19600 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19601 spec->cur_adc = nid;
19602 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19603 spec->cur_adc_format);
19604}
19605
c69aefab
KY
19606static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19607 struct hda_codec *codec,
19608 unsigned int stream_tag,
19609 unsigned int format,
19610 struct snd_pcm_substream *substream)
19611{
19612 struct alc_spec *spec = codec->spec;
c69aefab 19613
66ceeb6b 19614 spec->cur_adc = 0x07;
c69aefab
KY
19615 spec->cur_adc_stream_tag = stream_tag;
19616 spec->cur_adc_format = format;
19617
66ceeb6b 19618 alc680_rec_autoswitch(codec);
c69aefab
KY
19619 return 0;
19620}
19621
19622static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19623 struct hda_codec *codec,
19624 struct snd_pcm_substream *substream)
19625{
19626 snd_hda_codec_cleanup_stream(codec, 0x07);
19627 snd_hda_codec_cleanup_stream(codec, 0x08);
19628 snd_hda_codec_cleanup_stream(codec, 0x09);
19629 return 0;
19630}
19631
19632static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19633 .substreams = 1, /* can be overridden */
19634 .channels_min = 2,
19635 .channels_max = 2,
19636 /* NID is set in alc_build_pcms */
19637 .ops = {
19638 .prepare = alc680_capture_pcm_prepare,
19639 .cleanup = alc680_capture_pcm_cleanup
19640 },
19641};
19642
d1eb57f4
KY
19643static struct snd_kcontrol_new alc680_base_mixer[] = {
19644 /* output mixer control */
19645 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19646 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19647 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19648 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19649 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19650 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19651 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19652 { }
19653};
19654
c69aefab
KY
19655static struct hda_bind_ctls alc680_bind_cap_vol = {
19656 .ops = &snd_hda_bind_vol,
19657 .values = {
19658 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19659 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19660 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19661 0
19662 },
19663};
19664
19665static struct hda_bind_ctls alc680_bind_cap_switch = {
19666 .ops = &snd_hda_bind_sw,
19667 .values = {
19668 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19669 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19670 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19671 0
19672 },
19673};
19674
19675static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19676 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19677 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19678 { } /* end */
19679};
19680
19681/*
19682 * generic initialization of ADC, input mixers and output mixers
19683 */
19684static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19685 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19686 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19687 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19688
c69aefab
KY
19689 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19690 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19691 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19692 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19693 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19694 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19695
19696 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19697 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19698 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19699 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19700 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19701
19702 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19703 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19704 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19705
d1eb57f4
KY
19706 { }
19707};
19708
c69aefab
KY
19709/* toggle speaker-output according to the hp-jack state */
19710static void alc680_base_setup(struct hda_codec *codec)
19711{
19712 struct alc_spec *spec = codec->spec;
19713
19714 spec->autocfg.hp_pins[0] = 0x16;
19715 spec->autocfg.speaker_pins[0] = 0x14;
19716 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19717 spec->autocfg.num_inputs = 2;
19718 spec->autocfg.inputs[0].pin = 0x18;
19719 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19720 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19721 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
d922b51d
TI
19722 spec->automute = 1;
19723 spec->automute_mode = ALC_AUTOMUTE_AMP;
c69aefab
KY
19724}
19725
19726static void alc680_unsol_event(struct hda_codec *codec,
19727 unsigned int res)
19728{
19729 if ((res >> 26) == ALC880_HP_EVENT)
d922b51d 19730 alc_hp_automute(codec);
c69aefab
KY
19731 if ((res >> 26) == ALC880_MIC_EVENT)
19732 alc680_rec_autoswitch(codec);
19733}
19734
19735static void alc680_inithook(struct hda_codec *codec)
19736{
d922b51d 19737 alc_hp_automute(codec);
c69aefab
KY
19738 alc680_rec_autoswitch(codec);
19739}
19740
d1eb57f4
KY
19741/* create input playback/capture controls for the given pin */
19742static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19743 const char *ctlname, int idx)
19744{
19745 hda_nid_t dac;
19746 int err;
19747
19748 switch (nid) {
19749 case 0x14:
19750 dac = 0x02;
19751 break;
19752 case 0x15:
19753 dac = 0x03;
19754 break;
19755 case 0x16:
19756 dac = 0x04;
19757 break;
19758 default:
19759 return 0;
19760 }
19761 if (spec->multiout.dac_nids[0] != dac &&
19762 spec->multiout.dac_nids[1] != dac) {
19763 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19764 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19765 HDA_OUTPUT));
19766 if (err < 0)
19767 return err;
19768
19769 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19770 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19771
19772 if (err < 0)
19773 return err;
19774 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19775 }
19776
19777 return 0;
19778}
19779
19780/* add playback controls from the parsed DAC table */
19781static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19782 const struct auto_pin_cfg *cfg)
19783{
19784 hda_nid_t nid;
19785 int err;
19786
19787 spec->multiout.dac_nids = spec->private_dac_nids;
19788
19789 nid = cfg->line_out_pins[0];
19790 if (nid) {
19791 const char *name;
19792 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19793 name = "Speaker";
19794 else
19795 name = "Front";
19796 err = alc680_new_analog_output(spec, nid, name, 0);
19797 if (err < 0)
19798 return err;
19799 }
19800
19801 nid = cfg->speaker_pins[0];
19802 if (nid) {
19803 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19804 if (err < 0)
19805 return err;
19806 }
19807 nid = cfg->hp_pins[0];
19808 if (nid) {
19809 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19810 if (err < 0)
19811 return err;
19812 }
19813
19814 return 0;
19815}
19816
19817static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19818 hda_nid_t nid, int pin_type)
19819{
19820 alc_set_pin_output(codec, nid, pin_type);
19821}
19822
19823static void alc680_auto_init_multi_out(struct hda_codec *codec)
19824{
19825 struct alc_spec *spec = codec->spec;
19826 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19827 if (nid) {
19828 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19829 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19830 }
19831}
19832
19833static void alc680_auto_init_hp_out(struct hda_codec *codec)
19834{
19835 struct alc_spec *spec = codec->spec;
19836 hda_nid_t pin;
19837
19838 pin = spec->autocfg.hp_pins[0];
19839 if (pin)
19840 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19841 pin = spec->autocfg.speaker_pins[0];
19842 if (pin)
19843 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19844}
19845
19846/* pcm configuration: identical with ALC880 */
19847#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19848#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19849#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19850#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19851#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19852
19853/*
19854 * BIOS auto configuration
19855 */
19856static int alc680_parse_auto_config(struct hda_codec *codec)
19857{
19858 struct alc_spec *spec = codec->spec;
19859 int err;
19860 static hda_nid_t alc680_ignore[] = { 0 };
19861
19862 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19863 alc680_ignore);
19864 if (err < 0)
19865 return err;
c69aefab 19866
d1eb57f4
KY
19867 if (!spec->autocfg.line_outs) {
19868 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19869 spec->multiout.max_channels = 2;
19870 spec->no_analog = 1;
19871 goto dig_only;
19872 }
19873 return 0; /* can't find valid BIOS pin config */
19874 }
19875 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19876 if (err < 0)
19877 return err;
19878
19879 spec->multiout.max_channels = 2;
19880
19881 dig_only:
19882 /* digital only support output */
757899ac 19883 alc_auto_parse_digital(codec);
d1eb57f4
KY
19884 if (spec->kctls.list)
19885 add_mixer(spec, spec->kctls.list);
19886
19887 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19888
19889 err = alc_auto_add_mic_boost(codec);
19890 if (err < 0)
19891 return err;
19892
19893 return 1;
19894}
19895
19896#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19897
19898/* init callback for auto-configuration model -- overriding the default init */
19899static void alc680_auto_init(struct hda_codec *codec)
19900{
19901 struct alc_spec *spec = codec->spec;
19902 alc680_auto_init_multi_out(codec);
19903 alc680_auto_init_hp_out(codec);
19904 alc680_auto_init_analog_input(codec);
757899ac 19905 alc_auto_init_digital(codec);
d1eb57f4
KY
19906 if (spec->unsol_event)
19907 alc_inithook(codec);
19908}
19909
19910/*
19911 * configuration and preset
19912 */
ea734963 19913static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19914 [ALC680_BASE] = "base",
19915 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19916};
19917
19918static struct snd_pci_quirk alc680_cfg_tbl[] = {
19919 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19920 {}
19921};
19922
19923static struct alc_config_preset alc680_presets[] = {
19924 [ALC680_BASE] = {
19925 .mixers = { alc680_base_mixer },
c69aefab 19926 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19927 .init_verbs = { alc680_init_verbs },
19928 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19929 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19930 .dig_out_nid = ALC680_DIGOUT_NID,
19931 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19932 .channel_mode = alc680_modes,
c69aefab
KY
19933 .unsol_event = alc680_unsol_event,
19934 .setup = alc680_base_setup,
19935 .init_hook = alc680_inithook,
19936
d1eb57f4
KY
19937 },
19938};
19939
19940static int patch_alc680(struct hda_codec *codec)
19941{
19942 struct alc_spec *spec;
19943 int board_config;
19944 int err;
19945
19946 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19947 if (spec == NULL)
19948 return -ENOMEM;
19949
19950 codec->spec = spec;
19951
19952 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19953 alc680_models,
19954 alc680_cfg_tbl);
19955
19956 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19957 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19958 codec->chip_name);
19959 board_config = ALC680_AUTO;
19960 }
19961
19962 if (board_config == ALC680_AUTO) {
19963 /* automatic parse from the BIOS config */
19964 err = alc680_parse_auto_config(codec);
19965 if (err < 0) {
19966 alc_free(codec);
19967 return err;
19968 } else if (!err) {
19969 printk(KERN_INFO
19970 "hda_codec: Cannot set up configuration "
19971 "from BIOS. Using base mode...\n");
19972 board_config = ALC680_BASE;
19973 }
19974 }
19975
19976 if (board_config != ALC680_AUTO)
19977 setup_preset(codec, &alc680_presets[board_config]);
19978
19979 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19980 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19981 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19982 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19983
19984 if (!spec->adc_nids) {
19985 spec->adc_nids = alc680_adc_nids;
19986 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19987 }
19988
19989 if (!spec->cap_mixer)
19990 set_capture_mixer(codec);
19991
19992 spec->vmaster_nid = 0x02;
19993
19994 codec->patch_ops = alc_patch_ops;
19995 if (board_config == ALC680_AUTO)
19996 spec->init_hook = alc680_auto_init;
19997
19998 return 0;
19999}
20000
1da177e4
LT
20001/*
20002 * patch entries
20003 */
1289e9e8 20004static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 20005 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20006 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20007 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20008 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20009 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20010 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20011 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20012 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20013 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20014 .patch = patch_alc861 },
f32610ed
JS
20015 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20016 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20017 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20018 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20019 .patch = patch_alc882 },
bc9f98a9
KY
20020 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20021 .patch = patch_alc662 },
6dda9f4a 20022 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20023 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20024 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20025 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20026 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20027 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20028 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20029 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20030 .patch = patch_alc882 },
cb308f97 20031 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20032 .patch = patch_alc882 },
df694daa 20033 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20034 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20035 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20036 .patch = patch_alc882 },
274693f3 20037 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20038 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20039 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20040 {} /* terminator */
20041};
1289e9e8
TI
20042
20043MODULE_ALIAS("snd-hda-codec-id:10ec*");
20044
20045MODULE_LICENSE("GPL");
20046MODULE_DESCRIPTION("Realtek HD-audio codec");
20047
20048static struct hda_codec_preset_list realtek_list = {
20049 .preset = snd_hda_preset_realtek,
20050 .owner = THIS_MODULE,
20051};
20052
20053static int __init patch_realtek_init(void)
20054{
20055 return snd_hda_add_codec_preset(&realtek_list);
20056}
20057
20058static void __exit patch_realtek_exit(void)
20059{
20060 snd_hda_delete_codec_preset(&realtek_list);
20061}
20062
20063module_init(patch_realtek_init)
20064module_exit(patch_realtek_exit)