]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Remove unused fixup entry for ALC262
[mirror_ubuntu-jammy-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
9ad0e496
KY
285struct alc_jack {
286 hda_nid_t nid;
287 int type;
288 struct snd_jack *jack;
289};
290
6c819492
TI
291#define MUX_IDX_UNDEF ((unsigned char)-1)
292
da00c244
KY
293struct alc_customize_define {
294 unsigned int sku_cfg;
295 unsigned char port_connectivity;
296 unsigned char check_sum;
297 unsigned char customization;
298 unsigned char external_amp;
299 unsigned int enable_pcbeep:1;
300 unsigned int platform_type:1;
301 unsigned int swap:1;
302 unsigned int override:1;
90622917 303 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
304};
305
1da177e4
LT
306struct alc_spec {
307 /* codec parameterization */
df694daa 308 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 309 unsigned int num_mixers;
f9e336f6 310 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 311 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 312
2d9c6482 313 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
314 * don't forget NULL
315 * termination!
e9edcee0
TI
316 */
317 unsigned int num_init_verbs;
1da177e4 318
aa563af7 319 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
320 struct hda_pcm_stream *stream_analog_playback;
321 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
322 struct hda_pcm_stream *stream_analog_alt_playback;
323 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 324
aa563af7 325 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
326 struct hda_pcm_stream *stream_digital_playback;
327 struct hda_pcm_stream *stream_digital_capture;
328
329 /* playback */
16ded525
TI
330 struct hda_multi_out multiout; /* playback set-up
331 * max_channels, dacs must be set
332 * dig_out_nid and hp_nid are optional
333 */
6330079f 334 hda_nid_t alt_dac_nid;
6a05ac4a 335 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 336 int dig_out_type;
1da177e4
LT
337
338 /* capture */
339 unsigned int num_adc_nids;
340 hda_nid_t *adc_nids;
e1406348 341 hda_nid_t *capsrc_nids;
16ded525 342 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 343
840b64c0
TI
344 /* capture setup for dynamic dual-adc switch */
345 unsigned int cur_adc_idx;
346 hda_nid_t cur_adc;
347 unsigned int cur_adc_stream_tag;
348 unsigned int cur_adc_format;
349
1da177e4 350 /* capture source */
a1e8d2da 351 unsigned int num_mux_defs;
1da177e4
LT
352 const struct hda_input_mux *input_mux;
353 unsigned int cur_mux[3];
6c819492
TI
354 struct alc_mic_route ext_mic;
355 struct alc_mic_route int_mic;
1da177e4
LT
356
357 /* channel model */
d2a6d7dc 358 const struct hda_channel_mode *channel_mode;
1da177e4 359 int num_channel_mode;
4e195a7b 360 int need_dac_fix;
3b315d70
HM
361 int const_channel_count;
362 int ext_channel_count;
1da177e4
LT
363
364 /* PCM information */
4c5186ed 365 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 366
9ad0e496
KY
367 /* jack detection */
368 struct snd_array jacks;
369
e9edcee0
TI
370 /* dynamic controls, init_verbs and input_mux */
371 struct auto_pin_cfg autocfg;
da00c244 372 struct alc_customize_define cdefine;
603c4019 373 struct snd_array kctls;
61b9b9b1 374 struct hda_input_mux private_imux[3];
41923e44 375 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
376 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
377 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 378
ae6b813a
TI
379 /* hooks */
380 void (*init_hook)(struct hda_codec *codec);
381 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 382#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 383 void (*power_hook)(struct hda_codec *codec);
f5de24b0 384#endif
ae6b813a 385
834be88d
TI
386 /* for pin sensing */
387 unsigned int sense_updated: 1;
388 unsigned int jack_present: 1;
bec15c3a 389 unsigned int master_sw: 1;
6c819492 390 unsigned int auto_mic:1;
cb53c626 391
e64f14f4
TI
392 /* other flags */
393 unsigned int no_analog :1; /* digital I/O only */
840b64c0 394 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
4a79ba34 395 int init_amp;
d433a678 396 int codec_variant; /* flag for other variants */
e64f14f4 397
2134ea4f
TI
398 /* for virtual master */
399 hda_nid_t vmaster_nid;
cb53c626
TI
400#ifdef CONFIG_SND_HDA_POWER_SAVE
401 struct hda_loopback_check loopback;
402#endif
2c3bf9ab
TI
403
404 /* for PLL fix */
405 hda_nid_t pll_nid;
406 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
407};
408
409/*
410 * configuration template - to be copied to the spec instance
411 */
412struct alc_config_preset {
9c7f852e
TI
413 struct snd_kcontrol_new *mixers[5]; /* should be identical size
414 * with spec
415 */
f9e336f6 416 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
417 const struct hda_verb *init_verbs[5];
418 unsigned int num_dacs;
419 hda_nid_t *dac_nids;
420 hda_nid_t dig_out_nid; /* optional */
421 hda_nid_t hp_nid; /* optional */
b25c9da1 422 hda_nid_t *slave_dig_outs;
df694daa
KY
423 unsigned int num_adc_nids;
424 hda_nid_t *adc_nids;
e1406348 425 hda_nid_t *capsrc_nids;
df694daa
KY
426 hda_nid_t dig_in_nid;
427 unsigned int num_channel_mode;
428 const struct hda_channel_mode *channel_mode;
4e195a7b 429 int need_dac_fix;
3b315d70 430 int const_channel_count;
a1e8d2da 431 unsigned int num_mux_defs;
df694daa 432 const struct hda_input_mux *input_mux;
ae6b813a 433 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 434 void (*setup)(struct hda_codec *);
ae6b813a 435 void (*init_hook)(struct hda_codec *);
cb53c626
TI
436#ifdef CONFIG_SND_HDA_POWER_SAVE
437 struct hda_amp_list *loopbacks;
c97259df 438 void (*power_hook)(struct hda_codec *codec);
cb53c626 439#endif
1da177e4
LT
440};
441
1da177e4
LT
442
443/*
444 * input MUX handling
445 */
9c7f852e
TI
446static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
447 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
448{
449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
450 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
451 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
452 if (mux_idx >= spec->num_mux_defs)
453 mux_idx = 0;
5311114d
TI
454 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
455 mux_idx = 0;
a1e8d2da 456 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
457}
458
9c7f852e
TI
459static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
461{
462 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
463 struct alc_spec *spec = codec->spec;
464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
465
466 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
467 return 0;
468}
469
9c7f852e
TI
470static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
471 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
472{
473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
474 struct alc_spec *spec = codec->spec;
cd896c33 475 const struct hda_input_mux *imux;
1da177e4 476 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 477 unsigned int mux_idx;
e1406348
TI
478 hda_nid_t nid = spec->capsrc_nids ?
479 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 480 unsigned int type;
1da177e4 481
cd896c33
TI
482 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
483 imux = &spec->input_mux[mux_idx];
5311114d
TI
484 if (!imux->num_items && mux_idx > 0)
485 imux = &spec->input_mux[0];
cd896c33 486
a22d543a 487 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 488 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
489 /* Matrix-mixer style (e.g. ALC882) */
490 unsigned int *cur_val = &spec->cur_mux[adc_idx];
491 unsigned int i, idx;
492
493 idx = ucontrol->value.enumerated.item[0];
494 if (idx >= imux->num_items)
495 idx = imux->num_items - 1;
496 if (*cur_val == idx)
497 return 0;
498 for (i = 0; i < imux->num_items; i++) {
499 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
500 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
501 imux->items[i].index,
502 HDA_AMP_MUTE, v);
503 }
504 *cur_val = idx;
505 return 1;
506 } else {
507 /* MUX style (e.g. ALC880) */
cd896c33 508 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
509 &spec->cur_mux[adc_idx]);
510 }
511}
e9edcee0 512
1da177e4
LT
513/*
514 * channel mode setting
515 */
9c7f852e
TI
516static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
518{
519 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
520 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
521 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
522 spec->num_channel_mode);
1da177e4
LT
523}
524
9c7f852e
TI
525static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
526 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
527{
528 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
529 struct alc_spec *spec = codec->spec;
d2a6d7dc 530 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 531 spec->num_channel_mode,
3b315d70 532 spec->ext_channel_count);
1da177e4
LT
533}
534
9c7f852e
TI
535static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
536 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
537{
538 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
539 struct alc_spec *spec = codec->spec;
4e195a7b
TI
540 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
541 spec->num_channel_mode,
3b315d70
HM
542 &spec->ext_channel_count);
543 if (err >= 0 && !spec->const_channel_count) {
544 spec->multiout.max_channels = spec->ext_channel_count;
545 if (spec->need_dac_fix)
546 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
547 }
4e195a7b 548 return err;
1da177e4
LT
549}
550
a9430dd8 551/*
4c5186ed 552 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 553 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
554 * being part of a format specifier. Maximum allowed length of a value is
555 * 63 characters plus NULL terminator.
7cf51e48
JW
556 *
557 * Note: some retasking pin complexes seem to ignore requests for input
558 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
559 * are requested. Therefore order this list so that this behaviour will not
560 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
561 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
562 * March 2006.
4c5186ed
JW
563 */
564static char *alc_pin_mode_names[] = {
7cf51e48
JW
565 "Mic 50pc bias", "Mic 80pc bias",
566 "Line in", "Line out", "Headphone out",
4c5186ed
JW
567};
568static unsigned char alc_pin_mode_values[] = {
7cf51e48 569 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
570};
571/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
572 * in the pin being assumed to be exclusively an input or an output pin. In
573 * addition, "input" pins may or may not process the mic bias option
574 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
575 * accept requests for bias as of chip versions up to March 2006) and/or
576 * wiring in the computer.
a9430dd8 577 */
a1e8d2da
JW
578#define ALC_PIN_DIR_IN 0x00
579#define ALC_PIN_DIR_OUT 0x01
580#define ALC_PIN_DIR_INOUT 0x02
581#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
582#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 583
ea1fb29a 584/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
585 * For each direction the minimum and maximum values are given.
586 */
a1e8d2da 587static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
588 { 0, 2 }, /* ALC_PIN_DIR_IN */
589 { 3, 4 }, /* ALC_PIN_DIR_OUT */
590 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
591 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
592 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
593};
594#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
595#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
596#define alc_pin_mode_n_items(_dir) \
597 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
598
9c7f852e
TI
599static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
600 struct snd_ctl_elem_info *uinfo)
a9430dd8 601{
4c5186ed
JW
602 unsigned int item_num = uinfo->value.enumerated.item;
603 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
604
605 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 606 uinfo->count = 1;
4c5186ed
JW
607 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
608
609 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
610 item_num = alc_pin_mode_min(dir);
611 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
612 return 0;
613}
614
9c7f852e
TI
615static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
616 struct snd_ctl_elem_value *ucontrol)
a9430dd8 617{
4c5186ed 618 unsigned int i;
a9430dd8
JW
619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
620 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 621 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 622 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
623 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
624 AC_VERB_GET_PIN_WIDGET_CONTROL,
625 0x00);
a9430dd8 626
4c5186ed
JW
627 /* Find enumerated value for current pinctl setting */
628 i = alc_pin_mode_min(dir);
4b35d2ca 629 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 630 i++;
9c7f852e 631 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
632 return 0;
633}
634
9c7f852e
TI
635static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
636 struct snd_ctl_elem_value *ucontrol)
a9430dd8 637{
4c5186ed 638 signed int change;
a9430dd8
JW
639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
640 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
641 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
642 long val = *ucontrol->value.integer.value;
9c7f852e
TI
643 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
644 AC_VERB_GET_PIN_WIDGET_CONTROL,
645 0x00);
a9430dd8 646
f12ab1e0 647 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
648 val = alc_pin_mode_min(dir);
649
650 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
651 if (change) {
652 /* Set pin mode to that requested */
82beb8fd
TI
653 snd_hda_codec_write_cache(codec, nid, 0,
654 AC_VERB_SET_PIN_WIDGET_CONTROL,
655 alc_pin_mode_values[val]);
cdcd9268 656
ea1fb29a 657 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
658 * for the requested pin mode. Enum values of 2 or less are
659 * input modes.
660 *
661 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
662 * reduces noise slightly (particularly on input) so we'll
663 * do it. However, having both input and output buffers
664 * enabled simultaneously doesn't seem to be problematic if
665 * this turns out to be necessary in the future.
cdcd9268
JW
666 */
667 if (val <= 2) {
47fd830a
TI
668 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
669 HDA_AMP_MUTE, HDA_AMP_MUTE);
670 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
671 HDA_AMP_MUTE, 0);
cdcd9268 672 } else {
47fd830a
TI
673 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
674 HDA_AMP_MUTE, HDA_AMP_MUTE);
675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
676 HDA_AMP_MUTE, 0);
cdcd9268
JW
677 }
678 }
a9430dd8
JW
679 return change;
680}
681
4c5186ed 682#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 683 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 684 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
685 .info = alc_pin_mode_info, \
686 .get = alc_pin_mode_get, \
687 .put = alc_pin_mode_put, \
688 .private_value = nid | (dir<<16) }
df694daa 689
5c8f858d
JW
690/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
691 * together using a mask with more than one bit set. This control is
692 * currently used only by the ALC260 test model. At this stage they are not
693 * needed for any "production" models.
694 */
695#ifdef CONFIG_SND_DEBUG
a5ce8890 696#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 697
9c7f852e
TI
698static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
699 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
700{
701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
702 hda_nid_t nid = kcontrol->private_value & 0xffff;
703 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
704 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
705 unsigned int val = snd_hda_codec_read(codec, nid, 0,
706 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
707
708 *valp = (val & mask) != 0;
709 return 0;
710}
9c7f852e
TI
711static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
713{
714 signed int change;
715 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
716 hda_nid_t nid = kcontrol->private_value & 0xffff;
717 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
718 long val = *ucontrol->value.integer.value;
9c7f852e
TI
719 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
720 AC_VERB_GET_GPIO_DATA,
721 0x00);
5c8f858d
JW
722
723 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
724 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
725 if (val == 0)
5c8f858d
JW
726 gpio_data &= ~mask;
727 else
728 gpio_data |= mask;
82beb8fd
TI
729 snd_hda_codec_write_cache(codec, nid, 0,
730 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
731
732 return change;
733}
734#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
735 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
737 .info = alc_gpio_data_info, \
738 .get = alc_gpio_data_get, \
739 .put = alc_gpio_data_put, \
740 .private_value = nid | (mask<<16) }
741#endif /* CONFIG_SND_DEBUG */
742
92621f13
JW
743/* A switch control to allow the enabling of the digital IO pins on the
744 * ALC260. This is incredibly simplistic; the intention of this control is
745 * to provide something in the test model allowing digital outputs to be
746 * identified if present. If models are found which can utilise these
747 * outputs a more complete mixer control can be devised for those models if
748 * necessary.
749 */
750#ifdef CONFIG_SND_DEBUG
a5ce8890 751#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 752
9c7f852e
TI
753static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
754 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
755{
756 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
757 hda_nid_t nid = kcontrol->private_value & 0xffff;
758 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
759 long *valp = ucontrol->value.integer.value;
9c7f852e 760 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 761 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
762
763 *valp = (val & mask) != 0;
764 return 0;
765}
9c7f852e
TI
766static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
767 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
768{
769 signed int change;
770 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
771 hda_nid_t nid = kcontrol->private_value & 0xffff;
772 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
773 long val = *ucontrol->value.integer.value;
9c7f852e 774 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 775 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 776 0x00);
92621f13
JW
777
778 /* Set/unset the masked control bit(s) as needed */
9c7f852e 779 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
780 if (val==0)
781 ctrl_data &= ~mask;
782 else
783 ctrl_data |= mask;
82beb8fd
TI
784 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
785 ctrl_data);
92621f13
JW
786
787 return change;
788}
789#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
790 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 791 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
792 .info = alc_spdif_ctrl_info, \
793 .get = alc_spdif_ctrl_get, \
794 .put = alc_spdif_ctrl_put, \
795 .private_value = nid | (mask<<16) }
796#endif /* CONFIG_SND_DEBUG */
797
f8225f6d
JW
798/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
799 * Again, this is only used in the ALC26x test models to help identify when
800 * the EAPD line must be asserted for features to work.
801 */
802#ifdef CONFIG_SND_DEBUG
803#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
804
805static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
806 struct snd_ctl_elem_value *ucontrol)
807{
808 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
809 hda_nid_t nid = kcontrol->private_value & 0xffff;
810 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
811 long *valp = ucontrol->value.integer.value;
812 unsigned int val = snd_hda_codec_read(codec, nid, 0,
813 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
814
815 *valp = (val & mask) != 0;
816 return 0;
817}
818
819static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
820 struct snd_ctl_elem_value *ucontrol)
821{
822 int change;
823 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
824 hda_nid_t nid = kcontrol->private_value & 0xffff;
825 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
826 long val = *ucontrol->value.integer.value;
827 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
828 AC_VERB_GET_EAPD_BTLENABLE,
829 0x00);
830
831 /* Set/unset the masked control bit(s) as needed */
832 change = (!val ? 0 : mask) != (ctrl_data & mask);
833 if (!val)
834 ctrl_data &= ~mask;
835 else
836 ctrl_data |= mask;
837 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
838 ctrl_data);
839
840 return change;
841}
842
843#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
844 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 845 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
846 .info = alc_eapd_ctrl_info, \
847 .get = alc_eapd_ctrl_get, \
848 .put = alc_eapd_ctrl_put, \
849 .private_value = nid | (mask<<16) }
850#endif /* CONFIG_SND_DEBUG */
851
23f0c048
TI
852/*
853 * set up the input pin config (depending on the given auto-pin type)
854 */
855static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
856 int auto_pin_type)
857{
858 unsigned int val = PIN_IN;
859
86e2959a 860 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 861 unsigned int pincap;
954a29c8
TI
862 unsigned int oldval;
863 oldval = snd_hda_codec_read(codec, nid, 0,
864 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 865 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 866 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
867 /* if the default pin setup is vref50, we give it priority */
868 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 869 val = PIN_VREF80;
461c6c3a
TI
870 else if (pincap & AC_PINCAP_VREF_50)
871 val = PIN_VREF50;
872 else if (pincap & AC_PINCAP_VREF_100)
873 val = PIN_VREF100;
874 else if (pincap & AC_PINCAP_VREF_GRD)
875 val = PIN_VREFGRD;
23f0c048
TI
876 }
877 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
878}
879
f6837bbd
TI
880static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
881{
882 struct alc_spec *spec = codec->spec;
883 struct auto_pin_cfg *cfg = &spec->autocfg;
884
885 if (!cfg->line_outs) {
886 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
887 cfg->line_out_pins[cfg->line_outs])
888 cfg->line_outs++;
889 }
890 if (!cfg->speaker_outs) {
891 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
892 cfg->speaker_pins[cfg->speaker_outs])
893 cfg->speaker_outs++;
894 }
895 if (!cfg->hp_outs) {
896 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
897 cfg->hp_pins[cfg->hp_outs])
898 cfg->hp_outs++;
899 }
900}
901
d88897ea
TI
902/*
903 */
904static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
905{
906 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
907 return;
908 spec->mixers[spec->num_mixers++] = mix;
909}
910
911static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
912{
913 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
914 return;
915 spec->init_verbs[spec->num_init_verbs++] = verb;
916}
917
df694daa
KY
918/*
919 * set up from the preset table
920 */
e9c364c0 921static void setup_preset(struct hda_codec *codec,
9c7f852e 922 const struct alc_config_preset *preset)
df694daa 923{
e9c364c0 924 struct alc_spec *spec = codec->spec;
df694daa
KY
925 int i;
926
927 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 928 add_mixer(spec, preset->mixers[i]);
f9e336f6 929 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
930 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
931 i++)
d88897ea 932 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 933
df694daa
KY
934 spec->channel_mode = preset->channel_mode;
935 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 936 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 937 spec->const_channel_count = preset->const_channel_count;
df694daa 938
3b315d70
HM
939 if (preset->const_channel_count)
940 spec->multiout.max_channels = preset->const_channel_count;
941 else
942 spec->multiout.max_channels = spec->channel_mode[0].channels;
943 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
944
945 spec->multiout.num_dacs = preset->num_dacs;
946 spec->multiout.dac_nids = preset->dac_nids;
947 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 948 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 949 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 950
a1e8d2da 951 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 952 if (!spec->num_mux_defs)
a1e8d2da 953 spec->num_mux_defs = 1;
df694daa
KY
954 spec->input_mux = preset->input_mux;
955
956 spec->num_adc_nids = preset->num_adc_nids;
957 spec->adc_nids = preset->adc_nids;
e1406348 958 spec->capsrc_nids = preset->capsrc_nids;
df694daa 959 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
960
961 spec->unsol_event = preset->unsol_event;
962 spec->init_hook = preset->init_hook;
cb53c626 963#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 964 spec->power_hook = preset->power_hook;
cb53c626
TI
965 spec->loopback.amplist = preset->loopbacks;
966#endif
e9c364c0
TI
967
968 if (preset->setup)
969 preset->setup(codec);
f6837bbd
TI
970
971 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
972}
973
bc9f98a9
KY
974/* Enable GPIO mask and set output */
975static struct hda_verb alc_gpio1_init_verbs[] = {
976 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
977 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
978 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
979 { }
980};
981
982static struct hda_verb alc_gpio2_init_verbs[] = {
983 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
985 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
986 { }
987};
988
bdd148a3
KY
989static struct hda_verb alc_gpio3_init_verbs[] = {
990 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
992 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
993 { }
994};
995
2c3bf9ab
TI
996/*
997 * Fix hardware PLL issue
998 * On some codecs, the analog PLL gating control must be off while
999 * the default value is 1.
1000 */
1001static void alc_fix_pll(struct hda_codec *codec)
1002{
1003 struct alc_spec *spec = codec->spec;
1004 unsigned int val;
1005
1006 if (!spec->pll_nid)
1007 return;
1008 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1009 spec->pll_coef_idx);
1010 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1011 AC_VERB_GET_PROC_COEF, 0);
1012 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1013 spec->pll_coef_idx);
1014 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1015 val & ~(1 << spec->pll_coef_bit));
1016}
1017
1018static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1019 unsigned int coef_idx, unsigned int coef_bit)
1020{
1021 struct alc_spec *spec = codec->spec;
1022 spec->pll_nid = nid;
1023 spec->pll_coef_idx = coef_idx;
1024 spec->pll_coef_bit = coef_bit;
1025 alc_fix_pll(codec);
1026}
1027
9ad0e496
KY
1028#ifdef CONFIG_SND_HDA_INPUT_JACK
1029static void alc_free_jack_priv(struct snd_jack *jack)
1030{
1031 struct alc_jack *jacks = jack->private_data;
1032 jacks->nid = 0;
1033 jacks->jack = NULL;
1034}
1035
1036static int alc_add_jack(struct hda_codec *codec,
1037 hda_nid_t nid, int type)
1038{
1039 struct alc_spec *spec;
1040 struct alc_jack *jack;
1041 const char *name;
1042 int err;
1043
1044 spec = codec->spec;
1045 snd_array_init(&spec->jacks, sizeof(*jack), 32);
1046 jack = snd_array_new(&spec->jacks);
1047 if (!jack)
1048 return -ENOMEM;
1049
1050 jack->nid = nid;
1051 jack->type = type;
1052 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
1053
1054 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
1055 if (err < 0)
1056 return err;
1057 jack->jack->private_data = jack;
1058 jack->jack->private_free = alc_free_jack_priv;
1059 return 0;
1060}
1061
1062static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1063{
1064 struct alc_spec *spec = codec->spec;
1065 struct alc_jack *jacks = spec->jacks.list;
1066
1067 if (jacks) {
1068 int i;
1069 for (i = 0; i < spec->jacks.used; i++) {
1070 if (jacks->nid == nid) {
1071 unsigned int present;
1072 present = snd_hda_jack_detect(codec, nid);
1073
1074 present = (present) ? jacks->type : 0;
1075
1076 snd_jack_report(jacks->jack, present);
1077 }
1078 jacks++;
1079 }
1080 }
1081}
1082
1083static int alc_init_jacks(struct hda_codec *codec)
1084{
1085 struct alc_spec *spec = codec->spec;
1086 int err;
1087 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1088 unsigned int mic_nid = spec->ext_mic.pin;
1089
265a0247
TI
1090 if (hp_nid) {
1091 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE);
1092 if (err < 0)
1093 return err;
1094 alc_report_jack(codec, hp_nid);
1095 }
9ad0e496 1096
265a0247
TI
1097 if (mic_nid) {
1098 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE);
1099 if (err < 0)
1100 return err;
1101 alc_report_jack(codec, mic_nid);
1102 }
9ad0e496
KY
1103
1104 return 0;
1105}
1106#else
1107static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1108{
1109}
1110
1111static inline int alc_init_jacks(struct hda_codec *codec)
1112{
1113 return 0;
1114}
1115#endif
1116
bb35febd 1117static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
c9b58006
KY
1118{
1119 struct alc_spec *spec = codec->spec;
bb35febd
TI
1120 unsigned int mute;
1121 hda_nid_t nid;
a9fd4f3f 1122 int i;
c9b58006 1123
bb35febd
TI
1124 spec->jack_present = 0;
1125 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1126 nid = spec->autocfg.hp_pins[i];
1127 if (!nid)
1128 break;
1129 if (snd_hda_jack_detect(codec, nid)) {
1130 spec->jack_present = 1;
1131 break;
1132 }
9ad0e496 1133 alc_report_jack(codec, spec->autocfg.hp_pins[i]);
bb35febd
TI
1134 }
1135
1136 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1137 /* Toggle internal speakers muting */
a9fd4f3f
TI
1138 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1139 nid = spec->autocfg.speaker_pins[i];
1140 if (!nid)
1141 break;
bb35febd
TI
1142 if (pinctl) {
1143 snd_hda_codec_write(codec, nid, 0,
a9fd4f3f
TI
1144 AC_VERB_SET_PIN_WIDGET_CONTROL,
1145 spec->jack_present ? 0 : PIN_OUT);
bb35febd
TI
1146 } else {
1147 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1148 HDA_AMP_MUTE, mute);
1149 }
a9fd4f3f 1150 }
c9b58006
KY
1151}
1152
bb35febd
TI
1153static void alc_automute_pin(struct hda_codec *codec)
1154{
1155 alc_automute_speaker(codec, 1);
1156}
1157
6c819492
TI
1158static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1159 hda_nid_t nid)
1160{
1161 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1162 int i, nums;
1163
1164 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1165 for (i = 0; i < nums; i++)
1166 if (conn[i] == nid)
1167 return i;
1168 return -1;
1169}
1170
840b64c0
TI
1171/* switch the current ADC according to the jack state */
1172static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1173{
1174 struct alc_spec *spec = codec->spec;
1175 unsigned int present;
1176 hda_nid_t new_adc;
1177
1178 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1179 if (present)
1180 spec->cur_adc_idx = 1;
1181 else
1182 spec->cur_adc_idx = 0;
1183 new_adc = spec->adc_nids[spec->cur_adc_idx];
1184 if (spec->cur_adc && spec->cur_adc != new_adc) {
1185 /* stream is running, let's swap the current ADC */
f0cea797 1186 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1187 spec->cur_adc = new_adc;
1188 snd_hda_codec_setup_stream(codec, new_adc,
1189 spec->cur_adc_stream_tag, 0,
1190 spec->cur_adc_format);
1191 }
1192}
1193
7fb0d78f
KY
1194static void alc_mic_automute(struct hda_codec *codec)
1195{
1196 struct alc_spec *spec = codec->spec;
6c819492
TI
1197 struct alc_mic_route *dead, *alive;
1198 unsigned int present, type;
1199 hda_nid_t cap_nid;
1200
b59bdf3b
TI
1201 if (!spec->auto_mic)
1202 return;
6c819492
TI
1203 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1204 return;
1205 if (snd_BUG_ON(!spec->adc_nids))
1206 return;
1207
840b64c0
TI
1208 if (spec->dual_adc_switch) {
1209 alc_dual_mic_adc_auto_switch(codec);
1210 return;
1211 }
1212
6c819492
TI
1213 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1214
864f92be 1215 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1216 if (present) {
1217 alive = &spec->ext_mic;
1218 dead = &spec->int_mic;
1219 } else {
1220 alive = &spec->int_mic;
1221 dead = &spec->ext_mic;
1222 }
1223
6c819492
TI
1224 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1225 if (type == AC_WID_AUD_MIX) {
1226 /* Matrix-mixer style (e.g. ALC882) */
1227 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1228 alive->mux_idx,
1229 HDA_AMP_MUTE, 0);
1230 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1231 dead->mux_idx,
1232 HDA_AMP_MUTE, HDA_AMP_MUTE);
1233 } else {
1234 /* MUX style (e.g. ALC880) */
1235 snd_hda_codec_write_cache(codec, cap_nid, 0,
1236 AC_VERB_SET_CONNECT_SEL,
1237 alive->mux_idx);
1238 }
9ad0e496 1239 alc_report_jack(codec, spec->ext_mic.pin);
6c819492
TI
1240
1241 /* FIXME: analog mixer */
7fb0d78f
KY
1242}
1243
c9b58006
KY
1244/* unsolicited event for HP jack sensing */
1245static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1246{
1247 if (codec->vendor_id == 0x10ec0880)
1248 res >>= 28;
1249 else
1250 res >>= 26;
a9fd4f3f
TI
1251 switch (res) {
1252 case ALC880_HP_EVENT:
1253 alc_automute_pin(codec);
1254 break;
1255 case ALC880_MIC_EVENT:
7fb0d78f 1256 alc_mic_automute(codec);
a9fd4f3f
TI
1257 break;
1258 }
7fb0d78f
KY
1259}
1260
1261static void alc_inithook(struct hda_codec *codec)
1262{
a9fd4f3f 1263 alc_automute_pin(codec);
7fb0d78f 1264 alc_mic_automute(codec);
c9b58006
KY
1265}
1266
f9423e7a
KY
1267/* additional initialization for ALC888 variants */
1268static void alc888_coef_init(struct hda_codec *codec)
1269{
1270 unsigned int tmp;
1271
1272 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1273 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1274 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1275 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1276 /* alc888S-VC */
1277 snd_hda_codec_read(codec, 0x20, 0,
1278 AC_VERB_SET_PROC_COEF, 0x830);
1279 else
1280 /* alc888-VB */
1281 snd_hda_codec_read(codec, 0x20, 0,
1282 AC_VERB_SET_PROC_COEF, 0x3030);
1283}
1284
87a8c370
JK
1285static void alc889_coef_init(struct hda_codec *codec)
1286{
1287 unsigned int tmp;
1288
1289 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1290 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1291 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1292 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1293}
1294
3fb4a508
TI
1295/* turn on/off EAPD control (only if available) */
1296static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1297{
1298 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1299 return;
1300 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1301 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1302 on ? 2 : 0);
1303}
1304
4a79ba34 1305static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1306{
4a79ba34 1307 unsigned int tmp;
bc9f98a9 1308
4a79ba34
TI
1309 switch (type) {
1310 case ALC_INIT_GPIO1:
bc9f98a9
KY
1311 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1312 break;
4a79ba34 1313 case ALC_INIT_GPIO2:
bc9f98a9
KY
1314 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1315 break;
4a79ba34 1316 case ALC_INIT_GPIO3:
bdd148a3
KY
1317 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1318 break;
4a79ba34 1319 case ALC_INIT_DEFAULT:
bdd148a3 1320 switch (codec->vendor_id) {
c9b58006 1321 case 0x10ec0260:
3fb4a508
TI
1322 set_eapd(codec, 0x0f, 1);
1323 set_eapd(codec, 0x10, 1);
c9b58006
KY
1324 break;
1325 case 0x10ec0262:
bdd148a3
KY
1326 case 0x10ec0267:
1327 case 0x10ec0268:
c9b58006 1328 case 0x10ec0269:
3fb4a508 1329 case 0x10ec0270:
c6e8f2da 1330 case 0x10ec0272:
f9423e7a
KY
1331 case 0x10ec0660:
1332 case 0x10ec0662:
1333 case 0x10ec0663:
c9b58006 1334 case 0x10ec0862:
20a3a05d 1335 case 0x10ec0889:
3fb4a508
TI
1336 set_eapd(codec, 0x14, 1);
1337 set_eapd(codec, 0x15, 1);
c9b58006 1338 break;
bdd148a3 1339 }
c9b58006
KY
1340 switch (codec->vendor_id) {
1341 case 0x10ec0260:
1342 snd_hda_codec_write(codec, 0x1a, 0,
1343 AC_VERB_SET_COEF_INDEX, 7);
1344 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1345 AC_VERB_GET_PROC_COEF, 0);
1346 snd_hda_codec_write(codec, 0x1a, 0,
1347 AC_VERB_SET_COEF_INDEX, 7);
1348 snd_hda_codec_write(codec, 0x1a, 0,
1349 AC_VERB_SET_PROC_COEF,
1350 tmp | 0x2010);
1351 break;
1352 case 0x10ec0262:
1353 case 0x10ec0880:
1354 case 0x10ec0882:
1355 case 0x10ec0883:
1356 case 0x10ec0885:
4a5a4c56 1357 case 0x10ec0887:
20a3a05d 1358 case 0x10ec0889:
87a8c370 1359 alc889_coef_init(codec);
c9b58006 1360 break;
f9423e7a 1361 case 0x10ec0888:
4a79ba34 1362 alc888_coef_init(codec);
f9423e7a 1363 break;
0aea778e 1364#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1365 case 0x10ec0267:
1366 case 0x10ec0268:
1367 snd_hda_codec_write(codec, 0x20, 0,
1368 AC_VERB_SET_COEF_INDEX, 7);
1369 tmp = snd_hda_codec_read(codec, 0x20, 0,
1370 AC_VERB_GET_PROC_COEF, 0);
1371 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1372 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1373 snd_hda_codec_write(codec, 0x20, 0,
1374 AC_VERB_SET_PROC_COEF,
1375 tmp | 0x3000);
1376 break;
0aea778e 1377#endif /* XXX */
bc9f98a9 1378 }
4a79ba34
TI
1379 break;
1380 }
1381}
1382
1383static void alc_init_auto_hp(struct hda_codec *codec)
1384{
1385 struct alc_spec *spec = codec->spec;
bb35febd
TI
1386 struct auto_pin_cfg *cfg = &spec->autocfg;
1387 int i;
4a79ba34 1388
bb35febd
TI
1389 if (!cfg->hp_pins[0]) {
1390 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1391 return;
1392 }
4a79ba34 1393
bb35febd
TI
1394 if (!cfg->speaker_pins[0]) {
1395 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4a79ba34 1396 return;
bb35febd
TI
1397 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1398 sizeof(cfg->speaker_pins));
1399 cfg->speaker_outs = cfg->line_outs;
1400 }
1401
1402 if (!cfg->hp_pins[0]) {
1403 memcpy(cfg->hp_pins, cfg->line_out_pins,
1404 sizeof(cfg->hp_pins));
1405 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1406 }
1407
bb35febd
TI
1408 for (i = 0; i < cfg->hp_outs; i++) {
1409 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1410 cfg->hp_pins[i]);
1411 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
4a79ba34
TI
1412 AC_VERB_SET_UNSOLICITED_ENABLE,
1413 AC_USRSP_EN | ALC880_HP_EVENT);
bb35febd 1414 }
4a79ba34
TI
1415 spec->unsol_event = alc_sku_unsol_event;
1416}
1417
6c819492
TI
1418static void alc_init_auto_mic(struct hda_codec *codec)
1419{
1420 struct alc_spec *spec = codec->spec;
1421 struct auto_pin_cfg *cfg = &spec->autocfg;
1422 hda_nid_t fixed, ext;
1423 int i;
1424
1425 /* there must be only two mic inputs exclusively */
66ceeb6b 1426 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1427 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1428 return;
1429
1430 fixed = ext = 0;
66ceeb6b
TI
1431 for (i = 0; i < cfg->num_inputs; i++) {
1432 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1433 unsigned int defcfg;
6c819492 1434 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1435 switch (snd_hda_get_input_pin_attr(defcfg)) {
1436 case INPUT_PIN_ATTR_INT:
6c819492
TI
1437 if (fixed)
1438 return; /* already occupied */
1439 fixed = nid;
1440 break;
99ae28be
TI
1441 case INPUT_PIN_ATTR_UNUSED:
1442 return; /* invalid entry */
1443 default:
6c819492
TI
1444 if (ext)
1445 return; /* already occupied */
1446 ext = nid;
1447 break;
6c819492
TI
1448 }
1449 }
eaa9b3a7
TI
1450 if (!ext || !fixed)
1451 return;
6c819492
TI
1452 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1453 return; /* no unsol support */
1454 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1455 ext, fixed);
1456 spec->ext_mic.pin = ext;
1457 spec->int_mic.pin = fixed;
1458 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1459 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1460 spec->auto_mic = 1;
1461 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1462 AC_VERB_SET_UNSOLICITED_ENABLE,
1463 AC_USRSP_EN | ALC880_MIC_EVENT);
1464 spec->unsol_event = alc_sku_unsol_event;
1465}
1466
90622917
DH
1467/* Could be any non-zero and even value. When used as fixup, tells
1468 * the driver to ignore any present sku defines.
1469 */
1470#define ALC_FIXUP_SKU_IGNORE (2)
1471
da00c244
KY
1472static int alc_auto_parse_customize_define(struct hda_codec *codec)
1473{
1474 unsigned int ass, tmp, i;
7fb56223 1475 unsigned nid = 0;
da00c244
KY
1476 struct alc_spec *spec = codec->spec;
1477
b6cbe517
TI
1478 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1479
90622917
DH
1480 if (spec->cdefine.fixup) {
1481 ass = spec->cdefine.sku_cfg;
1482 if (ass == ALC_FIXUP_SKU_IGNORE)
1483 return -1;
1484 goto do_sku;
1485 }
1486
da00c244 1487 ass = codec->subsystem_id & 0xffff;
b6cbe517 1488 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1489 goto do_sku;
1490
1491 nid = 0x1d;
1492 if (codec->vendor_id == 0x10ec0260)
1493 nid = 0x17;
1494 ass = snd_hda_codec_get_pincfg(codec, nid);
1495
1496 if (!(ass & 1)) {
1497 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1498 codec->chip_name, ass);
1499 return -1;
1500 }
1501
1502 /* check sum */
1503 tmp = 0;
1504 for (i = 1; i < 16; i++) {
1505 if ((ass >> i) & 1)
1506 tmp++;
1507 }
1508 if (((ass >> 16) & 0xf) != tmp)
1509 return -1;
1510
1511 spec->cdefine.port_connectivity = ass >> 30;
1512 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1513 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1514 spec->cdefine.customization = ass >> 8;
1515do_sku:
1516 spec->cdefine.sku_cfg = ass;
1517 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1518 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1519 spec->cdefine.swap = (ass & 0x2) >> 1;
1520 spec->cdefine.override = ass & 0x1;
1521
1522 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1523 nid, spec->cdefine.sku_cfg);
1524 snd_printd("SKU: port_connectivity=0x%x\n",
1525 spec->cdefine.port_connectivity);
1526 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1527 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1528 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1529 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1530 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1531 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1532 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1533
1534 return 0;
1535}
1536
4a79ba34
TI
1537/* check subsystem ID and set up device-specific initialization;
1538 * return 1 if initialized, 0 if invalid SSID
1539 */
1540/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1541 * 31 ~ 16 : Manufacture ID
1542 * 15 ~ 8 : SKU ID
1543 * 7 ~ 0 : Assembly ID
1544 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1545 */
1546static int alc_subsystem_id(struct hda_codec *codec,
1547 hda_nid_t porta, hda_nid_t porte,
6227cdce 1548 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1549{
1550 unsigned int ass, tmp, i;
1551 unsigned nid;
1552 struct alc_spec *spec = codec->spec;
1553
90622917
DH
1554 if (spec->cdefine.fixup) {
1555 ass = spec->cdefine.sku_cfg;
1556 if (ass == ALC_FIXUP_SKU_IGNORE)
1557 return 0;
1558 goto do_sku;
1559 }
1560
4a79ba34
TI
1561 ass = codec->subsystem_id & 0xffff;
1562 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1563 goto do_sku;
1564
1565 /* invalid SSID, check the special NID pin defcfg instead */
1566 /*
def319f9 1567 * 31~30 : port connectivity
4a79ba34
TI
1568 * 29~21 : reserve
1569 * 20 : PCBEEP input
1570 * 19~16 : Check sum (15:1)
1571 * 15~1 : Custom
1572 * 0 : override
1573 */
1574 nid = 0x1d;
1575 if (codec->vendor_id == 0x10ec0260)
1576 nid = 0x17;
1577 ass = snd_hda_codec_get_pincfg(codec, nid);
1578 snd_printd("realtek: No valid SSID, "
1579 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1580 ass, nid);
6227cdce 1581 if (!(ass & 1))
4a79ba34
TI
1582 return 0;
1583 if ((ass >> 30) != 1) /* no physical connection */
1584 return 0;
1585
1586 /* check sum */
1587 tmp = 0;
1588 for (i = 1; i < 16; i++) {
1589 if ((ass >> i) & 1)
1590 tmp++;
1591 }
1592 if (((ass >> 16) & 0xf) != tmp)
1593 return 0;
1594do_sku:
1595 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1596 ass & 0xffff, codec->vendor_id);
1597 /*
1598 * 0 : override
1599 * 1 : Swap Jack
1600 * 2 : 0 --> Desktop, 1 --> Laptop
1601 * 3~5 : External Amplifier control
1602 * 7~6 : Reserved
1603 */
1604 tmp = (ass & 0x38) >> 3; /* external Amp control */
1605 switch (tmp) {
1606 case 1:
1607 spec->init_amp = ALC_INIT_GPIO1;
1608 break;
1609 case 3:
1610 spec->init_amp = ALC_INIT_GPIO2;
1611 break;
1612 case 7:
1613 spec->init_amp = ALC_INIT_GPIO3;
1614 break;
1615 case 5:
5a8cfb4e 1616 default:
4a79ba34 1617 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1618 break;
1619 }
ea1fb29a 1620
8c427226 1621 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1622 * when the external headphone out jack is plugged"
1623 */
8c427226 1624 if (!(ass & 0x8000))
4a79ba34 1625 return 1;
c9b58006
KY
1626 /*
1627 * 10~8 : Jack location
1628 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1629 * 14~13: Resvered
1630 * 15 : 1 --> enable the function "Mute internal speaker
1631 * when the external headphone out jack is plugged"
1632 */
c9b58006 1633 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1634 hda_nid_t nid;
c9b58006
KY
1635 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1636 if (tmp == 0)
01d4825d 1637 nid = porta;
c9b58006 1638 else if (tmp == 1)
01d4825d 1639 nid = porte;
c9b58006 1640 else if (tmp == 2)
01d4825d 1641 nid = portd;
6227cdce
KY
1642 else if (tmp == 3)
1643 nid = porti;
c9b58006 1644 else
4a79ba34 1645 return 1;
01d4825d
TI
1646 for (i = 0; i < spec->autocfg.line_outs; i++)
1647 if (spec->autocfg.line_out_pins[i] == nid)
1648 return 1;
1649 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1650 }
1651
4a79ba34 1652 alc_init_auto_hp(codec);
6c819492 1653 alc_init_auto_mic(codec);
4a79ba34
TI
1654 return 1;
1655}
ea1fb29a 1656
4a79ba34 1657static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1658 hda_nid_t porta, hda_nid_t porte,
1659 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1660{
6227cdce 1661 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1662 struct alc_spec *spec = codec->spec;
1663 snd_printd("realtek: "
1664 "Enable default setup for auto mode as fallback\n");
1665 spec->init_amp = ALC_INIT_DEFAULT;
1666 alc_init_auto_hp(codec);
6c819492 1667 alc_init_auto_mic(codec);
4a79ba34 1668 }
bc9f98a9
KY
1669}
1670
f95474ec 1671/*
f8f25ba3 1672 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1673 */
1674
1675struct alc_pincfg {
1676 hda_nid_t nid;
1677 u32 val;
1678};
1679
e1eb5f10
TB
1680struct alc_model_fixup {
1681 const int id;
1682 const char *name;
1683};
1684
f8f25ba3 1685struct alc_fixup {
90622917 1686 unsigned int sku;
f8f25ba3
TI
1687 const struct alc_pincfg *pins;
1688 const struct hda_verb *verbs;
9d57883f
TI
1689 void (*func)(struct hda_codec *codec, const struct alc_fixup *fix,
1690 int pre_init);
f8f25ba3
TI
1691};
1692
e1eb5f10
TB
1693static void __alc_pick_fixup(struct hda_codec *codec,
1694 const struct alc_fixup *fix,
1695 const char *modelname,
1696 int pre_init)
f95474ec
TI
1697{
1698 const struct alc_pincfg *cfg;
90622917 1699 struct alc_spec *spec;
f95474ec 1700
f8f25ba3 1701 cfg = fix->pins;
90622917
DH
1702 if (pre_init && fix->sku) {
1703#ifdef CONFIG_SND_DEBUG_VERBOSE
1704 snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n",
e1eb5f10 1705 codec->chip_name, modelname);
90622917
DH
1706#endif
1707 spec = codec->spec;
1708 spec->cdefine.sku_cfg = fix->sku;
1709 spec->cdefine.fixup = 1;
1710 }
7fa90e87
TI
1711 if (pre_init && cfg) {
1712#ifdef CONFIG_SND_DEBUG_VERBOSE
1713 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
e1eb5f10 1714 codec->chip_name, modelname);
7fa90e87 1715#endif
f8f25ba3
TI
1716 for (; cfg->nid; cfg++)
1717 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1718 }
7fa90e87
TI
1719 if (!pre_init && fix->verbs) {
1720#ifdef CONFIG_SND_DEBUG_VERBOSE
1721 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
e1eb5f10 1722 codec->chip_name, modelname);
7fa90e87 1723#endif
f8f25ba3 1724 add_verb(codec->spec, fix->verbs);
7fa90e87 1725 }
9d57883f
TI
1726 if (fix->func) {
1727#ifdef CONFIG_SND_DEBUG_VERBOSE
1728 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n",
e1eb5f10 1729 codec->chip_name, modelname);
9d57883f
TI
1730#endif
1731 fix->func(codec, fix, pre_init);
1732 }
f95474ec
TI
1733}
1734
e1eb5f10
TB
1735static void alc_pick_fixup(struct hda_codec *codec,
1736 const struct snd_pci_quirk *quirk,
1737 const struct alc_fixup *fix,
1738 int pre_init)
1739{
1740 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1741 if (quirk) {
1742 fix += quirk->value;
1743#ifdef CONFIG_SND_DEBUG_VERBOSE
1744 __alc_pick_fixup(codec, fix, quirk->name, pre_init);
1745#else
1746 __alc_pick_fixup(codec, fix, NULL, pre_init);
1747#endif
1748 }
1749}
1750
1751static void alc_pick_fixup_model(struct hda_codec *codec,
1752 const struct alc_model_fixup *models,
1753 const struct snd_pci_quirk *quirk,
1754 const struct alc_fixup *fix,
1755 int pre_init)
1756{
1757 if (codec->modelname && models) {
1758 while (models->name) {
1759 if (!strcmp(codec->modelname, models->name)) {
1760 fix += models->id;
1761 break;
1762 }
1763 models++;
1764 }
1765 __alc_pick_fixup(codec, fix, codec->modelname, pre_init);
1766 } else {
1767 alc_pick_fixup(codec, quirk, fix, pre_init);
1768 }
1769}
1770
274693f3
KY
1771static int alc_read_coef_idx(struct hda_codec *codec,
1772 unsigned int coef_idx)
1773{
1774 unsigned int val;
1775 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1776 coef_idx);
1777 val = snd_hda_codec_read(codec, 0x20, 0,
1778 AC_VERB_GET_PROC_COEF, 0);
1779 return val;
1780}
1781
977ddd6b
KY
1782static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1783 unsigned int coef_val)
1784{
1785 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1786 coef_idx);
1787 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1788 coef_val);
1789}
1790
757899ac
TI
1791/* set right pin controls for digital I/O */
1792static void alc_auto_init_digital(struct hda_codec *codec)
1793{
1794 struct alc_spec *spec = codec->spec;
1795 int i;
1796 hda_nid_t pin;
1797
1798 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1799 pin = spec->autocfg.dig_out_pins[i];
1800 if (pin) {
1801 snd_hda_codec_write(codec, pin, 0,
1802 AC_VERB_SET_PIN_WIDGET_CONTROL,
1803 PIN_OUT);
1804 }
1805 }
1806 pin = spec->autocfg.dig_in_pin;
1807 if (pin)
1808 snd_hda_codec_write(codec, pin, 0,
1809 AC_VERB_SET_PIN_WIDGET_CONTROL,
1810 PIN_IN);
1811}
1812
1813/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1814static void alc_auto_parse_digital(struct hda_codec *codec)
1815{
1816 struct alc_spec *spec = codec->spec;
1817 int i, err;
1818 hda_nid_t dig_nid;
1819
1820 /* support multiple SPDIFs; the secondary is set up as a slave */
1821 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1822 err = snd_hda_get_connections(codec,
1823 spec->autocfg.dig_out_pins[i],
1824 &dig_nid, 1);
1825 if (err < 0)
1826 continue;
1827 if (!i) {
1828 spec->multiout.dig_out_nid = dig_nid;
1829 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1830 } else {
1831 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1832 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1833 break;
1834 spec->slave_dig_outs[i - 1] = dig_nid;
1835 }
1836 }
1837
1838 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
1839 dig_nid = codec->start_nid;
1840 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1841 unsigned int wcaps = get_wcaps(codec, dig_nid);
1842 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1843 continue;
1844 if (!(wcaps & AC_WCAP_DIGITAL))
1845 continue;
1846 if (!(wcaps & AC_WCAP_CONN_LIST))
1847 continue;
1848 err = get_connection_index(codec, dig_nid,
1849 spec->autocfg.dig_in_pin);
1850 if (err >= 0) {
1851 spec->dig_in_nid = dig_nid;
1852 break;
1853 }
1854 }
757899ac
TI
1855 }
1856}
1857
ef8ef5fb
VP
1858/*
1859 * ALC888
1860 */
1861
1862/*
1863 * 2ch mode
1864 */
1865static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1866/* Mic-in jack as mic in */
1867 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1868 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1869/* Line-in jack as Line in */
1870 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1871 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1872/* Line-Out as Front */
1873 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1874 { } /* end */
1875};
1876
1877/*
1878 * 4ch mode
1879 */
1880static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1881/* Mic-in jack as mic in */
1882 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1883 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1884/* Line-in jack as Surround */
1885 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1886 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1887/* Line-Out as Front */
1888 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1889 { } /* end */
1890};
1891
1892/*
1893 * 6ch mode
1894 */
1895static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1896/* Mic-in jack as CLFE */
1897 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1898 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1899/* Line-in jack as Surround */
1900 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1901 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1902/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1903 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1904 { } /* end */
1905};
1906
1907/*
1908 * 8ch mode
1909 */
1910static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1911/* Mic-in jack as CLFE */
1912 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1913 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1914/* Line-in jack as Surround */
1915 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1916 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1917/* Line-Out as Side */
1918 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1919 { } /* end */
1920};
1921
1922static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1923 { 2, alc888_4ST_ch2_intel_init },
1924 { 4, alc888_4ST_ch4_intel_init },
1925 { 6, alc888_4ST_ch6_intel_init },
1926 { 8, alc888_4ST_ch8_intel_init },
1927};
1928
1929/*
1930 * ALC888 Fujitsu Siemens Amillo xa3530
1931 */
1932
1933static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1934/* Front Mic: set to PIN_IN (empty by default) */
1935 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1936/* Connect Internal HP to Front */
1937 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1938 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1939 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1940/* Connect Bass HP to Front */
1941 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1942 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1943 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1944/* Connect Line-Out side jack (SPDIF) to Side */
1945 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1946 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1947 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1948/* Connect Mic jack to CLFE */
1949 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1950 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1951 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1952/* Connect Line-in jack to Surround */
1953 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1954 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1955 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1956/* Connect HP out jack to Front */
1957 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1958 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1959 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1960/* Enable unsolicited event for HP jack and Line-out jack */
1961 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1962 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1963 {}
1964};
1965
a9fd4f3f 1966static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1967{
bb35febd 1968 alc_automute_speaker(codec, 0);
ef8ef5fb
VP
1969}
1970
a9fd4f3f
TI
1971static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1972 unsigned int res)
ef8ef5fb 1973{
a9fd4f3f
TI
1974 if (codec->vendor_id == 0x10ec0880)
1975 res >>= 28;
1976 else
1977 res >>= 26;
1978 if (res == ALC880_HP_EVENT)
1979 alc_automute_amp(codec);
ef8ef5fb
VP
1980}
1981
4f5d1706 1982static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1983{
1984 struct alc_spec *spec = codec->spec;
1985
1986 spec->autocfg.hp_pins[0] = 0x15;
1987 spec->autocfg.speaker_pins[0] = 0x14;
1988 spec->autocfg.speaker_pins[1] = 0x16;
1989 spec->autocfg.speaker_pins[2] = 0x17;
1990 spec->autocfg.speaker_pins[3] = 0x19;
1991 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1992}
1993
1994static void alc889_intel_init_hook(struct hda_codec *codec)
1995{
1996 alc889_coef_init(codec);
4f5d1706 1997 alc_automute_amp(codec);
6732bd0d
WF
1998}
1999
4f5d1706 2000static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2001{
2002 struct alc_spec *spec = codec->spec;
2003
2004 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2005 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2006 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2007 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 2008}
ef8ef5fb 2009
5b2d1eca
VP
2010/*
2011 * ALC888 Acer Aspire 4930G model
2012 */
2013
2014static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2015/* Front Mic: set to PIN_IN (empty by default) */
2016 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2017/* Unselect Front Mic by default in input mixer 3 */
2018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2019/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2020 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2021/* Connect Internal HP to front */
2022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2023 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2024 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2025/* Connect HP out to front */
2026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2028 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2029 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2030 { }
2031};
2032
d2fd4b09
TV
2033/*
2034 * ALC888 Acer Aspire 6530G model
2035 */
2036
2037static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2038/* Route to built-in subwoofer as well as speakers */
2039 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2040 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2041 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2043/* Bias voltage on for external mic port */
2044 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2045/* Front Mic: set to PIN_IN (empty by default) */
2046 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2047/* Unselect Front Mic by default in input mixer 3 */
2048 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2049/* Enable unsolicited event for HP jack */
2050 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2051/* Enable speaker output */
2052 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2053 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2054 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2055/* Enable headphone output */
2056 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2058 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2059 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2060 { }
2061};
2062
d9477207
DK
2063/*
2064 *ALC888 Acer Aspire 7730G model
2065 */
2066
2067static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2068/* Bias voltage on for external mic port */
2069 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2070/* Front Mic: set to PIN_IN (empty by default) */
2071 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2072/* Unselect Front Mic by default in input mixer 3 */
2073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2074/* Enable unsolicited event for HP jack */
2075 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2076/* Enable speaker output */
2077 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2078 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2079 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2080/* Enable headphone output */
2081 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2082 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2084 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2085/*Enable internal subwoofer */
2086 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2087 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2088 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2089 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2090 { }
2091};
2092
3b315d70 2093/*
018df418 2094 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2095 */
2096
018df418 2097static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2098/* Front Mic: set to PIN_IN (empty by default) */
2099 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2100/* Unselect Front Mic by default in input mixer 3 */
2101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2102/* Enable unsolicited event for HP jack */
2103 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2104/* Connect Internal Front to Front */
2105 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2107 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2108/* Connect Internal Rear to Rear */
2109 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2110 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2111 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2112/* Connect Internal CLFE to CLFE */
2113 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2114 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2115 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2116/* Connect HP out to Front */
018df418 2117 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2118 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2119 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2120/* Enable all DACs */
2121/* DAC DISABLE/MUTE 1? */
2122/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2123 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2124 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2125/* DAC DISABLE/MUTE 2? */
2126/* some bit here disables the other DACs. Init=0x4900 */
2127 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2128 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2129/* DMIC fix
2130 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2131 * which makes the stereo useless. However, either the mic or the ALC889
2132 * makes the signal become a difference/sum signal instead of standard
2133 * stereo, which is annoying. So instead we flip this bit which makes the
2134 * codec replicate the sum signal to both channels, turning it into a
2135 * normal mono mic.
2136 */
2137/* DMIC_CONTROL? Init value = 0x0001 */
2138 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2139 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2140 { }
2141};
2142
ef8ef5fb 2143static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2144 /* Front mic only available on one ADC */
2145 {
2146 .num_items = 4,
2147 .items = {
2148 { "Mic", 0x0 },
2149 { "Line", 0x2 },
2150 { "CD", 0x4 },
2151 { "Front Mic", 0xb },
2152 },
2153 },
2154 {
2155 .num_items = 3,
2156 .items = {
2157 { "Mic", 0x0 },
2158 { "Line", 0x2 },
2159 { "CD", 0x4 },
2160 },
2161 }
2162};
2163
d2fd4b09
TV
2164static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2165 /* Interal mic only available on one ADC */
2166 {
684a8842 2167 .num_items = 5,
d2fd4b09 2168 .items = {
8607f7c4 2169 { "Mic", 0x0 },
684a8842 2170 { "Line In", 0x2 },
d2fd4b09 2171 { "CD", 0x4 },
684a8842 2172 { "Input Mix", 0xa },
28c4edb7 2173 { "Internal Mic", 0xb },
d2fd4b09
TV
2174 },
2175 },
2176 {
684a8842 2177 .num_items = 4,
d2fd4b09 2178 .items = {
8607f7c4 2179 { "Mic", 0x0 },
684a8842 2180 { "Line In", 0x2 },
d2fd4b09 2181 { "CD", 0x4 },
684a8842 2182 { "Input Mix", 0xa },
d2fd4b09
TV
2183 },
2184 }
2185};
2186
018df418
HM
2187static struct hda_input_mux alc889_capture_sources[3] = {
2188 /* Digital mic only available on first "ADC" */
2189 {
2190 .num_items = 5,
2191 .items = {
2192 { "Mic", 0x0 },
2193 { "Line", 0x2 },
2194 { "CD", 0x4 },
2195 { "Front Mic", 0xb },
2196 { "Input Mix", 0xa },
2197 },
2198 },
2199 {
2200 .num_items = 4,
2201 .items = {
2202 { "Mic", 0x0 },
2203 { "Line", 0x2 },
2204 { "CD", 0x4 },
2205 { "Input Mix", 0xa },
2206 },
2207 },
2208 {
2209 .num_items = 4,
2210 .items = {
2211 { "Mic", 0x0 },
2212 { "Line", 0x2 },
2213 { "CD", 0x4 },
2214 { "Input Mix", 0xa },
2215 },
2216 }
2217};
2218
ef8ef5fb 2219static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2222 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2223 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2225 HDA_OUTPUT),
2226 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2229 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2230 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2238 { } /* end */
2239};
2240
556eea9a
HM
2241static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2242 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2243 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2244 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2245 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2246 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2247 HDA_OUTPUT),
2248 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2249 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2250 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2254 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2256 { } /* end */
2257};
2258
2259
4f5d1706 2260static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2261{
a9fd4f3f 2262 struct alc_spec *spec = codec->spec;
5b2d1eca 2263
a9fd4f3f
TI
2264 spec->autocfg.hp_pins[0] = 0x15;
2265 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2266 spec->autocfg.speaker_pins[1] = 0x16;
2267 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2268}
2269
4f5d1706 2270static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2271{
2272 struct alc_spec *spec = codec->spec;
2273
2274 spec->autocfg.hp_pins[0] = 0x15;
2275 spec->autocfg.speaker_pins[0] = 0x14;
2276 spec->autocfg.speaker_pins[1] = 0x16;
2277 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2278}
2279
d9477207
DK
2280static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2281{
2282 struct alc_spec *spec = codec->spec;
2283
2284 spec->autocfg.hp_pins[0] = 0x15;
2285 spec->autocfg.speaker_pins[0] = 0x14;
2286 spec->autocfg.speaker_pins[1] = 0x16;
2287 spec->autocfg.speaker_pins[2] = 0x17;
2288}
2289
4f5d1706 2290static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2291{
2292 struct alc_spec *spec = codec->spec;
2293
2294 spec->autocfg.hp_pins[0] = 0x15;
2295 spec->autocfg.speaker_pins[0] = 0x14;
2296 spec->autocfg.speaker_pins[1] = 0x16;
2297 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2298}
2299
1da177e4 2300/*
e9edcee0
TI
2301 * ALC880 3-stack model
2302 *
2303 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2304 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2305 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2306 */
2307
e9edcee0
TI
2308static hda_nid_t alc880_dac_nids[4] = {
2309 /* front, rear, clfe, rear_surr */
2310 0x02, 0x05, 0x04, 0x03
2311};
2312
2313static hda_nid_t alc880_adc_nids[3] = {
2314 /* ADC0-2 */
2315 0x07, 0x08, 0x09,
2316};
2317
2318/* The datasheet says the node 0x07 is connected from inputs,
2319 * but it shows zero connection in the real implementation on some devices.
df694daa 2320 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2321 */
e9edcee0
TI
2322static hda_nid_t alc880_adc_nids_alt[2] = {
2323 /* ADC1-2 */
2324 0x08, 0x09,
2325};
2326
2327#define ALC880_DIGOUT_NID 0x06
2328#define ALC880_DIGIN_NID 0x0a
2329
2330static struct hda_input_mux alc880_capture_source = {
2331 .num_items = 4,
2332 .items = {
2333 { "Mic", 0x0 },
2334 { "Front Mic", 0x3 },
2335 { "Line", 0x2 },
2336 { "CD", 0x4 },
2337 },
2338};
2339
2340/* channel source setting (2/6 channel selection for 3-stack) */
2341/* 2ch mode */
2342static struct hda_verb alc880_threestack_ch2_init[] = {
2343 /* set line-in to input, mute it */
2344 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2345 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2346 /* set mic-in to input vref 80%, mute it */
2347 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2348 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2349 { } /* end */
2350};
2351
2352/* 6ch mode */
2353static struct hda_verb alc880_threestack_ch6_init[] = {
2354 /* set line-in to output, unmute it */
2355 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2356 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2357 /* set mic-in to output, unmute it */
2358 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2359 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2360 { } /* end */
2361};
2362
d2a6d7dc 2363static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2364 { 2, alc880_threestack_ch2_init },
2365 { 6, alc880_threestack_ch6_init },
2366};
2367
c8b6bf9b 2368static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2369 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2370 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2371 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2372 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2373 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2374 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2375 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2376 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2377 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2378 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2379 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2380 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2383 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2384 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2385 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2386 {
2387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2388 .name = "Channel Mode",
df694daa
KY
2389 .info = alc_ch_mode_info,
2390 .get = alc_ch_mode_get,
2391 .put = alc_ch_mode_put,
e9edcee0
TI
2392 },
2393 { } /* end */
2394};
2395
2396/* capture mixer elements */
f9e336f6
TI
2397static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2398 struct snd_ctl_elem_info *uinfo)
2399{
2400 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2401 struct alc_spec *spec = codec->spec;
2402 int err;
1da177e4 2403
5a9e02e9 2404 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2405 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2406 HDA_INPUT);
2407 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2408 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2409 return err;
2410}
2411
2412static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2413 unsigned int size, unsigned int __user *tlv)
2414{
2415 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2416 struct alc_spec *spec = codec->spec;
2417 int err;
1da177e4 2418
5a9e02e9 2419 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2420 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2421 HDA_INPUT);
2422 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2423 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2424 return err;
2425}
2426
2427typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2428 struct snd_ctl_elem_value *ucontrol);
2429
2430static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2431 struct snd_ctl_elem_value *ucontrol,
2432 getput_call_t func)
2433{
2434 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2435 struct alc_spec *spec = codec->spec;
2436 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2437 int err;
2438
5a9e02e9 2439 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2440 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2441 3, 0, HDA_INPUT);
2442 err = func(kcontrol, ucontrol);
5a9e02e9 2443 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2444 return err;
2445}
2446
2447static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2448 struct snd_ctl_elem_value *ucontrol)
2449{
2450 return alc_cap_getput_caller(kcontrol, ucontrol,
2451 snd_hda_mixer_amp_volume_get);
2452}
2453
2454static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2455 struct snd_ctl_elem_value *ucontrol)
2456{
2457 return alc_cap_getput_caller(kcontrol, ucontrol,
2458 snd_hda_mixer_amp_volume_put);
2459}
2460
2461/* capture mixer elements */
2462#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2463
2464static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2465 struct snd_ctl_elem_value *ucontrol)
2466{
2467 return alc_cap_getput_caller(kcontrol, ucontrol,
2468 snd_hda_mixer_amp_switch_get);
2469}
2470
2471static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2472 struct snd_ctl_elem_value *ucontrol)
2473{
2474 return alc_cap_getput_caller(kcontrol, ucontrol,
2475 snd_hda_mixer_amp_switch_put);
2476}
2477
a23b688f 2478#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2479 { \
2480 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2481 .name = "Capture Switch", \
2482 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2483 .count = num, \
2484 .info = alc_cap_sw_info, \
2485 .get = alc_cap_sw_get, \
2486 .put = alc_cap_sw_put, \
2487 }, \
2488 { \
2489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2490 .name = "Capture Volume", \
2491 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2492 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2493 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2494 .count = num, \
2495 .info = alc_cap_vol_info, \
2496 .get = alc_cap_vol_get, \
2497 .put = alc_cap_vol_put, \
2498 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2499 }
2500
2501#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2502 { \
2503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2504 /* .name = "Capture Source", */ \
2505 .name = "Input Source", \
2506 .count = num, \
2507 .info = alc_mux_enum_info, \
2508 .get = alc_mux_enum_get, \
2509 .put = alc_mux_enum_put, \
a23b688f
TI
2510 }
2511
2512#define DEFINE_CAPMIX(num) \
2513static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2514 _DEFINE_CAPMIX(num), \
2515 _DEFINE_CAPSRC(num), \
2516 { } /* end */ \
2517}
2518
2519#define DEFINE_CAPMIX_NOSRC(num) \
2520static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2521 _DEFINE_CAPMIX(num), \
2522 { } /* end */ \
f9e336f6
TI
2523}
2524
2525/* up to three ADCs */
2526DEFINE_CAPMIX(1);
2527DEFINE_CAPMIX(2);
2528DEFINE_CAPMIX(3);
a23b688f
TI
2529DEFINE_CAPMIX_NOSRC(1);
2530DEFINE_CAPMIX_NOSRC(2);
2531DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2532
2533/*
2534 * ALC880 5-stack model
2535 *
9c7f852e
TI
2536 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2537 * Side = 0x02 (0xd)
e9edcee0
TI
2538 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2539 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2540 */
2541
2542/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2543static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2544 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2545 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2546 { } /* end */
2547};
2548
e9edcee0
TI
2549/* channel source setting (6/8 channel selection for 5-stack) */
2550/* 6ch mode */
2551static struct hda_verb alc880_fivestack_ch6_init[] = {
2552 /* set line-in to input, mute it */
2553 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2554 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2555 { } /* end */
2556};
2557
e9edcee0
TI
2558/* 8ch mode */
2559static struct hda_verb alc880_fivestack_ch8_init[] = {
2560 /* set line-in to output, unmute it */
2561 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2562 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2563 { } /* end */
2564};
2565
d2a6d7dc 2566static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2567 { 6, alc880_fivestack_ch6_init },
2568 { 8, alc880_fivestack_ch8_init },
2569};
2570
2571
2572/*
2573 * ALC880 6-stack model
2574 *
9c7f852e
TI
2575 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2576 * Side = 0x05 (0x0f)
e9edcee0
TI
2577 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2578 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2579 */
2580
2581static hda_nid_t alc880_6st_dac_nids[4] = {
2582 /* front, rear, clfe, rear_surr */
2583 0x02, 0x03, 0x04, 0x05
f12ab1e0 2584};
e9edcee0
TI
2585
2586static struct hda_input_mux alc880_6stack_capture_source = {
2587 .num_items = 4,
2588 .items = {
2589 { "Mic", 0x0 },
2590 { "Front Mic", 0x1 },
2591 { "Line", 0x2 },
2592 { "CD", 0x4 },
2593 },
2594};
2595
2596/* fixed 8-channels */
d2a6d7dc 2597static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2598 { 8, NULL },
2599};
2600
c8b6bf9b 2601static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2602 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2603 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2604 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2605 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2606 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2607 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2608 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2609 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2610 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2611 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2612 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2613 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2614 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2615 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2618 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2619 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2620 {
2621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2622 .name = "Channel Mode",
df694daa
KY
2623 .info = alc_ch_mode_info,
2624 .get = alc_ch_mode_get,
2625 .put = alc_ch_mode_put,
16ded525
TI
2626 },
2627 { } /* end */
2628};
2629
e9edcee0
TI
2630
2631/*
2632 * ALC880 W810 model
2633 *
2634 * W810 has rear IO for:
2635 * Front (DAC 02)
2636 * Surround (DAC 03)
2637 * Center/LFE (DAC 04)
2638 * Digital out (06)
2639 *
2640 * The system also has a pair of internal speakers, and a headphone jack.
2641 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2642 *
e9edcee0
TI
2643 * There is a variable resistor to control the speaker or headphone
2644 * volume. This is a hardware-only device without a software API.
2645 *
2646 * Plugging headphones in will disable the internal speakers. This is
2647 * implemented in hardware, not via the driver using jack sense. In
2648 * a similar fashion, plugging into the rear socket marked "front" will
2649 * disable both the speakers and headphones.
2650 *
2651 * For input, there's a microphone jack, and an "audio in" jack.
2652 * These may not do anything useful with this driver yet, because I
2653 * haven't setup any initialization verbs for these yet...
2654 */
2655
2656static hda_nid_t alc880_w810_dac_nids[3] = {
2657 /* front, rear/surround, clfe */
2658 0x02, 0x03, 0x04
16ded525
TI
2659};
2660
e9edcee0 2661/* fixed 6 channels */
d2a6d7dc 2662static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2663 { 6, NULL }
2664};
2665
2666/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2667static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2668 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2669 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2670 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2671 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2672 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2673 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2674 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2675 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2676 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2677 { } /* end */
2678};
2679
2680
2681/*
2682 * Z710V model
2683 *
2684 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2685 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2686 * Line = 0x1a
e9edcee0
TI
2687 */
2688
2689static hda_nid_t alc880_z71v_dac_nids[1] = {
2690 0x02
2691};
2692#define ALC880_Z71V_HP_DAC 0x03
2693
2694/* fixed 2 channels */
d2a6d7dc 2695static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2696 { 2, NULL }
2697};
2698
c8b6bf9b 2699static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2700 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2701 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2702 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2703 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2704 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2705 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2708 { } /* end */
2709};
2710
e9edcee0 2711
e9edcee0
TI
2712/*
2713 * ALC880 F1734 model
2714 *
2715 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2716 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2717 */
2718
2719static hda_nid_t alc880_f1734_dac_nids[1] = {
2720 0x03
2721};
2722#define ALC880_F1734_HP_DAC 0x02
2723
c8b6bf9b 2724static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2725 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2726 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2727 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2728 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2729 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2730 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2731 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2732 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2733 { } /* end */
2734};
2735
937b4160
TI
2736static struct hda_input_mux alc880_f1734_capture_source = {
2737 .num_items = 2,
2738 .items = {
2739 { "Mic", 0x1 },
2740 { "CD", 0x4 },
2741 },
2742};
2743
e9edcee0 2744
e9edcee0
TI
2745/*
2746 * ALC880 ASUS model
2747 *
2748 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2749 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2750 * Mic = 0x18, Line = 0x1a
2751 */
2752
2753#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2754#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2755
c8b6bf9b 2756static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2757 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2758 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2759 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2760 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2761 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2762 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2763 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2764 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2765 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2766 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2767 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2768 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2771 {
2772 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2773 .name = "Channel Mode",
df694daa
KY
2774 .info = alc_ch_mode_info,
2775 .get = alc_ch_mode_get,
2776 .put = alc_ch_mode_put,
16ded525
TI
2777 },
2778 { } /* end */
2779};
e9edcee0 2780
e9edcee0
TI
2781/*
2782 * ALC880 ASUS W1V model
2783 *
2784 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2785 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2786 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2787 */
2788
2789/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2790static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2791 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2792 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2793 { } /* end */
2794};
2795
df694daa
KY
2796/* TCL S700 */
2797static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2798 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2799 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2800 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2801 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2802 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2805 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2806 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2807 { } /* end */
2808};
2809
ccc656ce
KY
2810/* Uniwill */
2811static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2812 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2813 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2814 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2815 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2816 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2817 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2818 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2819 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2820 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2821 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2822 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2823 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2824 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2826 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2827 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2828 {
2829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2830 .name = "Channel Mode",
2831 .info = alc_ch_mode_info,
2832 .get = alc_ch_mode_get,
2833 .put = alc_ch_mode_put,
2834 },
2835 { } /* end */
2836};
2837
2cf9f0fc
TD
2838static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2839 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2840 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2841 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2842 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2843 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2844 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
2845 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2846 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
2847 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2848 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
2849 { } /* end */
2850};
2851
ccc656ce 2852static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2853 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2854 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2855 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2856 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2859 { } /* end */
2860};
2861
2134ea4f
TI
2862/*
2863 * virtual master controls
2864 */
2865
2866/*
2867 * slave controls for virtual master
2868 */
2869static const char *alc_slave_vols[] = {
2870 "Front Playback Volume",
2871 "Surround Playback Volume",
2872 "Center Playback Volume",
2873 "LFE Playback Volume",
2874 "Side Playback Volume",
2875 "Headphone Playback Volume",
2876 "Speaker Playback Volume",
2877 "Mono Playback Volume",
2134ea4f 2878 "Line-Out Playback Volume",
26f5df26 2879 "PCM Playback Volume",
2134ea4f
TI
2880 NULL,
2881};
2882
2883static const char *alc_slave_sws[] = {
2884 "Front Playback Switch",
2885 "Surround Playback Switch",
2886 "Center Playback Switch",
2887 "LFE Playback Switch",
2888 "Side Playback Switch",
2889 "Headphone Playback Switch",
2890 "Speaker Playback Switch",
2891 "Mono Playback Switch",
edb54a55 2892 "IEC958 Playback Switch",
23033b2b
TI
2893 "Line-Out Playback Switch",
2894 "PCM Playback Switch",
2134ea4f
TI
2895 NULL,
2896};
2897
1da177e4 2898/*
e9edcee0 2899 * build control elements
1da177e4 2900 */
603c4019 2901
5b0cb1d8
JK
2902#define NID_MAPPING (-1)
2903
2904#define SUBDEV_SPEAKER_ (0 << 6)
2905#define SUBDEV_HP_ (1 << 6)
2906#define SUBDEV_LINE_ (2 << 6)
2907#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2908#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2909#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2910
603c4019
TI
2911static void alc_free_kctls(struct hda_codec *codec);
2912
67d634c0 2913#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2914/* additional beep mixers; the actual parameters are overwritten at build */
2915static struct snd_kcontrol_new alc_beep_mixer[] = {
2916 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2917 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2918 { } /* end */
2919};
67d634c0 2920#endif
45bdd1c1 2921
1da177e4
LT
2922static int alc_build_controls(struct hda_codec *codec)
2923{
2924 struct alc_spec *spec = codec->spec;
2f44f847 2925 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2926 struct snd_kcontrol_new *knew;
2927 int i, j, err;
2928 unsigned int u;
2929 hda_nid_t nid;
1da177e4
LT
2930
2931 for (i = 0; i < spec->num_mixers; i++) {
2932 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2933 if (err < 0)
2934 return err;
2935 }
f9e336f6
TI
2936 if (spec->cap_mixer) {
2937 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2938 if (err < 0)
2939 return err;
2940 }
1da177e4 2941 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2942 err = snd_hda_create_spdif_out_ctls(codec,
2943 spec->multiout.dig_out_nid);
1da177e4
LT
2944 if (err < 0)
2945 return err;
e64f14f4
TI
2946 if (!spec->no_analog) {
2947 err = snd_hda_create_spdif_share_sw(codec,
2948 &spec->multiout);
2949 if (err < 0)
2950 return err;
2951 spec->multiout.share_spdif = 1;
2952 }
1da177e4
LT
2953 }
2954 if (spec->dig_in_nid) {
2955 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2956 if (err < 0)
2957 return err;
2958 }
2134ea4f 2959
67d634c0 2960#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2961 /* create beep controls if needed */
2962 if (spec->beep_amp) {
2963 struct snd_kcontrol_new *knew;
2964 for (knew = alc_beep_mixer; knew->name; knew++) {
2965 struct snd_kcontrol *kctl;
2966 kctl = snd_ctl_new1(knew, codec);
2967 if (!kctl)
2968 return -ENOMEM;
2969 kctl->private_value = spec->beep_amp;
5e26dfd0 2970 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2971 if (err < 0)
2972 return err;
2973 }
2974 }
67d634c0 2975#endif
45bdd1c1 2976
2134ea4f 2977 /* if we have no master control, let's create it */
e64f14f4
TI
2978 if (!spec->no_analog &&
2979 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2980 unsigned int vmaster_tlv[4];
2134ea4f 2981 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2982 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2983 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2984 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2985 if (err < 0)
2986 return err;
2987 }
e64f14f4
TI
2988 if (!spec->no_analog &&
2989 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2990 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2991 NULL, alc_slave_sws);
2992 if (err < 0)
2993 return err;
2994 }
2995
5b0cb1d8 2996 /* assign Capture Source enums to NID */
fbe618f2
TI
2997 if (spec->capsrc_nids || spec->adc_nids) {
2998 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2999 if (!kctl)
3000 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3001 for (i = 0; kctl && i < kctl->count; i++) {
3002 hda_nid_t *nids = spec->capsrc_nids;
3003 if (!nids)
3004 nids = spec->adc_nids;
3005 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3006 if (err < 0)
3007 return err;
3008 }
5b0cb1d8
JK
3009 }
3010 if (spec->cap_mixer) {
3011 const char *kname = kctl ? kctl->id.name : NULL;
3012 for (knew = spec->cap_mixer; knew->name; knew++) {
3013 if (kname && strcmp(knew->name, kname) == 0)
3014 continue;
3015 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3016 for (i = 0; kctl && i < kctl->count; i++) {
3017 err = snd_hda_add_nid(codec, kctl, i,
3018 spec->adc_nids[i]);
3019 if (err < 0)
3020 return err;
3021 }
3022 }
3023 }
3024
3025 /* other nid->control mapping */
3026 for (i = 0; i < spec->num_mixers; i++) {
3027 for (knew = spec->mixers[i]; knew->name; knew++) {
3028 if (knew->iface != NID_MAPPING)
3029 continue;
3030 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3031 if (kctl == NULL)
3032 continue;
3033 u = knew->subdevice;
3034 for (j = 0; j < 4; j++, u >>= 8) {
3035 nid = u & 0x3f;
3036 if (nid == 0)
3037 continue;
3038 switch (u & 0xc0) {
3039 case SUBDEV_SPEAKER_:
3040 nid = spec->autocfg.speaker_pins[nid];
3041 break;
3042 case SUBDEV_LINE_:
3043 nid = spec->autocfg.line_out_pins[nid];
3044 break;
3045 case SUBDEV_HP_:
3046 nid = spec->autocfg.hp_pins[nid];
3047 break;
3048 default:
3049 continue;
3050 }
3051 err = snd_hda_add_nid(codec, kctl, 0, nid);
3052 if (err < 0)
3053 return err;
3054 }
3055 u = knew->private_value;
3056 for (j = 0; j < 4; j++, u >>= 8) {
3057 nid = u & 0xff;
3058 if (nid == 0)
3059 continue;
3060 err = snd_hda_add_nid(codec, kctl, 0, nid);
3061 if (err < 0)
3062 return err;
3063 }
3064 }
3065 }
bae84e70
TI
3066
3067 alc_free_kctls(codec); /* no longer needed */
3068
1da177e4
LT
3069 return 0;
3070}
3071
e9edcee0 3072
1da177e4
LT
3073/*
3074 * initialize the codec volumes, etc
3075 */
3076
e9edcee0
TI
3077/*
3078 * generic initialization of ADC, input mixers and output mixers
3079 */
3080static struct hda_verb alc880_volume_init_verbs[] = {
3081 /*
3082 * Unmute ADC0-2 and set the default input to mic-in
3083 */
71fe7b82 3084 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3086 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3087 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3088 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3090
e9edcee0
TI
3091 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3092 * mixer widget
9c7f852e
TI
3093 * Note: PASD motherboards uses the Line In 2 as the input for front
3094 * panel mic (mic 2)
1da177e4 3095 */
e9edcee0 3096 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3104
e9edcee0
TI
3105 /*
3106 * Set up output mixers (0x0c - 0x0f)
1da177e4 3107 */
e9edcee0
TI
3108 /* set vol=0 to output mixers */
3109 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3110 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3112 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3113 /* set up input amps for analog loopback */
3114 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3117 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3118 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3119 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3120 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3121 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3122 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3123
3124 { }
3125};
3126
e9edcee0
TI
3127/*
3128 * 3-stack pin configuration:
3129 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3130 */
3131static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3132 /*
3133 * preset connection lists of input pins
3134 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3135 */
3136 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3137 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3138 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3139
3140 /*
3141 * Set pin mode and muting
3142 */
3143 /* set front pin widgets 0x14 for output */
05acb863 3144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3145 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3146 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3147 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3148 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3149 /* Mic2 (as headphone out) for HP output */
3150 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3151 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3152 /* Line In pin widget for input */
05acb863 3153 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3154 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3155 /* Line2 (as front mic) pin widget for input and vref at 80% */
3156 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3157 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3158 /* CD pin widget for input */
05acb863 3159 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3160
e9edcee0
TI
3161 { }
3162};
1da177e4 3163
e9edcee0
TI
3164/*
3165 * 5-stack pin configuration:
3166 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3167 * line-in/side = 0x1a, f-mic = 0x1b
3168 */
3169static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3170 /*
3171 * preset connection lists of input pins
3172 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3173 */
e9edcee0
TI
3174 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3175 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3176
e9edcee0
TI
3177 /*
3178 * Set pin mode and muting
1da177e4 3179 */
e9edcee0
TI
3180 /* set pin widgets 0x14-0x17 for output */
3181 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3184 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3185 /* unmute pins for output (no gain on this amp) */
3186 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3188 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3189 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3190
3191 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3192 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3193 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3194 /* Mic2 (as headphone out) for HP output */
3195 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3196 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3197 /* Line In pin widget for input */
3198 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3199 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3200 /* Line2 (as front mic) pin widget for input and vref at 80% */
3201 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3202 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3203 /* CD pin widget for input */
3204 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3205
3206 { }
3207};
3208
e9edcee0
TI
3209/*
3210 * W810 pin configuration:
3211 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3212 */
3213static struct hda_verb alc880_pin_w810_init_verbs[] = {
3214 /* hphone/speaker input selector: front DAC */
3215 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3216
05acb863 3217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3220 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3221 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3222 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3223
e9edcee0 3224 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3225 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3226
1da177e4
LT
3227 { }
3228};
3229
e9edcee0
TI
3230/*
3231 * Z71V pin configuration:
3232 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3233 */
3234static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3235 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3236 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3237 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3238 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3239
16ded525 3240 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3241 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3242 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3243 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3244
3245 { }
3246};
3247
e9edcee0
TI
3248/*
3249 * 6-stack pin configuration:
9c7f852e
TI
3250 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3251 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3252 */
3253static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3254 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3255
16ded525 3256 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3257 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3258 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3259 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3260 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3261 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3262 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3263 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3264
16ded525 3265 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3266 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3267 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3269 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3270 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3272 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3273 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3274
e9edcee0
TI
3275 { }
3276};
3277
ccc656ce
KY
3278/*
3279 * Uniwill pin configuration:
3280 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3281 * line = 0x1a
3282 */
3283static struct hda_verb alc880_uniwill_init_verbs[] = {
3284 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3285
3286 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3287 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3290 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3291 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3292 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3293 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3296 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3297 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3298 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3299 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3300
3301 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3302 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3303 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3304 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3307 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3308 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3309 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3310
3311 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3312 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3313
3314 { }
3315};
3316
3317/*
3318* Uniwill P53
ea1fb29a 3319* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3320 */
3321static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3322 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3323
3324 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3325 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3327 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3328 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3329 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3332 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3333 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3335 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3336
3337 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3339 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3340 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3341 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3343
3344 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3345 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3346
3347 { }
3348};
3349
2cf9f0fc
TD
3350static struct hda_verb alc880_beep_init_verbs[] = {
3351 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3352 { }
3353};
3354
458a4fab 3355/* auto-toggle front mic */
eeb43387 3356static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3357{
3358 unsigned int present;
3359 unsigned char bits;
ccc656ce 3360
864f92be 3361 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3362 bits = present ? HDA_AMP_MUTE : 0;
3363 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3364}
3365
4f5d1706 3366static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3367{
a9fd4f3f
TI
3368 struct alc_spec *spec = codec->spec;
3369
3370 spec->autocfg.hp_pins[0] = 0x14;
3371 spec->autocfg.speaker_pins[0] = 0x15;
3372 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3373}
3374
3375static void alc880_uniwill_init_hook(struct hda_codec *codec)
3376{
a9fd4f3f 3377 alc_automute_amp(codec);
eeb43387 3378 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3379}
3380
3381static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3382 unsigned int res)
3383{
3384 /* Looks like the unsol event is incompatible with the standard
3385 * definition. 4bit tag is placed at 28 bit!
3386 */
458a4fab 3387 switch (res >> 28) {
458a4fab 3388 case ALC880_MIC_EVENT:
eeb43387 3389 alc88x_simple_mic_automute(codec);
458a4fab 3390 break;
a9fd4f3f
TI
3391 default:
3392 alc_automute_amp_unsol_event(codec, res);
3393 break;
458a4fab 3394 }
ccc656ce
KY
3395}
3396
4f5d1706 3397static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3398{
a9fd4f3f 3399 struct alc_spec *spec = codec->spec;
ccc656ce 3400
a9fd4f3f
TI
3401 spec->autocfg.hp_pins[0] = 0x14;
3402 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3403}
3404
3405static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3406{
3407 unsigned int present;
ea1fb29a 3408
ccc656ce 3409 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3410 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3411 present &= HDA_AMP_VOLMASK;
3412 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3413 HDA_AMP_VOLMASK, present);
3414 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3415 HDA_AMP_VOLMASK, present);
ccc656ce 3416}
47fd830a 3417
ccc656ce
KY
3418static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3419 unsigned int res)
3420{
3421 /* Looks like the unsol event is incompatible with the standard
3422 * definition. 4bit tag is placed at 28 bit!
3423 */
f12ab1e0 3424 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3425 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3426 else
3427 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3428}
3429
e9edcee0
TI
3430/*
3431 * F1734 pin configuration:
3432 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3433 */
3434static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3435 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3436 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3437 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3438 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3439 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3440
e9edcee0 3441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3442 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3443 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3444 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3445
e9edcee0
TI
3446 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3447 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3448 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3449 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3450 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3451 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3452 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3453 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3454 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3455
937b4160
TI
3456 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3457 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3458
dfc0ff62
TI
3459 { }
3460};
3461
e9edcee0
TI
3462/*
3463 * ASUS pin configuration:
3464 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3465 */
3466static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3467 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3468 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3469 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3470 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3471
3472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3474 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3475 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3476 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3477 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3478 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3479 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3480
3481 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3482 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3483 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3488 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3489 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3490
e9edcee0
TI
3491 { }
3492};
16ded525 3493
e9edcee0 3494/* Enable GPIO mask and set output */
bc9f98a9
KY
3495#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3496#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3497#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3498
3499/* Clevo m520g init */
3500static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3501 /* headphone output */
3502 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3503 /* line-out */
3504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3506 /* Line-in */
3507 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3508 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3509 /* CD */
3510 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3511 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3512 /* Mic1 (rear panel) */
3513 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3514 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3515 /* Mic2 (front panel) */
3516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3517 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3518 /* headphone */
3519 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3520 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3521 /* change to EAPD mode */
3522 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3523 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3524
3525 { }
16ded525
TI
3526};
3527
df694daa 3528static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3529 /* change to EAPD mode */
3530 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3531 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3532
df694daa
KY
3533 /* Headphone output */
3534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3535 /* Front output*/
3536 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3538
3539 /* Line In pin widget for input */
3540 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3541 /* CD pin widget for input */
3542 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3543 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3544 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3545
3546 /* change to EAPD mode */
3547 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3548 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3549
3550 { }
3551};
16ded525 3552
e9edcee0 3553/*
ae6b813a
TI
3554 * LG m1 express dual
3555 *
3556 * Pin assignment:
3557 * Rear Line-In/Out (blue): 0x14
3558 * Build-in Mic-In: 0x15
3559 * Speaker-out: 0x17
3560 * HP-Out (green): 0x1b
3561 * Mic-In/Out (red): 0x19
3562 * SPDIF-Out: 0x1e
3563 */
3564
3565/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3566static hda_nid_t alc880_lg_dac_nids[3] = {
3567 0x05, 0x02, 0x03
3568};
3569
3570/* seems analog CD is not working */
3571static struct hda_input_mux alc880_lg_capture_source = {
3572 .num_items = 3,
3573 .items = {
3574 { "Mic", 0x1 },
3575 { "Line", 0x5 },
3576 { "Internal Mic", 0x6 },
3577 },
3578};
3579
3580/* 2,4,6 channel modes */
3581static struct hda_verb alc880_lg_ch2_init[] = {
3582 /* set line-in and mic-in to input */
3583 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3584 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3585 { }
3586};
3587
3588static struct hda_verb alc880_lg_ch4_init[] = {
3589 /* set line-in to out and mic-in to input */
3590 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3591 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3592 { }
3593};
3594
3595static struct hda_verb alc880_lg_ch6_init[] = {
3596 /* set line-in and mic-in to output */
3597 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3598 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3599 { }
3600};
3601
3602static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3603 { 2, alc880_lg_ch2_init },
3604 { 4, alc880_lg_ch4_init },
3605 { 6, alc880_lg_ch6_init },
3606};
3607
3608static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3609 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3610 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3611 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3612 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3613 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3614 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3615 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3616 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3618 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3620 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3621 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3622 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3623 {
3624 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3625 .name = "Channel Mode",
3626 .info = alc_ch_mode_info,
3627 .get = alc_ch_mode_get,
3628 .put = alc_ch_mode_put,
3629 },
3630 { } /* end */
3631};
3632
3633static struct hda_verb alc880_lg_init_verbs[] = {
3634 /* set capture source to mic-in */
3635 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3636 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3637 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3638 /* mute all amp mixer inputs */
3639 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3640 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3642 /* line-in to input */
3643 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3644 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3645 /* built-in mic */
3646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3648 /* speaker-out */
3649 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3650 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3651 /* mic-in to input */
3652 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3655 /* HP-out */
3656 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3657 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3658 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3659 /* jack sense */
a9fd4f3f 3660 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3661 { }
3662};
3663
3664/* toggle speaker-output according to the hp-jack state */
4f5d1706 3665static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3666{
a9fd4f3f 3667 struct alc_spec *spec = codec->spec;
ae6b813a 3668
a9fd4f3f
TI
3669 spec->autocfg.hp_pins[0] = 0x1b;
3670 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3671}
3672
d681518a
TI
3673/*
3674 * LG LW20
3675 *
3676 * Pin assignment:
3677 * Speaker-out: 0x14
3678 * Mic-In: 0x18
e4f41da9
CM
3679 * Built-in Mic-In: 0x19
3680 * Line-In: 0x1b
3681 * HP-Out: 0x1a
d681518a
TI
3682 * SPDIF-Out: 0x1e
3683 */
3684
d681518a 3685static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3686 .num_items = 3,
d681518a
TI
3687 .items = {
3688 { "Mic", 0x0 },
3689 { "Internal Mic", 0x1 },
e4f41da9 3690 { "Line In", 0x2 },
d681518a
TI
3691 },
3692};
3693
0a8c5da3
CM
3694#define alc880_lg_lw_modes alc880_threestack_modes
3695
d681518a 3696static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3697 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3698 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3699 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3700 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3701 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3702 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3703 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3704 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3705 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3706 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3709 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3710 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3711 {
3712 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3713 .name = "Channel Mode",
3714 .info = alc_ch_mode_info,
3715 .get = alc_ch_mode_get,
3716 .put = alc_ch_mode_put,
3717 },
d681518a
TI
3718 { } /* end */
3719};
3720
3721static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3722 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3723 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3724 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3725
d681518a
TI
3726 /* set capture source to mic-in */
3727 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3728 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3729 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3730 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3731 /* speaker-out */
3732 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3733 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3734 /* HP-out */
d681518a
TI
3735 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3736 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3737 /* mic-in to input */
3738 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3739 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3740 /* built-in mic */
3741 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3742 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3743 /* jack sense */
a9fd4f3f 3744 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3745 { }
3746};
3747
3748/* toggle speaker-output according to the hp-jack state */
4f5d1706 3749static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3750{
a9fd4f3f 3751 struct alc_spec *spec = codec->spec;
d681518a 3752
a9fd4f3f
TI
3753 spec->autocfg.hp_pins[0] = 0x1b;
3754 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3755}
3756
df99cd33
TI
3757static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3758 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3759 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3761 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3762 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3763 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3764 { } /* end */
3765};
3766
3767static struct hda_input_mux alc880_medion_rim_capture_source = {
3768 .num_items = 2,
3769 .items = {
3770 { "Mic", 0x0 },
3771 { "Internal Mic", 0x1 },
3772 },
3773};
3774
3775static struct hda_verb alc880_medion_rim_init_verbs[] = {
3776 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3777
3778 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3779 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3780
3781 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3782 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3783 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3784 /* Mic2 (as headphone out) for HP output */
3785 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3787 /* Internal Speaker */
3788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3789 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3790
3791 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3792 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3793
3794 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3795 { }
3796};
3797
3798/* toggle speaker-output according to the hp-jack state */
3799static void alc880_medion_rim_automute(struct hda_codec *codec)
3800{
a9fd4f3f
TI
3801 struct alc_spec *spec = codec->spec;
3802 alc_automute_amp(codec);
3803 /* toggle EAPD */
3804 if (spec->jack_present)
df99cd33
TI
3805 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3806 else
3807 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3808}
3809
3810static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3811 unsigned int res)
3812{
3813 /* Looks like the unsol event is incompatible with the standard
3814 * definition. 4bit tag is placed at 28 bit!
3815 */
3816 if ((res >> 28) == ALC880_HP_EVENT)
3817 alc880_medion_rim_automute(codec);
3818}
3819
4f5d1706 3820static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3821{
3822 struct alc_spec *spec = codec->spec;
3823
3824 spec->autocfg.hp_pins[0] = 0x14;
3825 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3826}
3827
cb53c626
TI
3828#ifdef CONFIG_SND_HDA_POWER_SAVE
3829static struct hda_amp_list alc880_loopbacks[] = {
3830 { 0x0b, HDA_INPUT, 0 },
3831 { 0x0b, HDA_INPUT, 1 },
3832 { 0x0b, HDA_INPUT, 2 },
3833 { 0x0b, HDA_INPUT, 3 },
3834 { 0x0b, HDA_INPUT, 4 },
3835 { } /* end */
3836};
3837
3838static struct hda_amp_list alc880_lg_loopbacks[] = {
3839 { 0x0b, HDA_INPUT, 1 },
3840 { 0x0b, HDA_INPUT, 6 },
3841 { 0x0b, HDA_INPUT, 7 },
3842 { } /* end */
3843};
3844#endif
3845
ae6b813a
TI
3846/*
3847 * Common callbacks
e9edcee0
TI
3848 */
3849
1da177e4
LT
3850static int alc_init(struct hda_codec *codec)
3851{
3852 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3853 unsigned int i;
3854
2c3bf9ab 3855 alc_fix_pll(codec);
4a79ba34 3856 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3857
e9edcee0
TI
3858 for (i = 0; i < spec->num_init_verbs; i++)
3859 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3860
3861 if (spec->init_hook)
3862 spec->init_hook(codec);
3863
9e5341b9 3864 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
3865 return 0;
3866}
3867
ae6b813a
TI
3868static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3869{
3870 struct alc_spec *spec = codec->spec;
3871
3872 if (spec->unsol_event)
3873 spec->unsol_event(codec, res);
3874}
3875
cb53c626
TI
3876#ifdef CONFIG_SND_HDA_POWER_SAVE
3877static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3878{
3879 struct alc_spec *spec = codec->spec;
3880 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3881}
3882#endif
3883
1da177e4
LT
3884/*
3885 * Analog playback callbacks
3886 */
3887static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3888 struct hda_codec *codec,
c8b6bf9b 3889 struct snd_pcm_substream *substream)
1da177e4
LT
3890{
3891 struct alc_spec *spec = codec->spec;
9a08160b
TI
3892 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3893 hinfo);
1da177e4
LT
3894}
3895
3896static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3897 struct hda_codec *codec,
3898 unsigned int stream_tag,
3899 unsigned int format,
c8b6bf9b 3900 struct snd_pcm_substream *substream)
1da177e4
LT
3901{
3902 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3903 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3904 stream_tag, format, substream);
1da177e4
LT
3905}
3906
3907static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3908 struct hda_codec *codec,
c8b6bf9b 3909 struct snd_pcm_substream *substream)
1da177e4
LT
3910{
3911 struct alc_spec *spec = codec->spec;
3912 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3913}
3914
3915/*
3916 * Digital out
3917 */
3918static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3919 struct hda_codec *codec,
c8b6bf9b 3920 struct snd_pcm_substream *substream)
1da177e4
LT
3921{
3922 struct alc_spec *spec = codec->spec;
3923 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3924}
3925
6b97eb45
TI
3926static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3927 struct hda_codec *codec,
3928 unsigned int stream_tag,
3929 unsigned int format,
3930 struct snd_pcm_substream *substream)
3931{
3932 struct alc_spec *spec = codec->spec;
3933 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3934 stream_tag, format, substream);
3935}
3936
9b5f12e5
TI
3937static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3938 struct hda_codec *codec,
3939 struct snd_pcm_substream *substream)
3940{
3941 struct alc_spec *spec = codec->spec;
3942 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3943}
3944
1da177e4
LT
3945static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3946 struct hda_codec *codec,
c8b6bf9b 3947 struct snd_pcm_substream *substream)
1da177e4
LT
3948{
3949 struct alc_spec *spec = codec->spec;
3950 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3951}
3952
3953/*
3954 * Analog capture
3955 */
6330079f 3956static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3957 struct hda_codec *codec,
3958 unsigned int stream_tag,
3959 unsigned int format,
c8b6bf9b 3960 struct snd_pcm_substream *substream)
1da177e4
LT
3961{
3962 struct alc_spec *spec = codec->spec;
3963
6330079f 3964 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3965 stream_tag, 0, format);
3966 return 0;
3967}
3968
6330079f 3969static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3970 struct hda_codec *codec,
c8b6bf9b 3971 struct snd_pcm_substream *substream)
1da177e4
LT
3972{
3973 struct alc_spec *spec = codec->spec;
3974
888afa15
TI
3975 snd_hda_codec_cleanup_stream(codec,
3976 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3977 return 0;
3978}
3979
840b64c0
TI
3980/* analog capture with dynamic dual-adc changes */
3981static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3982 struct hda_codec *codec,
3983 unsigned int stream_tag,
3984 unsigned int format,
3985 struct snd_pcm_substream *substream)
3986{
3987 struct alc_spec *spec = codec->spec;
3988 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3989 spec->cur_adc_stream_tag = stream_tag;
3990 spec->cur_adc_format = format;
3991 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3992 return 0;
3993}
3994
3995static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3996 struct hda_codec *codec,
3997 struct snd_pcm_substream *substream)
3998{
3999 struct alc_spec *spec = codec->spec;
4000 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4001 spec->cur_adc = 0;
4002 return 0;
4003}
4004
4005static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4006 .substreams = 1,
4007 .channels_min = 2,
4008 .channels_max = 2,
4009 .nid = 0, /* fill later */
4010 .ops = {
4011 .prepare = dualmic_capture_pcm_prepare,
4012 .cleanup = dualmic_capture_pcm_cleanup
4013 },
4014};
1da177e4
LT
4015
4016/*
4017 */
4018static struct hda_pcm_stream alc880_pcm_analog_playback = {
4019 .substreams = 1,
4020 .channels_min = 2,
4021 .channels_max = 8,
e9edcee0 4022 /* NID is set in alc_build_pcms */
1da177e4
LT
4023 .ops = {
4024 .open = alc880_playback_pcm_open,
4025 .prepare = alc880_playback_pcm_prepare,
4026 .cleanup = alc880_playback_pcm_cleanup
4027 },
4028};
4029
4030static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4031 .substreams = 1,
4032 .channels_min = 2,
4033 .channels_max = 2,
4034 /* NID is set in alc_build_pcms */
4035};
4036
4037static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4038 .substreams = 1,
4039 .channels_min = 2,
4040 .channels_max = 2,
4041 /* NID is set in alc_build_pcms */
4042};
4043
4044static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4045 .substreams = 2, /* can be overridden */
1da177e4
LT
4046 .channels_min = 2,
4047 .channels_max = 2,
e9edcee0 4048 /* NID is set in alc_build_pcms */
1da177e4 4049 .ops = {
6330079f
TI
4050 .prepare = alc880_alt_capture_pcm_prepare,
4051 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4052 },
4053};
4054
4055static struct hda_pcm_stream alc880_pcm_digital_playback = {
4056 .substreams = 1,
4057 .channels_min = 2,
4058 .channels_max = 2,
4059 /* NID is set in alc_build_pcms */
4060 .ops = {
4061 .open = alc880_dig_playback_pcm_open,
6b97eb45 4062 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4063 .prepare = alc880_dig_playback_pcm_prepare,
4064 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4065 },
4066};
4067
4068static struct hda_pcm_stream alc880_pcm_digital_capture = {
4069 .substreams = 1,
4070 .channels_min = 2,
4071 .channels_max = 2,
4072 /* NID is set in alc_build_pcms */
4073};
4074
4c5186ed 4075/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 4076static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4077 .substreams = 0,
4078 .channels_min = 0,
4079 .channels_max = 0,
4080};
4081
1da177e4
LT
4082static int alc_build_pcms(struct hda_codec *codec)
4083{
4084 struct alc_spec *spec = codec->spec;
4085 struct hda_pcm *info = spec->pcm_rec;
4086 int i;
4087
4088 codec->num_pcms = 1;
4089 codec->pcm_info = info;
4090
e64f14f4
TI
4091 if (spec->no_analog)
4092 goto skip_analog;
4093
812a2cca
TI
4094 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4095 "%s Analog", codec->chip_name);
1da177e4 4096 info->name = spec->stream_name_analog;
274693f3 4097
4a471b7d 4098 if (spec->stream_analog_playback) {
da3cec35
TI
4099 if (snd_BUG_ON(!spec->multiout.dac_nids))
4100 return -EINVAL;
4a471b7d
TI
4101 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4102 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4103 }
4104 if (spec->stream_analog_capture) {
da3cec35
TI
4105 if (snd_BUG_ON(!spec->adc_nids))
4106 return -EINVAL;
4a471b7d
TI
4107 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4108 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4109 }
4110
4111 if (spec->channel_mode) {
4112 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4113 for (i = 0; i < spec->num_channel_mode; i++) {
4114 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4115 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4116 }
1da177e4
LT
4117 }
4118 }
4119
e64f14f4 4120 skip_analog:
e08a007d 4121 /* SPDIF for stream index #1 */
1da177e4 4122 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4123 snprintf(spec->stream_name_digital,
4124 sizeof(spec->stream_name_digital),
4125 "%s Digital", codec->chip_name);
e08a007d 4126 codec->num_pcms = 2;
b25c9da1 4127 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4128 info = spec->pcm_rec + 1;
1da177e4 4129 info->name = spec->stream_name_digital;
8c441982
TI
4130 if (spec->dig_out_type)
4131 info->pcm_type = spec->dig_out_type;
4132 else
4133 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4134 if (spec->multiout.dig_out_nid &&
4135 spec->stream_digital_playback) {
1da177e4
LT
4136 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4137 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4138 }
4a471b7d
TI
4139 if (spec->dig_in_nid &&
4140 spec->stream_digital_capture) {
1da177e4
LT
4141 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4142 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4143 }
963f803f
TI
4144 /* FIXME: do we need this for all Realtek codec models? */
4145 codec->spdif_status_reset = 1;
1da177e4
LT
4146 }
4147
e64f14f4
TI
4148 if (spec->no_analog)
4149 return 0;
4150
e08a007d
TI
4151 /* If the use of more than one ADC is requested for the current
4152 * model, configure a second analog capture-only PCM.
4153 */
4154 /* Additional Analaog capture for index #2 */
6330079f
TI
4155 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4156 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4157 codec->num_pcms = 3;
c06134d7 4158 info = spec->pcm_rec + 2;
e08a007d 4159 info->name = spec->stream_name_analog;
6330079f
TI
4160 if (spec->alt_dac_nid) {
4161 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4162 *spec->stream_analog_alt_playback;
4163 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4164 spec->alt_dac_nid;
4165 } else {
4166 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4167 alc_pcm_null_stream;
4168 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4169 }
4170 if (spec->num_adc_nids > 1) {
4171 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4172 *spec->stream_analog_alt_capture;
4173 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4174 spec->adc_nids[1];
4175 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4176 spec->num_adc_nids - 1;
4177 } else {
4178 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4179 alc_pcm_null_stream;
4180 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4181 }
4182 }
4183
1da177e4
LT
4184 return 0;
4185}
4186
a4e09aa3
TI
4187static inline void alc_shutup(struct hda_codec *codec)
4188{
4189 snd_hda_shutup_pins(codec);
4190}
4191
603c4019
TI
4192static void alc_free_kctls(struct hda_codec *codec)
4193{
4194 struct alc_spec *spec = codec->spec;
4195
4196 if (spec->kctls.list) {
4197 struct snd_kcontrol_new *kctl = spec->kctls.list;
4198 int i;
4199 for (i = 0; i < spec->kctls.used; i++)
4200 kfree(kctl[i].name);
4201 }
4202 snd_array_free(&spec->kctls);
4203}
4204
1da177e4
LT
4205static void alc_free(struct hda_codec *codec)
4206{
e9edcee0 4207 struct alc_spec *spec = codec->spec;
e9edcee0 4208
f12ab1e0 4209 if (!spec)
e9edcee0
TI
4210 return;
4211
a4e09aa3 4212 alc_shutup(codec);
603c4019 4213 alc_free_kctls(codec);
e9edcee0 4214 kfree(spec);
680cd536 4215 snd_hda_detach_beep_device(codec);
1da177e4
LT
4216}
4217
f5de24b0 4218#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4219static void alc_power_eapd(struct hda_codec *codec)
4220{
4221 /* We currently only handle front, HP */
4222 switch (codec->vendor_id) {
4223 case 0x10ec0260:
9e4c8496
TI
4224 set_eapd(codec, 0x0f, 0);
4225 set_eapd(codec, 0x10, 0);
c97259df
DC
4226 break;
4227 case 0x10ec0262:
4228 case 0x10ec0267:
4229 case 0x10ec0268:
4230 case 0x10ec0269:
9e4c8496 4231 case 0x10ec0270:
c97259df
DC
4232 case 0x10ec0272:
4233 case 0x10ec0660:
4234 case 0x10ec0662:
4235 case 0x10ec0663:
4236 case 0x10ec0862:
4237 case 0x10ec0889:
9e4c8496
TI
4238 set_eapd(codec, 0x14, 0);
4239 set_eapd(codec, 0x15, 0);
c97259df
DC
4240 break;
4241 }
4242}
4243
f5de24b0
HM
4244static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4245{
4246 struct alc_spec *spec = codec->spec;
a4e09aa3 4247 alc_shutup(codec);
f5de24b0 4248 if (spec && spec->power_hook)
c97259df 4249 spec->power_hook(codec);
f5de24b0
HM
4250 return 0;
4251}
4252#endif
4253
e044c39a 4254#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4255static int alc_resume(struct hda_codec *codec)
4256{
e044c39a
TI
4257 codec->patch_ops.init(codec);
4258 snd_hda_codec_resume_amp(codec);
4259 snd_hda_codec_resume_cache(codec);
9e5341b9 4260 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4261 return 0;
4262}
e044c39a
TI
4263#endif
4264
1da177e4
LT
4265/*
4266 */
4267static struct hda_codec_ops alc_patch_ops = {
4268 .build_controls = alc_build_controls,
4269 .build_pcms = alc_build_pcms,
4270 .init = alc_init,
4271 .free = alc_free,
ae6b813a 4272 .unsol_event = alc_unsol_event,
e044c39a
TI
4273#ifdef SND_HDA_NEEDS_RESUME
4274 .resume = alc_resume,
4275#endif
cb53c626 4276#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4277 .suspend = alc_suspend,
cb53c626
TI
4278 .check_power_status = alc_check_power_status,
4279#endif
c97259df 4280 .reboot_notify = alc_shutup,
1da177e4
LT
4281};
4282
c027ddcd
KY
4283/* replace the codec chip_name with the given string */
4284static int alc_codec_rename(struct hda_codec *codec, const char *name)
4285{
4286 kfree(codec->chip_name);
4287 codec->chip_name = kstrdup(name, GFP_KERNEL);
4288 if (!codec->chip_name) {
4289 alc_free(codec);
4290 return -ENOMEM;
4291 }
4292 return 0;
4293}
4294
2fa522be
TI
4295/*
4296 * Test configuration for debugging
4297 *
4298 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4299 * enum controls.
4300 */
4301#ifdef CONFIG_SND_DEBUG
4302static hda_nid_t alc880_test_dac_nids[4] = {
4303 0x02, 0x03, 0x04, 0x05
4304};
4305
4306static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4307 .num_items = 7,
2fa522be
TI
4308 .items = {
4309 { "In-1", 0x0 },
4310 { "In-2", 0x1 },
4311 { "In-3", 0x2 },
4312 { "In-4", 0x3 },
4313 { "CD", 0x4 },
ae6b813a
TI
4314 { "Front", 0x5 },
4315 { "Surround", 0x6 },
2fa522be
TI
4316 },
4317};
4318
d2a6d7dc 4319static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4320 { 2, NULL },
fd2c326d 4321 { 4, NULL },
2fa522be 4322 { 6, NULL },
fd2c326d 4323 { 8, NULL },
2fa522be
TI
4324};
4325
9c7f852e
TI
4326static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4327 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4328{
4329 static char *texts[] = {
4330 "N/A", "Line Out", "HP Out",
4331 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4332 };
4333 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4334 uinfo->count = 1;
4335 uinfo->value.enumerated.items = 8;
4336 if (uinfo->value.enumerated.item >= 8)
4337 uinfo->value.enumerated.item = 7;
4338 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4339 return 0;
4340}
4341
9c7f852e
TI
4342static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4343 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4344{
4345 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4346 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4347 unsigned int pin_ctl, item = 0;
4348
4349 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4350 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4351 if (pin_ctl & AC_PINCTL_OUT_EN) {
4352 if (pin_ctl & AC_PINCTL_HP_EN)
4353 item = 2;
4354 else
4355 item = 1;
4356 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4357 switch (pin_ctl & AC_PINCTL_VREFEN) {
4358 case AC_PINCTL_VREF_HIZ: item = 3; break;
4359 case AC_PINCTL_VREF_50: item = 4; break;
4360 case AC_PINCTL_VREF_GRD: item = 5; break;
4361 case AC_PINCTL_VREF_80: item = 6; break;
4362 case AC_PINCTL_VREF_100: item = 7; break;
4363 }
4364 }
4365 ucontrol->value.enumerated.item[0] = item;
4366 return 0;
4367}
4368
9c7f852e
TI
4369static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4370 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4371{
4372 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4373 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4374 static unsigned int ctls[] = {
4375 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4376 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4377 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4378 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4379 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4380 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4381 };
4382 unsigned int old_ctl, new_ctl;
4383
4384 old_ctl = snd_hda_codec_read(codec, nid, 0,
4385 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4386 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4387 if (old_ctl != new_ctl) {
82beb8fd
TI
4388 int val;
4389 snd_hda_codec_write_cache(codec, nid, 0,
4390 AC_VERB_SET_PIN_WIDGET_CONTROL,
4391 new_ctl);
47fd830a
TI
4392 val = ucontrol->value.enumerated.item[0] >= 3 ?
4393 HDA_AMP_MUTE : 0;
4394 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4395 HDA_AMP_MUTE, val);
2fa522be
TI
4396 return 1;
4397 }
4398 return 0;
4399}
4400
9c7f852e
TI
4401static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4402 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4403{
4404 static char *texts[] = {
4405 "Front", "Surround", "CLFE", "Side"
4406 };
4407 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4408 uinfo->count = 1;
4409 uinfo->value.enumerated.items = 4;
4410 if (uinfo->value.enumerated.item >= 4)
4411 uinfo->value.enumerated.item = 3;
4412 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4413 return 0;
4414}
4415
9c7f852e
TI
4416static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4417 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4418{
4419 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4420 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4421 unsigned int sel;
4422
4423 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4424 ucontrol->value.enumerated.item[0] = sel & 3;
4425 return 0;
4426}
4427
9c7f852e
TI
4428static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4429 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4430{
4431 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4432 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4433 unsigned int sel;
4434
4435 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4436 if (ucontrol->value.enumerated.item[0] != sel) {
4437 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4438 snd_hda_codec_write_cache(codec, nid, 0,
4439 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4440 return 1;
4441 }
4442 return 0;
4443}
4444
4445#define PIN_CTL_TEST(xname,nid) { \
4446 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4447 .name = xname, \
5b0cb1d8 4448 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4449 .info = alc_test_pin_ctl_info, \
4450 .get = alc_test_pin_ctl_get, \
4451 .put = alc_test_pin_ctl_put, \
4452 .private_value = nid \
4453 }
4454
4455#define PIN_SRC_TEST(xname,nid) { \
4456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4457 .name = xname, \
5b0cb1d8 4458 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4459 .info = alc_test_pin_src_info, \
4460 .get = alc_test_pin_src_get, \
4461 .put = alc_test_pin_src_put, \
4462 .private_value = nid \
4463 }
4464
c8b6bf9b 4465static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4466 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4467 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4468 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4469 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4470 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4471 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4472 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4473 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4474 PIN_CTL_TEST("Front Pin Mode", 0x14),
4475 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4476 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4477 PIN_CTL_TEST("Side Pin Mode", 0x17),
4478 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4479 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4480 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4481 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4482 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4483 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4484 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4485 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4486 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4487 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4488 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4489 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4490 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4491 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4492 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4493 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4494 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4495 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4496 {
4497 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4498 .name = "Channel Mode",
df694daa
KY
4499 .info = alc_ch_mode_info,
4500 .get = alc_ch_mode_get,
4501 .put = alc_ch_mode_put,
2fa522be
TI
4502 },
4503 { } /* end */
4504};
4505
4506static struct hda_verb alc880_test_init_verbs[] = {
4507 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4510 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4511 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4512 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4515 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4516 /* Vol output for 0x0c-0x0f */
05acb863
TI
4517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4519 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4520 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4521 /* Set output pins 0x14-0x17 */
05acb863
TI
4522 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4523 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4524 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4525 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4526 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4527 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4528 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4529 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4530 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4531 /* Set input pins 0x18-0x1c */
16ded525
TI
4532 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4533 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4534 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4535 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4536 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4537 /* Mute input pins 0x18-0x1b */
05acb863
TI
4538 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4539 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4540 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4541 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4542 /* ADC set up */
05acb863 4543 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4544 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4545 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4546 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4547 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4548 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4549 /* Analog input/passthru */
4550 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4551 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4552 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4553 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4554 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4555 { }
4556};
4557#endif
4558
1da177e4
LT
4559/*
4560 */
4561
f5fcc13c
TI
4562static const char *alc880_models[ALC880_MODEL_LAST] = {
4563 [ALC880_3ST] = "3stack",
4564 [ALC880_TCL_S700] = "tcl",
4565 [ALC880_3ST_DIG] = "3stack-digout",
4566 [ALC880_CLEVO] = "clevo",
4567 [ALC880_5ST] = "5stack",
4568 [ALC880_5ST_DIG] = "5stack-digout",
4569 [ALC880_W810] = "w810",
4570 [ALC880_Z71V] = "z71v",
4571 [ALC880_6ST] = "6stack",
4572 [ALC880_6ST_DIG] = "6stack-digout",
4573 [ALC880_ASUS] = "asus",
4574 [ALC880_ASUS_W1V] = "asus-w1v",
4575 [ALC880_ASUS_DIG] = "asus-dig",
4576 [ALC880_ASUS_DIG2] = "asus-dig2",
4577 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4578 [ALC880_UNIWILL_P53] = "uniwill-p53",
4579 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4580 [ALC880_F1734] = "F1734",
4581 [ALC880_LG] = "lg",
4582 [ALC880_LG_LW] = "lg-lw",
df99cd33 4583 [ALC880_MEDION_RIM] = "medion",
2fa522be 4584#ifdef CONFIG_SND_DEBUG
f5fcc13c 4585 [ALC880_TEST] = "test",
2fa522be 4586#endif
f5fcc13c
TI
4587 [ALC880_AUTO] = "auto",
4588};
4589
4590static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4591 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4592 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4593 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4594 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4595 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4596 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4597 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4598 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4599 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4600 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4601 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4602 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4603 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4604 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4605 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4606 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4607 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4608 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4609 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4610 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4611 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4612 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4613 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4614 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4615 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4616 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4617 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4618 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4619 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4620 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4621 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4622 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4623 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4624 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4625 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4626 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4627 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4628 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4629 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4630 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4631 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4632 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4633 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4634 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4635 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4636 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4637 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4638 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4639 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4640 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4641 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4642 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4643 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4644 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4645 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4646 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4647 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4648 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4649 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4650 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4651 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4652 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4653 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4654 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4655 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4656 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4657 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4658 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4659 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4660 /* default Intel */
4661 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4662 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4663 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4664 {}
4665};
4666
16ded525 4667/*
df694daa 4668 * ALC880 codec presets
16ded525 4669 */
16ded525
TI
4670static struct alc_config_preset alc880_presets[] = {
4671 [ALC880_3ST] = {
e9edcee0 4672 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4673 .init_verbs = { alc880_volume_init_verbs,
4674 alc880_pin_3stack_init_verbs },
16ded525 4675 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4676 .dac_nids = alc880_dac_nids,
16ded525
TI
4677 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4678 .channel_mode = alc880_threestack_modes,
4e195a7b 4679 .need_dac_fix = 1,
16ded525
TI
4680 .input_mux = &alc880_capture_source,
4681 },
4682 [ALC880_3ST_DIG] = {
e9edcee0 4683 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4684 .init_verbs = { alc880_volume_init_verbs,
4685 alc880_pin_3stack_init_verbs },
16ded525 4686 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4687 .dac_nids = alc880_dac_nids,
4688 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4689 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4690 .channel_mode = alc880_threestack_modes,
4e195a7b 4691 .need_dac_fix = 1,
16ded525
TI
4692 .input_mux = &alc880_capture_source,
4693 },
df694daa
KY
4694 [ALC880_TCL_S700] = {
4695 .mixers = { alc880_tcl_s700_mixer },
4696 .init_verbs = { alc880_volume_init_verbs,
4697 alc880_pin_tcl_S700_init_verbs,
4698 alc880_gpio2_init_verbs },
4699 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4700 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4701 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4702 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4703 .hp_nid = 0x03,
4704 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4705 .channel_mode = alc880_2_jack_modes,
4706 .input_mux = &alc880_capture_source,
4707 },
16ded525 4708 [ALC880_5ST] = {
f12ab1e0
TI
4709 .mixers = { alc880_three_stack_mixer,
4710 alc880_five_stack_mixer},
4711 .init_verbs = { alc880_volume_init_verbs,
4712 alc880_pin_5stack_init_verbs },
16ded525
TI
4713 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4714 .dac_nids = alc880_dac_nids,
16ded525
TI
4715 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4716 .channel_mode = alc880_fivestack_modes,
4717 .input_mux = &alc880_capture_source,
4718 },
4719 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4720 .mixers = { alc880_three_stack_mixer,
4721 alc880_five_stack_mixer },
4722 .init_verbs = { alc880_volume_init_verbs,
4723 alc880_pin_5stack_init_verbs },
16ded525
TI
4724 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4725 .dac_nids = alc880_dac_nids,
4726 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4727 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4728 .channel_mode = alc880_fivestack_modes,
4729 .input_mux = &alc880_capture_source,
4730 },
b6482d48
TI
4731 [ALC880_6ST] = {
4732 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4733 .init_verbs = { alc880_volume_init_verbs,
4734 alc880_pin_6stack_init_verbs },
b6482d48
TI
4735 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4736 .dac_nids = alc880_6st_dac_nids,
4737 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4738 .channel_mode = alc880_sixstack_modes,
4739 .input_mux = &alc880_6stack_capture_source,
4740 },
16ded525 4741 [ALC880_6ST_DIG] = {
e9edcee0 4742 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4743 .init_verbs = { alc880_volume_init_verbs,
4744 alc880_pin_6stack_init_verbs },
16ded525
TI
4745 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4746 .dac_nids = alc880_6st_dac_nids,
4747 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4748 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4749 .channel_mode = alc880_sixstack_modes,
4750 .input_mux = &alc880_6stack_capture_source,
4751 },
4752 [ALC880_W810] = {
e9edcee0 4753 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4754 .init_verbs = { alc880_volume_init_verbs,
4755 alc880_pin_w810_init_verbs,
b0af0de5 4756 alc880_gpio2_init_verbs },
16ded525
TI
4757 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4758 .dac_nids = alc880_w810_dac_nids,
4759 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4760 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4761 .channel_mode = alc880_w810_modes,
4762 .input_mux = &alc880_capture_source,
4763 },
4764 [ALC880_Z71V] = {
e9edcee0 4765 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4766 .init_verbs = { alc880_volume_init_verbs,
4767 alc880_pin_z71v_init_verbs },
16ded525
TI
4768 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4769 .dac_nids = alc880_z71v_dac_nids,
4770 .dig_out_nid = ALC880_DIGOUT_NID,
4771 .hp_nid = 0x03,
e9edcee0
TI
4772 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4773 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4774 .input_mux = &alc880_capture_source,
4775 },
4776 [ALC880_F1734] = {
e9edcee0 4777 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4778 .init_verbs = { alc880_volume_init_verbs,
4779 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4780 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4781 .dac_nids = alc880_f1734_dac_nids,
4782 .hp_nid = 0x02,
4783 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4784 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4785 .input_mux = &alc880_f1734_capture_source,
4786 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4787 .setup = alc880_uniwill_p53_setup,
4788 .init_hook = alc_automute_amp,
16ded525
TI
4789 },
4790 [ALC880_ASUS] = {
e9edcee0 4791 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4792 .init_verbs = { alc880_volume_init_verbs,
4793 alc880_pin_asus_init_verbs,
e9edcee0
TI
4794 alc880_gpio1_init_verbs },
4795 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4796 .dac_nids = alc880_asus_dac_nids,
4797 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4798 .channel_mode = alc880_asus_modes,
4e195a7b 4799 .need_dac_fix = 1,
16ded525
TI
4800 .input_mux = &alc880_capture_source,
4801 },
4802 [ALC880_ASUS_DIG] = {
e9edcee0 4803 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4804 .init_verbs = { alc880_volume_init_verbs,
4805 alc880_pin_asus_init_verbs,
e9edcee0
TI
4806 alc880_gpio1_init_verbs },
4807 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4808 .dac_nids = alc880_asus_dac_nids,
16ded525 4809 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4810 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4811 .channel_mode = alc880_asus_modes,
4e195a7b 4812 .need_dac_fix = 1,
16ded525
TI
4813 .input_mux = &alc880_capture_source,
4814 },
df694daa
KY
4815 [ALC880_ASUS_DIG2] = {
4816 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4817 .init_verbs = { alc880_volume_init_verbs,
4818 alc880_pin_asus_init_verbs,
df694daa
KY
4819 alc880_gpio2_init_verbs }, /* use GPIO2 */
4820 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4821 .dac_nids = alc880_asus_dac_nids,
4822 .dig_out_nid = ALC880_DIGOUT_NID,
4823 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4824 .channel_mode = alc880_asus_modes,
4e195a7b 4825 .need_dac_fix = 1,
df694daa
KY
4826 .input_mux = &alc880_capture_source,
4827 },
16ded525 4828 [ALC880_ASUS_W1V] = {
e9edcee0 4829 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4830 .init_verbs = { alc880_volume_init_verbs,
4831 alc880_pin_asus_init_verbs,
e9edcee0
TI
4832 alc880_gpio1_init_verbs },
4833 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4834 .dac_nids = alc880_asus_dac_nids,
16ded525 4835 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4836 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4837 .channel_mode = alc880_asus_modes,
4e195a7b 4838 .need_dac_fix = 1,
16ded525
TI
4839 .input_mux = &alc880_capture_source,
4840 },
4841 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4842 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4843 .init_verbs = { alc880_volume_init_verbs,
4844 alc880_pin_asus_init_verbs },
e9edcee0
TI
4845 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4846 .dac_nids = alc880_asus_dac_nids,
16ded525 4847 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4848 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4849 .channel_mode = alc880_asus_modes,
4e195a7b 4850 .need_dac_fix = 1,
16ded525
TI
4851 .input_mux = &alc880_capture_source,
4852 },
ccc656ce
KY
4853 [ALC880_UNIWILL] = {
4854 .mixers = { alc880_uniwill_mixer },
4855 .init_verbs = { alc880_volume_init_verbs,
4856 alc880_uniwill_init_verbs },
4857 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4858 .dac_nids = alc880_asus_dac_nids,
4859 .dig_out_nid = ALC880_DIGOUT_NID,
4860 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4861 .channel_mode = alc880_threestack_modes,
4862 .need_dac_fix = 1,
4863 .input_mux = &alc880_capture_source,
4864 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4865 .setup = alc880_uniwill_setup,
a9fd4f3f 4866 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4867 },
4868 [ALC880_UNIWILL_P53] = {
4869 .mixers = { alc880_uniwill_p53_mixer },
4870 .init_verbs = { alc880_volume_init_verbs,
4871 alc880_uniwill_p53_init_verbs },
4872 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4873 .dac_nids = alc880_asus_dac_nids,
4874 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4875 .channel_mode = alc880_threestack_modes,
4876 .input_mux = &alc880_capture_source,
4877 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4878 .setup = alc880_uniwill_p53_setup,
4879 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4880 },
4881 [ALC880_FUJITSU] = {
45bdd1c1 4882 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4883 .init_verbs = { alc880_volume_init_verbs,
4884 alc880_uniwill_p53_init_verbs,
4885 alc880_beep_init_verbs },
4886 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4887 .dac_nids = alc880_dac_nids,
d53d7d9e 4888 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4889 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4890 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4891 .input_mux = &alc880_capture_source,
4892 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4893 .setup = alc880_uniwill_p53_setup,
4894 .init_hook = alc_automute_amp,
ccc656ce 4895 },
df694daa
KY
4896 [ALC880_CLEVO] = {
4897 .mixers = { alc880_three_stack_mixer },
4898 .init_verbs = { alc880_volume_init_verbs,
4899 alc880_pin_clevo_init_verbs },
4900 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4901 .dac_nids = alc880_dac_nids,
4902 .hp_nid = 0x03,
4903 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4904 .channel_mode = alc880_threestack_modes,
4e195a7b 4905 .need_dac_fix = 1,
df694daa
KY
4906 .input_mux = &alc880_capture_source,
4907 },
ae6b813a
TI
4908 [ALC880_LG] = {
4909 .mixers = { alc880_lg_mixer },
4910 .init_verbs = { alc880_volume_init_verbs,
4911 alc880_lg_init_verbs },
4912 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4913 .dac_nids = alc880_lg_dac_nids,
4914 .dig_out_nid = ALC880_DIGOUT_NID,
4915 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4916 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4917 .need_dac_fix = 1,
ae6b813a 4918 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4919 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4920 .setup = alc880_lg_setup,
4921 .init_hook = alc_automute_amp,
cb53c626
TI
4922#ifdef CONFIG_SND_HDA_POWER_SAVE
4923 .loopbacks = alc880_lg_loopbacks,
4924#endif
ae6b813a 4925 },
d681518a
TI
4926 [ALC880_LG_LW] = {
4927 .mixers = { alc880_lg_lw_mixer },
4928 .init_verbs = { alc880_volume_init_verbs,
4929 alc880_lg_lw_init_verbs },
0a8c5da3 4930 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4931 .dac_nids = alc880_dac_nids,
4932 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4933 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4934 .channel_mode = alc880_lg_lw_modes,
d681518a 4935 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4936 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4937 .setup = alc880_lg_lw_setup,
4938 .init_hook = alc_automute_amp,
d681518a 4939 },
df99cd33
TI
4940 [ALC880_MEDION_RIM] = {
4941 .mixers = { alc880_medion_rim_mixer },
4942 .init_verbs = { alc880_volume_init_verbs,
4943 alc880_medion_rim_init_verbs,
4944 alc_gpio2_init_verbs },
4945 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4946 .dac_nids = alc880_dac_nids,
4947 .dig_out_nid = ALC880_DIGOUT_NID,
4948 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4949 .channel_mode = alc880_2_jack_modes,
4950 .input_mux = &alc880_medion_rim_capture_source,
4951 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4952 .setup = alc880_medion_rim_setup,
4953 .init_hook = alc880_medion_rim_automute,
df99cd33 4954 },
16ded525
TI
4955#ifdef CONFIG_SND_DEBUG
4956 [ALC880_TEST] = {
e9edcee0
TI
4957 .mixers = { alc880_test_mixer },
4958 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4959 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4960 .dac_nids = alc880_test_dac_nids,
4961 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4962 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4963 .channel_mode = alc880_test_modes,
4964 .input_mux = &alc880_test_capture_source,
4965 },
4966#endif
4967};
4968
e9edcee0
TI
4969/*
4970 * Automatic parse of I/O pins from the BIOS configuration
4971 */
4972
e9edcee0
TI
4973enum {
4974 ALC_CTL_WIDGET_VOL,
4975 ALC_CTL_WIDGET_MUTE,
4976 ALC_CTL_BIND_MUTE,
4977};
c8b6bf9b 4978static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4979 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4980 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4981 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4982};
4983
4984/* add dynamic controls */
f12ab1e0 4985static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 4986 int cidx, unsigned long val)
e9edcee0 4987{
c8b6bf9b 4988 struct snd_kcontrol_new *knew;
e9edcee0 4989
603c4019
TI
4990 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4991 knew = snd_array_new(&spec->kctls);
4992 if (!knew)
4993 return -ENOMEM;
e9edcee0 4994 *knew = alc880_control_templates[type];
543537bd 4995 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4996 if (!knew->name)
e9edcee0 4997 return -ENOMEM;
66ceeb6b 4998 knew->index = cidx;
4d02d1b6 4999 if (get_amp_nid_(val))
5e26dfd0 5000 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5001 knew->private_value = val;
e9edcee0
TI
5002 return 0;
5003}
5004
0afe5f89
TI
5005static int add_control_with_pfx(struct alc_spec *spec, int type,
5006 const char *pfx, const char *dir,
66ceeb6b 5007 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5008{
5009 char name[32];
5010 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5011 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5012}
5013
66ceeb6b
TI
5014#define add_pb_vol_ctrl(spec, type, pfx, val) \
5015 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5016#define add_pb_sw_ctrl(spec, type, pfx, val) \
5017 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5018#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5019 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5020#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5021 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5022
e9edcee0
TI
5023#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5024#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5025#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5026#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5027#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5028#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5029#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5030#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5031#define ALC880_PIN_CD_NID 0x1c
5032
5033/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5034static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5035 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5036{
5037 hda_nid_t nid;
5038 int assigned[4];
5039 int i, j;
5040
5041 memset(assigned, 0, sizeof(assigned));
b0af0de5 5042 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5043
5044 /* check the pins hardwired to audio widget */
5045 for (i = 0; i < cfg->line_outs; i++) {
5046 nid = cfg->line_out_pins[i];
5047 if (alc880_is_fixed_pin(nid)) {
5048 int idx = alc880_fixed_pin_idx(nid);
5014f193 5049 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5050 assigned[idx] = 1;
5051 }
5052 }
5053 /* left pins can be connect to any audio widget */
5054 for (i = 0; i < cfg->line_outs; i++) {
5055 nid = cfg->line_out_pins[i];
5056 if (alc880_is_fixed_pin(nid))
5057 continue;
5058 /* search for an empty channel */
5059 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
5060 if (!assigned[j]) {
5061 spec->multiout.dac_nids[i] =
5062 alc880_idx_to_dac(j);
e9edcee0
TI
5063 assigned[j] = 1;
5064 break;
5065 }
5066 }
5067 }
5068 spec->multiout.num_dacs = cfg->line_outs;
5069 return 0;
5070}
5071
bcb2f0f5
TI
5072static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5073 bool can_be_master)
5074{
5075 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5076 return "Master";
5077
5078 switch (cfg->line_out_type) {
5079 case AUTO_PIN_SPEAKER_OUT:
5080 return "Speaker";
5081 case AUTO_PIN_HP_OUT:
5082 return "Headphone";
5083 default:
5084 if (cfg->line_outs == 1)
5085 return "PCM";
5086 break;
5087 }
5088 return NULL;
5089}
5090
e9edcee0 5091/* add playback controls from the parsed DAC table */
df694daa
KY
5092static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5093 const struct auto_pin_cfg *cfg)
e9edcee0 5094{
f12ab1e0
TI
5095 static const char *chname[4] = {
5096 "Front", "Surround", NULL /*CLFE*/, "Side"
5097 };
bcb2f0f5 5098 const char *pfx = alc_get_line_out_pfx(cfg, false);
e9edcee0
TI
5099 hda_nid_t nid;
5100 int i, err;
5101
5102 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 5103 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5104 continue;
5105 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5106 if (!pfx && i == 2) {
e9edcee0 5107 /* Center/LFE */
0afe5f89
TI
5108 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5109 "Center",
f12ab1e0
TI
5110 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5111 HDA_OUTPUT));
5112 if (err < 0)
e9edcee0 5113 return err;
0afe5f89
TI
5114 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5115 "LFE",
f12ab1e0
TI
5116 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5117 HDA_OUTPUT));
5118 if (err < 0)
e9edcee0 5119 return err;
0afe5f89
TI
5120 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5121 "Center",
f12ab1e0
TI
5122 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5123 HDA_INPUT));
5124 if (err < 0)
e9edcee0 5125 return err;
0afe5f89
TI
5126 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5127 "LFE",
f12ab1e0
TI
5128 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5129 HDA_INPUT));
5130 if (err < 0)
e9edcee0
TI
5131 return err;
5132 } else {
bcb2f0f5
TI
5133 const char *name = pfx;
5134 if (!name)
5135 name = chname[i];
5136 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5137 name, i,
f12ab1e0
TI
5138 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5139 HDA_OUTPUT));
5140 if (err < 0)
e9edcee0 5141 return err;
bcb2f0f5
TI
5142 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5143 name, i,
f12ab1e0
TI
5144 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5145 HDA_INPUT));
5146 if (err < 0)
e9edcee0
TI
5147 return err;
5148 }
5149 }
e9edcee0
TI
5150 return 0;
5151}
5152
8d88bc3d
TI
5153/* add playback controls for speaker and HP outputs */
5154static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5155 const char *pfx)
e9edcee0
TI
5156{
5157 hda_nid_t nid;
5158 int err;
5159
f12ab1e0 5160 if (!pin)
e9edcee0
TI
5161 return 0;
5162
5163 if (alc880_is_fixed_pin(pin)) {
5164 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5165 /* specify the DAC as the extra output */
f12ab1e0 5166 if (!spec->multiout.hp_nid)
e9edcee0 5167 spec->multiout.hp_nid = nid;
82bc955f
TI
5168 else
5169 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5170 /* control HP volume/switch on the output mixer amp */
5171 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5172 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5173 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5174 if (err < 0)
e9edcee0 5175 return err;
0afe5f89 5176 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5177 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5178 if (err < 0)
e9edcee0
TI
5179 return err;
5180 } else if (alc880_is_multi_pin(pin)) {
5181 /* set manual connection */
e9edcee0 5182 /* we have only a switch on HP-out PIN */
0afe5f89 5183 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5184 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5185 if (err < 0)
e9edcee0
TI
5186 return err;
5187 }
5188 return 0;
5189}
5190
5191/* create input playback/capture controls for the given pin */
f12ab1e0 5192static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5193 const char *ctlname, int ctlidx,
df694daa 5194 int idx, hda_nid_t mix_nid)
e9edcee0 5195{
df694daa 5196 int err;
e9edcee0 5197
66ceeb6b 5198 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5199 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5200 if (err < 0)
e9edcee0 5201 return err;
66ceeb6b 5202 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5203 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5204 if (err < 0)
e9edcee0
TI
5205 return err;
5206 return 0;
5207}
5208
05f5f477
TI
5209static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5210{
5211 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5212 return (pincap & AC_PINCAP_IN) != 0;
5213}
5214
e9edcee0 5215/* create playback/capture controls for input pins */
05f5f477
TI
5216static int alc_auto_create_input_ctls(struct hda_codec *codec,
5217 const struct auto_pin_cfg *cfg,
5218 hda_nid_t mixer,
5219 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5220{
05f5f477 5221 struct alc_spec *spec = codec->spec;
61b9b9b1 5222 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5223 int i, err, idx, type_idx = 0;
5224 const char *prev_label = NULL;
e9edcee0 5225
66ceeb6b 5226 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5227 hda_nid_t pin;
10a20af7 5228 const char *label;
05f5f477 5229
66ceeb6b 5230 pin = cfg->inputs[i].pin;
05f5f477
TI
5231 if (!alc_is_input_pin(codec, pin))
5232 continue;
5233
5322bf27
DH
5234 label = hda_get_autocfg_input_label(codec, cfg, i);
5235 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5236 type_idx++;
5237 else
5238 type_idx = 0;
5322bf27
DH
5239 prev_label = label;
5240
05f5f477
TI
5241 if (mixer) {
5242 idx = get_connection_index(codec, mixer, pin);
5243 if (idx >= 0) {
5244 err = new_analog_input(spec, pin,
10a20af7
TI
5245 label, type_idx,
5246 idx, mixer);
05f5f477
TI
5247 if (err < 0)
5248 return err;
5249 }
5250 }
5251
5252 if (!cap1)
5253 continue;
5254 idx = get_connection_index(codec, cap1, pin);
5255 if (idx < 0 && cap2)
5256 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5257 if (idx >= 0)
5258 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5259 }
5260 return 0;
5261}
5262
05f5f477
TI
5263static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5264 const struct auto_pin_cfg *cfg)
5265{
5266 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5267}
5268
f6c7e546
TI
5269static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5270 unsigned int pin_type)
5271{
5272 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5273 pin_type);
5274 /* unmute pin */
d260cdf6
TI
5275 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5276 AMP_OUT_UNMUTE);
f6c7e546
TI
5277}
5278
df694daa
KY
5279static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5280 hda_nid_t nid, int pin_type,
e9edcee0
TI
5281 int dac_idx)
5282{
f6c7e546 5283 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5284 /* need the manual connection? */
5285 if (alc880_is_multi_pin(nid)) {
5286 struct alc_spec *spec = codec->spec;
5287 int idx = alc880_multi_pin_idx(nid);
5288 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5289 AC_VERB_SET_CONNECT_SEL,
5290 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5291 }
5292}
5293
baba8ee9
TI
5294static int get_pin_type(int line_out_type)
5295{
5296 if (line_out_type == AUTO_PIN_HP_OUT)
5297 return PIN_HP;
5298 else
5299 return PIN_OUT;
5300}
5301
e9edcee0
TI
5302static void alc880_auto_init_multi_out(struct hda_codec *codec)
5303{
5304 struct alc_spec *spec = codec->spec;
5305 int i;
ea1fb29a 5306
e9edcee0
TI
5307 for (i = 0; i < spec->autocfg.line_outs; i++) {
5308 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5309 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5310 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5311 }
5312}
5313
8d88bc3d 5314static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5315{
5316 struct alc_spec *spec = codec->spec;
5317 hda_nid_t pin;
5318
82bc955f 5319 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5320 if (pin) /* connect to front */
5321 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5322 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5323 if (pin) /* connect to front */
5324 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5325}
5326
5327static void alc880_auto_init_analog_input(struct hda_codec *codec)
5328{
5329 struct alc_spec *spec = codec->spec;
66ceeb6b 5330 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5331 int i;
5332
66ceeb6b
TI
5333 for (i = 0; i < cfg->num_inputs; i++) {
5334 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5335 if (alc_is_input_pin(codec, nid)) {
30ea098f 5336 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5337 if (nid != ALC880_PIN_CD_NID &&
5338 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5339 snd_hda_codec_write(codec, nid, 0,
5340 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5341 AMP_OUT_MUTE);
5342 }
5343 }
5344}
5345
7f311a46
TI
5346static void alc880_auto_init_input_src(struct hda_codec *codec)
5347{
5348 struct alc_spec *spec = codec->spec;
5349 int c;
5350
5351 for (c = 0; c < spec->num_adc_nids; c++) {
5352 unsigned int mux_idx;
5353 const struct hda_input_mux *imux;
5354 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5355 imux = &spec->input_mux[mux_idx];
5356 if (!imux->num_items && mux_idx > 0)
5357 imux = &spec->input_mux[0];
5358 if (imux)
5359 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5360 AC_VERB_SET_CONNECT_SEL,
5361 imux->items[0].index);
5362 }
5363}
5364
e9edcee0 5365/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5366/* return 1 if successful, 0 if the proper config is not found,
5367 * or a negative error code
5368 */
e9edcee0
TI
5369static int alc880_parse_auto_config(struct hda_codec *codec)
5370{
5371 struct alc_spec *spec = codec->spec;
757899ac 5372 int err;
df694daa 5373 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5374
f12ab1e0
TI
5375 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5376 alc880_ignore);
5377 if (err < 0)
e9edcee0 5378 return err;
f12ab1e0 5379 if (!spec->autocfg.line_outs)
e9edcee0 5380 return 0; /* can't find valid BIOS pin config */
df694daa 5381
f12ab1e0
TI
5382 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5383 if (err < 0)
5384 return err;
5385 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5386 if (err < 0)
5387 return err;
5388 err = alc880_auto_create_extra_out(spec,
5389 spec->autocfg.speaker_pins[0],
5390 "Speaker");
5391 if (err < 0)
5392 return err;
5393 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5394 "Headphone");
5395 if (err < 0)
5396 return err;
05f5f477 5397 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5398 if (err < 0)
e9edcee0
TI
5399 return err;
5400
5401 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5402
757899ac 5403 alc_auto_parse_digital(codec);
e9edcee0 5404
603c4019 5405 if (spec->kctls.list)
d88897ea 5406 add_mixer(spec, spec->kctls.list);
e9edcee0 5407
d88897ea 5408 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5409
a1e8d2da 5410 spec->num_mux_defs = 1;
61b9b9b1 5411 spec->input_mux = &spec->private_imux[0];
e9edcee0 5412
6227cdce 5413 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5414
e9edcee0
TI
5415 return 1;
5416}
5417
ae6b813a
TI
5418/* additional initialization for auto-configuration model */
5419static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5420{
f6c7e546 5421 struct alc_spec *spec = codec->spec;
e9edcee0 5422 alc880_auto_init_multi_out(codec);
8d88bc3d 5423 alc880_auto_init_extra_out(codec);
e9edcee0 5424 alc880_auto_init_analog_input(codec);
7f311a46 5425 alc880_auto_init_input_src(codec);
757899ac 5426 alc_auto_init_digital(codec);
f6c7e546 5427 if (spec->unsol_event)
7fb0d78f 5428 alc_inithook(codec);
e9edcee0
TI
5429}
5430
b59bdf3b
TI
5431/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5432 * one of two digital mic pins, e.g. on ALC272
5433 */
5434static void fixup_automic_adc(struct hda_codec *codec)
5435{
5436 struct alc_spec *spec = codec->spec;
5437 int i;
5438
5439 for (i = 0; i < spec->num_adc_nids; i++) {
5440 hda_nid_t cap = spec->capsrc_nids ?
5441 spec->capsrc_nids[i] : spec->adc_nids[i];
5442 int iidx, eidx;
5443
5444 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5445 if (iidx < 0)
5446 continue;
5447 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5448 if (eidx < 0)
5449 continue;
5450 spec->int_mic.mux_idx = iidx;
5451 spec->ext_mic.mux_idx = eidx;
5452 if (spec->capsrc_nids)
5453 spec->capsrc_nids += i;
5454 spec->adc_nids += i;
5455 spec->num_adc_nids = 1;
5456 return;
5457 }
5458 snd_printd(KERN_INFO "hda_codec: %s: "
5459 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5460 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5461 spec->auto_mic = 0; /* disable auto-mic to be sure */
5462}
5463
748cce43
TI
5464/* select or unmute the given capsrc route */
5465static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5466 int idx)
5467{
5468 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5469 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5470 HDA_AMP_MUTE, 0);
5471 } else {
5472 snd_hda_codec_write_cache(codec, cap, 0,
5473 AC_VERB_SET_CONNECT_SEL, idx);
5474 }
5475}
5476
840b64c0
TI
5477/* set the default connection to that pin */
5478static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5479{
5480 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5481 int i;
5482
eaa9b3a7
TI
5483 for (i = 0; i < spec->num_adc_nids; i++) {
5484 hda_nid_t cap = spec->capsrc_nids ?
5485 spec->capsrc_nids[i] : spec->adc_nids[i];
5486 int idx;
5487
5488 idx = get_connection_index(codec, cap, pin);
5489 if (idx < 0)
5490 continue;
748cce43 5491 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5492 return i; /* return the found index */
5493 }
5494 return -1; /* not found */
5495}
5496
5497/* choose the ADC/MUX containing the input pin and initialize the setup */
5498static void fixup_single_adc(struct hda_codec *codec)
5499{
5500 struct alc_spec *spec = codec->spec;
66ceeb6b 5501 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5502 int i;
5503
5504 /* search for the input pin; there must be only one */
66ceeb6b 5505 if (cfg->num_inputs != 1)
eaa9b3a7 5506 return;
66ceeb6b 5507 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5508 if (i >= 0) {
5509 /* use only this ADC */
5510 if (spec->capsrc_nids)
5511 spec->capsrc_nids += i;
5512 spec->adc_nids += i;
5513 spec->num_adc_nids = 1;
eaa9b3a7
TI
5514 }
5515}
5516
840b64c0
TI
5517/* initialize dual adcs */
5518static void fixup_dual_adc_switch(struct hda_codec *codec)
5519{
5520 struct alc_spec *spec = codec->spec;
5521 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5522 init_capsrc_for_pin(codec, spec->int_mic.pin);
5523}
5524
b59bdf3b 5525static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5526{
b59bdf3b 5527 struct alc_spec *spec = codec->spec;
a23b688f
TI
5528 static struct snd_kcontrol_new *caps[2][3] = {
5529 { alc_capture_mixer_nosrc1,
5530 alc_capture_mixer_nosrc2,
5531 alc_capture_mixer_nosrc3 },
5532 { alc_capture_mixer1,
5533 alc_capture_mixer2,
5534 alc_capture_mixer3 },
f9e336f6 5535 };
a23b688f 5536 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5537 int mux = 0;
840b64c0
TI
5538 int num_adcs = spec->num_adc_nids;
5539 if (spec->dual_adc_switch)
5540 fixup_dual_adc_switch(codec);
5541 else if (spec->auto_mic)
b59bdf3b 5542 fixup_automic_adc(codec);
eaa9b3a7
TI
5543 else if (spec->input_mux) {
5544 if (spec->input_mux->num_items > 1)
5545 mux = 1;
5546 else if (spec->input_mux->num_items == 1)
5547 fixup_single_adc(codec);
5548 }
840b64c0
TI
5549 if (spec->dual_adc_switch)
5550 num_adcs = 1;
5551 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5552 }
f9e336f6
TI
5553}
5554
6694635d
TI
5555/* fill adc_nids (and capsrc_nids) containing all active input pins */
5556static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5557 int num_nids)
5558{
5559 struct alc_spec *spec = codec->spec;
66ceeb6b 5560 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5561 int n;
5562 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5563
5564 for (n = 0; n < num_nids; n++) {
5565 hda_nid_t adc, cap;
5566 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5567 int nconns, i, j;
5568
5569 adc = nids[n];
5570 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5571 continue;
5572 cap = adc;
5573 nconns = snd_hda_get_connections(codec, cap, conn,
5574 ARRAY_SIZE(conn));
5575 if (nconns == 1) {
5576 cap = conn[0];
5577 nconns = snd_hda_get_connections(codec, cap, conn,
5578 ARRAY_SIZE(conn));
5579 }
5580 if (nconns <= 0)
5581 continue;
5582 if (!fallback_adc) {
5583 fallback_adc = adc;
5584 fallback_cap = cap;
5585 }
66ceeb6b
TI
5586 for (i = 0; i < cfg->num_inputs; i++) {
5587 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5588 for (j = 0; j < nconns; j++) {
5589 if (conn[j] == nid)
5590 break;
5591 }
5592 if (j >= nconns)
5593 break;
5594 }
66ceeb6b 5595 if (i >= cfg->num_inputs) {
6694635d
TI
5596 int num_adcs = spec->num_adc_nids;
5597 spec->private_adc_nids[num_adcs] = adc;
5598 spec->private_capsrc_nids[num_adcs] = cap;
5599 spec->num_adc_nids++;
5600 spec->adc_nids = spec->private_adc_nids;
5601 if (adc != cap)
5602 spec->capsrc_nids = spec->private_capsrc_nids;
5603 }
5604 }
5605 if (!spec->num_adc_nids) {
5606 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5607 " using fallback 0x%x\n",
5608 codec->chip_name, fallback_adc);
6694635d
TI
5609 spec->private_adc_nids[0] = fallback_adc;
5610 spec->adc_nids = spec->private_adc_nids;
5611 if (fallback_adc != fallback_cap) {
5612 spec->private_capsrc_nids[0] = fallback_cap;
5613 spec->capsrc_nids = spec->private_adc_nids;
5614 }
5615 }
5616}
5617
67d634c0 5618#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5619#define set_beep_amp(spec, nid, idx, dir) \
5620 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5621
5622static struct snd_pci_quirk beep_white_list[] = {
5623 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5624 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5625 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5626 {}
5627};
5628
5629static inline int has_cdefine_beep(struct hda_codec *codec)
5630{
5631 struct alc_spec *spec = codec->spec;
5632 const struct snd_pci_quirk *q;
5633 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5634 if (q)
5635 return q->value;
5636 return spec->cdefine.enable_pcbeep;
5637}
67d634c0
TI
5638#else
5639#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5640#define has_cdefine_beep(codec) 0
67d634c0 5641#endif
45bdd1c1
TI
5642
5643/*
5644 * OK, here we have finally the patch for ALC880
5645 */
5646
1da177e4
LT
5647static int patch_alc880(struct hda_codec *codec)
5648{
5649 struct alc_spec *spec;
5650 int board_config;
df694daa 5651 int err;
1da177e4 5652
e560d8d8 5653 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5654 if (spec == NULL)
5655 return -ENOMEM;
5656
5657 codec->spec = spec;
5658
f5fcc13c
TI
5659 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5660 alc880_models,
5661 alc880_cfg_tbl);
5662 if (board_config < 0) {
9a11f1aa
TI
5663 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5664 codec->chip_name);
e9edcee0 5665 board_config = ALC880_AUTO;
1da177e4 5666 }
1da177e4 5667
e9edcee0
TI
5668 if (board_config == ALC880_AUTO) {
5669 /* automatic parse from the BIOS config */
5670 err = alc880_parse_auto_config(codec);
5671 if (err < 0) {
5672 alc_free(codec);
5673 return err;
f12ab1e0 5674 } else if (!err) {
9c7f852e
TI
5675 printk(KERN_INFO
5676 "hda_codec: Cannot set up configuration "
5677 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5678 board_config = ALC880_3ST;
5679 }
1da177e4
LT
5680 }
5681
680cd536
KK
5682 err = snd_hda_attach_beep_device(codec, 0x1);
5683 if (err < 0) {
5684 alc_free(codec);
5685 return err;
5686 }
5687
df694daa 5688 if (board_config != ALC880_AUTO)
e9c364c0 5689 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5690
1da177e4
LT
5691 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5692 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5693 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5694
1da177e4
LT
5695 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5696 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5697
f12ab1e0 5698 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5699 /* check whether NID 0x07 is valid */
54d17403 5700 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5701 /* get type */
a22d543a 5702 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5703 if (wcap != AC_WID_AUD_IN) {
5704 spec->adc_nids = alc880_adc_nids_alt;
5705 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5706 } else {
5707 spec->adc_nids = alc880_adc_nids;
5708 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5709 }
5710 }
b59bdf3b 5711 set_capture_mixer(codec);
45bdd1c1 5712 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5713
2134ea4f
TI
5714 spec->vmaster_nid = 0x0c;
5715
1da177e4 5716 codec->patch_ops = alc_patch_ops;
e9edcee0 5717 if (board_config == ALC880_AUTO)
ae6b813a 5718 spec->init_hook = alc880_auto_init;
cb53c626
TI
5719#ifdef CONFIG_SND_HDA_POWER_SAVE
5720 if (!spec->loopback.amplist)
5721 spec->loopback.amplist = alc880_loopbacks;
5722#endif
1da177e4
LT
5723
5724 return 0;
5725}
5726
e9edcee0 5727
1da177e4
LT
5728/*
5729 * ALC260 support
5730 */
5731
e9edcee0
TI
5732static hda_nid_t alc260_dac_nids[1] = {
5733 /* front */
5734 0x02,
5735};
5736
5737static hda_nid_t alc260_adc_nids[1] = {
5738 /* ADC0 */
5739 0x04,
5740};
5741
df694daa 5742static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5743 /* ADC1 */
5744 0x05,
5745};
5746
d57fdac0
JW
5747/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5748 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5749 */
5750static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5751 /* ADC0, ADC1 */
5752 0x04, 0x05
5753};
5754
e9edcee0
TI
5755#define ALC260_DIGOUT_NID 0x03
5756#define ALC260_DIGIN_NID 0x06
5757
5758static struct hda_input_mux alc260_capture_source = {
5759 .num_items = 4,
5760 .items = {
5761 { "Mic", 0x0 },
5762 { "Front Mic", 0x1 },
5763 { "Line", 0x2 },
5764 { "CD", 0x4 },
5765 },
5766};
5767
17e7aec6 5768/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5769 * headphone jack and the internal CD lines since these are the only pins at
5770 * which audio can appear. For flexibility, also allow the option of
5771 * recording the mixer output on the second ADC (ADC0 doesn't have a
5772 * connection to the mixer output).
a9430dd8 5773 */
a1e8d2da
JW
5774static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5775 {
5776 .num_items = 3,
5777 .items = {
5778 { "Mic/Line", 0x0 },
5779 { "CD", 0x4 },
5780 { "Headphone", 0x2 },
5781 },
a9430dd8 5782 },
a1e8d2da
JW
5783 {
5784 .num_items = 4,
5785 .items = {
5786 { "Mic/Line", 0x0 },
5787 { "CD", 0x4 },
5788 { "Headphone", 0x2 },
5789 { "Mixer", 0x5 },
5790 },
5791 },
5792
a9430dd8
JW
5793};
5794
a1e8d2da
JW
5795/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5796 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5797 */
a1e8d2da
JW
5798static struct hda_input_mux alc260_acer_capture_sources[2] = {
5799 {
5800 .num_items = 4,
5801 .items = {
5802 { "Mic", 0x0 },
5803 { "Line", 0x2 },
5804 { "CD", 0x4 },
5805 { "Headphone", 0x5 },
5806 },
5807 },
5808 {
5809 .num_items = 5,
5810 .items = {
5811 { "Mic", 0x0 },
5812 { "Line", 0x2 },
5813 { "CD", 0x4 },
5814 { "Headphone", 0x6 },
5815 { "Mixer", 0x5 },
5816 },
0bfc90e9
JW
5817 },
5818};
cc959489
MS
5819
5820/* Maxdata Favorit 100XS */
5821static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5822 {
5823 .num_items = 2,
5824 .items = {
5825 { "Line/Mic", 0x0 },
5826 { "CD", 0x4 },
5827 },
5828 },
5829 {
5830 .num_items = 3,
5831 .items = {
5832 { "Line/Mic", 0x0 },
5833 { "CD", 0x4 },
5834 { "Mixer", 0x5 },
5835 },
5836 },
5837};
5838
1da177e4
LT
5839/*
5840 * This is just place-holder, so there's something for alc_build_pcms to look
5841 * at when it calculates the maximum number of channels. ALC260 has no mixer
5842 * element which allows changing the channel mode, so the verb list is
5843 * never used.
5844 */
d2a6d7dc 5845static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5846 { 2, NULL },
5847};
5848
df694daa
KY
5849
5850/* Mixer combinations
5851 *
5852 * basic: base_output + input + pc_beep + capture
5853 * HP: base_output + input + capture_alt
5854 * HP_3013: hp_3013 + input + capture
5855 * fujitsu: fujitsu + capture
0bfc90e9 5856 * acer: acer + capture
df694daa
KY
5857 */
5858
5859static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5860 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5861 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5862 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5863 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5864 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5865 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5866 { } /* end */
f12ab1e0 5867};
1da177e4 5868
df694daa 5869static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5870 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5871 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5872 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5873 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5875 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5876 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5877 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5878 { } /* end */
5879};
5880
bec15c3a
TI
5881/* update HP, line and mono out pins according to the master switch */
5882static void alc260_hp_master_update(struct hda_codec *codec,
5883 hda_nid_t hp, hda_nid_t line,
5884 hda_nid_t mono)
5885{
5886 struct alc_spec *spec = codec->spec;
5887 unsigned int val = spec->master_sw ? PIN_HP : 0;
5888 /* change HP and line-out pins */
30cde0aa 5889 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5890 val);
30cde0aa 5891 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5892 val);
5893 /* mono (speaker) depending on the HP jack sense */
5894 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5895 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5896 val);
5897}
5898
5899static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5900 struct snd_ctl_elem_value *ucontrol)
5901{
5902 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5903 struct alc_spec *spec = codec->spec;
5904 *ucontrol->value.integer.value = spec->master_sw;
5905 return 0;
5906}
5907
5908static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5909 struct snd_ctl_elem_value *ucontrol)
5910{
5911 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5912 struct alc_spec *spec = codec->spec;
5913 int val = !!*ucontrol->value.integer.value;
5914 hda_nid_t hp, line, mono;
5915
5916 if (val == spec->master_sw)
5917 return 0;
5918 spec->master_sw = val;
5919 hp = (kcontrol->private_value >> 16) & 0xff;
5920 line = (kcontrol->private_value >> 8) & 0xff;
5921 mono = kcontrol->private_value & 0xff;
5922 alc260_hp_master_update(codec, hp, line, mono);
5923 return 1;
5924}
5925
5926static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5927 {
5928 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5929 .name = "Master Playback Switch",
5b0cb1d8 5930 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5931 .info = snd_ctl_boolean_mono_info,
5932 .get = alc260_hp_master_sw_get,
5933 .put = alc260_hp_master_sw_put,
5934 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5935 },
5936 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5937 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5938 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5939 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5940 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5941 HDA_OUTPUT),
5942 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5943 { } /* end */
5944};
5945
5946static struct hda_verb alc260_hp_unsol_verbs[] = {
5947 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5948 {},
5949};
5950
5951static void alc260_hp_automute(struct hda_codec *codec)
5952{
5953 struct alc_spec *spec = codec->spec;
bec15c3a 5954
864f92be 5955 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5956 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5957}
5958
5959static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5960{
5961 if ((res >> 26) == ALC880_HP_EVENT)
5962 alc260_hp_automute(codec);
5963}
5964
df694daa 5965static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5966 {
5967 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5968 .name = "Master Playback Switch",
5b0cb1d8 5969 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5970 .info = snd_ctl_boolean_mono_info,
5971 .get = alc260_hp_master_sw_get,
5972 .put = alc260_hp_master_sw_put,
30cde0aa 5973 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5974 },
df694daa
KY
5975 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5976 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5977 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5978 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5979 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5980 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5981 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5982 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5983 { } /* end */
5984};
5985
3f878308
KY
5986static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5987 .ops = &snd_hda_bind_vol,
5988 .values = {
5989 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5990 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5991 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5992 0
5993 },
5994};
5995
5996static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5997 .ops = &snd_hda_bind_sw,
5998 .values = {
5999 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6000 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6001 0
6002 },
6003};
6004
6005static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6006 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6007 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6008 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6010 { } /* end */
6011};
6012
bec15c3a
TI
6013static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6014 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6015 {},
6016};
6017
6018static void alc260_hp_3013_automute(struct hda_codec *codec)
6019{
6020 struct alc_spec *spec = codec->spec;
bec15c3a 6021
864f92be 6022 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 6023 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
6024}
6025
6026static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6027 unsigned int res)
6028{
6029 if ((res >> 26) == ALC880_HP_EVENT)
6030 alc260_hp_3013_automute(codec);
6031}
6032
3f878308
KY
6033static void alc260_hp_3012_automute(struct hda_codec *codec)
6034{
864f92be 6035 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 6036
3f878308
KY
6037 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6038 bits);
6039 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6040 bits);
6041 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6042 bits);
6043}
6044
6045static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6046 unsigned int res)
6047{
6048 if ((res >> 26) == ALC880_HP_EVENT)
6049 alc260_hp_3012_automute(codec);
6050}
6051
6052/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6053 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6054 */
c8b6bf9b 6055static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6056 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6057 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6058 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6059 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6060 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6061 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6062 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6063 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6064 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6065 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6066 { } /* end */
6067};
6068
a1e8d2da
JW
6069/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6070 * versions of the ALC260 don't act on requests to enable mic bias from NID
6071 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6072 * datasheet doesn't mention this restriction. At this stage it's not clear
6073 * whether this behaviour is intentional or is a hardware bug in chip
6074 * revisions available in early 2006. Therefore for now allow the
6075 * "Headphone Jack Mode" control to span all choices, but if it turns out
6076 * that the lack of mic bias for this NID is intentional we could change the
6077 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6078 *
6079 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6080 * don't appear to make the mic bias available from the "line" jack, even
6081 * though the NID used for this jack (0x14) can supply it. The theory is
6082 * that perhaps Acer have included blocking capacitors between the ALC260
6083 * and the output jack. If this turns out to be the case for all such
6084 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6085 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6086 *
6087 * The C20x Tablet series have a mono internal speaker which is controlled
6088 * via the chip's Mono sum widget and pin complex, so include the necessary
6089 * controls for such models. On models without a "mono speaker" the control
6090 * won't do anything.
a1e8d2da 6091 */
0bfc90e9
JW
6092static struct snd_kcontrol_new alc260_acer_mixer[] = {
6093 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6094 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6095 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6096 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6097 HDA_OUTPUT),
31bffaa9 6098 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6099 HDA_INPUT),
0bfc90e9
JW
6100 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6101 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6103 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6104 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6105 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6106 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6107 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6108 { } /* end */
6109};
6110
cc959489
MS
6111/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6112 */
6113static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6114 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6115 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6116 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6117 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6118 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6119 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6120 { } /* end */
6121};
6122
bc9f98a9
KY
6123/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6124 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6125 */
6126static struct snd_kcontrol_new alc260_will_mixer[] = {
6127 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6128 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6129 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6130 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6131 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6132 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6133 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6134 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6135 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6136 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6137 { } /* end */
6138};
6139
6140/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6141 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6142 */
6143static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6144 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6145 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6146 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6147 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6148 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6149 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6150 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6151 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6152 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6153 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6154 { } /* end */
6155};
6156
df694daa
KY
6157/*
6158 * initialization verbs
6159 */
1da177e4
LT
6160static struct hda_verb alc260_init_verbs[] = {
6161 /* Line In pin widget for input */
05acb863 6162 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6163 /* CD pin widget for input */
05acb863 6164 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6165 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6166 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6167 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6168 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6169 /* LINE-2 is used for line-out in rear */
05acb863 6170 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6171 /* select line-out */
fd56f2db 6172 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6173 /* LINE-OUT pin */
05acb863 6174 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6175 /* enable HP */
05acb863 6176 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6177 /* enable Mono */
05acb863
TI
6178 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6179 /* mute capture amp left and right */
16ded525 6180 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6181 /* set connection select to line in (default select for this ADC) */
6182 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6183 /* mute capture amp left and right */
6184 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6185 /* set connection select to line in (default select for this ADC) */
6186 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6187 /* set vol=0 Line-Out mixer amp left and right */
6188 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6189 /* unmute pin widget amp left and right (no gain on this amp) */
6190 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6191 /* set vol=0 HP mixer amp left and right */
6192 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6193 /* unmute pin widget amp left and right (no gain on this amp) */
6194 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6195 /* set vol=0 Mono mixer amp left and right */
6196 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6197 /* unmute pin widget amp left and right (no gain on this amp) */
6198 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6199 /* unmute LINE-2 out pin */
6200 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6201 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6202 * Line In 2 = 0x03
6203 */
cb53c626
TI
6204 /* mute analog inputs */
6205 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6206 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6207 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6208 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6209 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6210 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6211 /* mute Front out path */
6212 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6213 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6214 /* mute Headphone out path */
6215 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6216 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6217 /* mute Mono out path */
6218 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6219 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6220 { }
6221};
6222
474167d6 6223#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6224static struct hda_verb alc260_hp_init_verbs[] = {
6225 /* Headphone and output */
6226 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6227 /* mono output */
6228 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6229 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6230 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6231 /* Mic2 (front panel) pin widget for input and vref at 80% */
6232 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6233 /* Line In pin widget for input */
6234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6235 /* Line-2 pin widget for output */
6236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6237 /* CD pin widget for input */
6238 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6239 /* unmute amp left and right */
6240 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6241 /* set connection select to line in (default select for this ADC) */
6242 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6243 /* unmute Line-Out mixer amp left and right (volume = 0) */
6244 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6245 /* mute pin widget amp left and right (no gain on this amp) */
6246 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6247 /* unmute HP mixer amp left and right (volume = 0) */
6248 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6249 /* mute pin widget amp left and right (no gain on this amp) */
6250 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6251 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6252 * Line In 2 = 0x03
6253 */
cb53c626
TI
6254 /* mute analog inputs */
6255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6256 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6259 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6260 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6261 /* Unmute Front out path */
6262 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6263 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6264 /* Unmute Headphone out path */
6265 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6266 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6267 /* Unmute Mono out path */
6268 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6269 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6270 { }
6271};
474167d6 6272#endif
df694daa
KY
6273
6274static struct hda_verb alc260_hp_3013_init_verbs[] = {
6275 /* Line out and output */
6276 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6277 /* mono output */
6278 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6279 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6280 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6281 /* Mic2 (front panel) pin widget for input and vref at 80% */
6282 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6283 /* Line In pin widget for input */
6284 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6285 /* Headphone pin widget for output */
6286 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6287 /* CD pin widget for input */
6288 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6289 /* unmute amp left and right */
6290 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6291 /* set connection select to line in (default select for this ADC) */
6292 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6293 /* unmute Line-Out mixer amp left and right (volume = 0) */
6294 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6295 /* mute pin widget amp left and right (no gain on this amp) */
6296 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6297 /* unmute HP mixer amp left and right (volume = 0) */
6298 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6299 /* mute pin widget amp left and right (no gain on this amp) */
6300 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6301 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6302 * Line In 2 = 0x03
6303 */
cb53c626
TI
6304 /* mute analog inputs */
6305 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6306 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6307 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6308 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6309 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6310 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6311 /* Unmute Front out path */
6312 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6313 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6314 /* Unmute Headphone out path */
6315 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6316 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6317 /* Unmute Mono out path */
6318 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6319 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6320 { }
6321};
6322
a9430dd8 6323/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6324 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6325 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6326 */
6327static struct hda_verb alc260_fujitsu_init_verbs[] = {
6328 /* Disable all GPIOs */
6329 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6330 /* Internal speaker is connected to headphone pin */
6331 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6332 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6333 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6334 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6335 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6336 /* Ensure all other unused pins are disabled and muted. */
6337 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6338 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6339 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6340 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6341 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6342 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6343 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6345
6346 /* Disable digital (SPDIF) pins */
6347 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6348 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6349
ea1fb29a 6350 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6351 * when acting as an output.
6352 */
6353 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6354
f7ace40d 6355 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6357 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6358 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6359 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6360 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6361 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6362 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6363 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6364 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6365
f7ace40d
JW
6366 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6367 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6368 /* Unmute Line1 pin widget output buffer since it starts as an output.
6369 * If the pin mode is changed by the user the pin mode control will
6370 * take care of enabling the pin's input/output buffers as needed.
6371 * Therefore there's no need to enable the input buffer at this
6372 * stage.
cdcd9268 6373 */
f7ace40d 6374 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6375 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6376 * mixer ctrl)
6377 */
f7ace40d
JW
6378 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6379
6380 /* Mute capture amp left and right */
6381 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6382 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6383 * in (on mic1 pin)
6384 */
6385 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6386
6387 /* Do the same for the second ADC: mute capture input amp and
6388 * set ADC connection to line in (on mic1 pin)
6389 */
6390 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6391 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6392
6393 /* Mute all inputs to mixer widget (even unconnected ones) */
6394 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6395 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6397 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6398 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6400 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6401 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6402
6403 { }
a9430dd8
JW
6404};
6405
0bfc90e9
JW
6406/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6407 * similar laptops (adapted from Fujitsu init verbs).
6408 */
6409static struct hda_verb alc260_acer_init_verbs[] = {
6410 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6411 * the headphone jack. Turn this on and rely on the standard mute
6412 * methods whenever the user wants to turn these outputs off.
6413 */
6414 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6415 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6416 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6417 /* Internal speaker/Headphone jack is connected to Line-out pin */
6418 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6419 /* Internal microphone/Mic jack is connected to Mic1 pin */
6420 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6421 /* Line In jack is connected to Line1 pin */
6422 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6423 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6424 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6425 /* Ensure all other unused pins are disabled and muted. */
6426 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6427 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6428 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6429 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6431 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6432 /* Disable digital (SPDIF) pins */
6433 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6434 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6435
ea1fb29a 6436 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6437 * bus when acting as outputs.
6438 */
6439 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6440 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6441
6442 /* Start with output sum widgets muted and their output gains at min */
6443 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6444 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6445 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6447 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6448 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6449 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6450 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6451 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6452
f12ab1e0
TI
6453 /* Unmute Line-out pin widget amp left and right
6454 * (no equiv mixer ctrl)
6455 */
0bfc90e9 6456 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6457 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6458 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6459 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6460 * inputs. If the pin mode is changed by the user the pin mode control
6461 * will take care of enabling the pin's input/output buffers as needed.
6462 * Therefore there's no need to enable the input buffer at this
6463 * stage.
6464 */
6465 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6466 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6467
6468 /* Mute capture amp left and right */
6469 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6470 /* Set ADC connection select to match default mixer setting - mic
6471 * (on mic1 pin)
6472 */
6473 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6474
6475 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6476 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6477 */
6478 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6479 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6480
6481 /* Mute all inputs to mixer widget (even unconnected ones) */
6482 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6485 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6487 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6489 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6490
6491 { }
6492};
6493
cc959489
MS
6494/* Initialisation sequence for Maxdata Favorit 100XS
6495 * (adapted from Acer init verbs).
6496 */
6497static struct hda_verb alc260_favorit100_init_verbs[] = {
6498 /* GPIO 0 enables the output jack.
6499 * Turn this on and rely on the standard mute
6500 * methods whenever the user wants to turn these outputs off.
6501 */
6502 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6503 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6504 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6505 /* Line/Mic input jack is connected to Mic1 pin */
6506 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6507 /* Ensure all other unused pins are disabled and muted. */
6508 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6509 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6510 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6511 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6512 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6513 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6514 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6515 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6516 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6517 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6518 /* Disable digital (SPDIF) pins */
6519 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6520 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6521
6522 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6523 * bus when acting as outputs.
6524 */
6525 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6526 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6527
6528 /* Start with output sum widgets muted and their output gains at min */
6529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6531 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6533 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6534 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6535 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6536 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6537 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6538
6539 /* Unmute Line-out pin widget amp left and right
6540 * (no equiv mixer ctrl)
6541 */
6542 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6543 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6544 * inputs. If the pin mode is changed by the user the pin mode control
6545 * will take care of enabling the pin's input/output buffers as needed.
6546 * Therefore there's no need to enable the input buffer at this
6547 * stage.
6548 */
6549 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6550
6551 /* Mute capture amp left and right */
6552 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6553 /* Set ADC connection select to match default mixer setting - mic
6554 * (on mic1 pin)
6555 */
6556 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6557
6558 /* Do similar with the second ADC: mute capture input amp and
6559 * set ADC connection to mic to match ALSA's default state.
6560 */
6561 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6562 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6563
6564 /* Mute all inputs to mixer widget (even unconnected ones) */
6565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6570 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6571 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6573
6574 { }
6575};
6576
bc9f98a9
KY
6577static struct hda_verb alc260_will_verbs[] = {
6578 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6579 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6580 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6581 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6582 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6583 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6584 {}
6585};
6586
6587static struct hda_verb alc260_replacer_672v_verbs[] = {
6588 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6589 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6590 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6591
6592 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6593 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6594 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6595
6596 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6597 {}
6598};
6599
6600/* toggle speaker-output according to the hp-jack state */
6601static void alc260_replacer_672v_automute(struct hda_codec *codec)
6602{
6603 unsigned int present;
6604
6605 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6606 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6607 if (present) {
82beb8fd
TI
6608 snd_hda_codec_write_cache(codec, 0x01, 0,
6609 AC_VERB_SET_GPIO_DATA, 1);
6610 snd_hda_codec_write_cache(codec, 0x0f, 0,
6611 AC_VERB_SET_PIN_WIDGET_CONTROL,
6612 PIN_HP);
bc9f98a9 6613 } else {
82beb8fd
TI
6614 snd_hda_codec_write_cache(codec, 0x01, 0,
6615 AC_VERB_SET_GPIO_DATA, 0);
6616 snd_hda_codec_write_cache(codec, 0x0f, 0,
6617 AC_VERB_SET_PIN_WIDGET_CONTROL,
6618 PIN_OUT);
bc9f98a9
KY
6619 }
6620}
6621
6622static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6623 unsigned int res)
6624{
6625 if ((res >> 26) == ALC880_HP_EVENT)
6626 alc260_replacer_672v_automute(codec);
6627}
6628
3f878308
KY
6629static struct hda_verb alc260_hp_dc7600_verbs[] = {
6630 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6631 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6632 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6633 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6634 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6635 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6636 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6637 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6638 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6639 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6640 {}
6641};
6642
7cf51e48
JW
6643/* Test configuration for debugging, modelled after the ALC880 test
6644 * configuration.
6645 */
6646#ifdef CONFIG_SND_DEBUG
6647static hda_nid_t alc260_test_dac_nids[1] = {
6648 0x02,
6649};
6650static hda_nid_t alc260_test_adc_nids[2] = {
6651 0x04, 0x05,
6652};
a1e8d2da 6653/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6654 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6655 * is NID 0x04.
17e7aec6 6656 */
a1e8d2da
JW
6657static struct hda_input_mux alc260_test_capture_sources[2] = {
6658 {
6659 .num_items = 7,
6660 .items = {
6661 { "MIC1 pin", 0x0 },
6662 { "MIC2 pin", 0x1 },
6663 { "LINE1 pin", 0x2 },
6664 { "LINE2 pin", 0x3 },
6665 { "CD pin", 0x4 },
6666 { "LINE-OUT pin", 0x5 },
6667 { "HP-OUT pin", 0x6 },
6668 },
6669 },
6670 {
6671 .num_items = 8,
6672 .items = {
6673 { "MIC1 pin", 0x0 },
6674 { "MIC2 pin", 0x1 },
6675 { "LINE1 pin", 0x2 },
6676 { "LINE2 pin", 0x3 },
6677 { "CD pin", 0x4 },
6678 { "Mixer", 0x5 },
6679 { "LINE-OUT pin", 0x6 },
6680 { "HP-OUT pin", 0x7 },
6681 },
7cf51e48
JW
6682 },
6683};
6684static struct snd_kcontrol_new alc260_test_mixer[] = {
6685 /* Output driver widgets */
6686 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6687 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6688 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6689 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6690 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6691 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6692
a1e8d2da
JW
6693 /* Modes for retasking pin widgets
6694 * Note: the ALC260 doesn't seem to act on requests to enable mic
6695 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6696 * mention this restriction. At this stage it's not clear whether
6697 * this behaviour is intentional or is a hardware bug in chip
6698 * revisions available at least up until early 2006. Therefore for
6699 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6700 * choices, but if it turns out that the lack of mic bias for these
6701 * NIDs is intentional we could change their modes from
6702 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6703 */
7cf51e48
JW
6704 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6705 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6706 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6707 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6708 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6709 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6710
6711 /* Loopback mixer controls */
6712 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6713 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6714 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6715 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6716 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6717 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6718 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6719 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6720 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6721 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6722 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6723 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6724 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6725 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6726
6727 /* Controls for GPIO pins, assuming they are configured as outputs */
6728 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6729 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6730 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6731 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6732
92621f13
JW
6733 /* Switches to allow the digital IO pins to be enabled. The datasheet
6734 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6735 * make this output available should provide clarification.
92621f13
JW
6736 */
6737 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6738 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6739
f8225f6d
JW
6740 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6741 * this output to turn on an external amplifier.
6742 */
6743 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6744 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6745
7cf51e48
JW
6746 { } /* end */
6747};
6748static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6749 /* Enable all GPIOs as outputs with an initial value of 0 */
6750 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6751 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6752 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6753
7cf51e48
JW
6754 /* Enable retasking pins as output, initially without power amp */
6755 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6756 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6757 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6759 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6760 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6761
92621f13
JW
6762 /* Disable digital (SPDIF) pins initially, but users can enable
6763 * them via a mixer switch. In the case of SPDIF-out, this initverb
6764 * payload also sets the generation to 0, output to be in "consumer"
6765 * PCM format, copyright asserted, no pre-emphasis and no validity
6766 * control.
6767 */
7cf51e48
JW
6768 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6769 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6770
ea1fb29a 6771 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6772 * OUT1 sum bus when acting as an output.
6773 */
6774 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6775 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6776 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6777 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6778
6779 /* Start with output sum widgets muted and their output gains at min */
6780 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6781 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6782 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6783 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6784 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6785 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6786 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6787 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6788 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6789
cdcd9268
JW
6790 /* Unmute retasking pin widget output buffers since the default
6791 * state appears to be output. As the pin mode is changed by the
6792 * user the pin mode control will take care of enabling the pin's
6793 * input/output buffers as needed.
6794 */
7cf51e48
JW
6795 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6796 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6797 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6798 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6799 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6800 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6801 /* Also unmute the mono-out pin widget */
6802 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6803
7cf51e48
JW
6804 /* Mute capture amp left and right */
6805 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6806 /* Set ADC connection select to match default mixer setting (mic1
6807 * pin)
7cf51e48
JW
6808 */
6809 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6810
6811 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6812 * set ADC connection to mic1 pin
7cf51e48
JW
6813 */
6814 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6815 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6816
6817 /* Mute all inputs to mixer widget (even unconnected ones) */
6818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6820 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6821 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6822 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6823 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6824 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6826
6827 { }
6828};
6829#endif
6830
6330079f
TI
6831#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6832#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6833
a3bcba38
TI
6834#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6835#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6836
df694daa
KY
6837/*
6838 * for BIOS auto-configuration
6839 */
16ded525 6840
df694daa 6841static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6842 const char *pfx, int *vol_bits)
df694daa
KY
6843{
6844 hda_nid_t nid_vol;
6845 unsigned long vol_val, sw_val;
df694daa
KY
6846 int err;
6847
6848 if (nid >= 0x0f && nid < 0x11) {
6849 nid_vol = nid - 0x7;
6850 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6851 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6852 } else if (nid == 0x11) {
6853 nid_vol = nid - 0x7;
6854 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6855 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6856 } else if (nid >= 0x12 && nid <= 0x15) {
6857 nid_vol = 0x08;
6858 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6859 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6860 } else
6861 return 0; /* N/A */
ea1fb29a 6862
863b4518
TI
6863 if (!(*vol_bits & (1 << nid_vol))) {
6864 /* first control for the volume widget */
0afe5f89 6865 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6866 if (err < 0)
6867 return err;
6868 *vol_bits |= (1 << nid_vol);
6869 }
0afe5f89 6870 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6871 if (err < 0)
df694daa
KY
6872 return err;
6873 return 1;
6874}
6875
6876/* add playback controls from the parsed DAC table */
6877static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6878 const struct auto_pin_cfg *cfg)
6879{
6880 hda_nid_t nid;
6881 int err;
863b4518 6882 int vols = 0;
df694daa
KY
6883
6884 spec->multiout.num_dacs = 1;
6885 spec->multiout.dac_nids = spec->private_dac_nids;
6886 spec->multiout.dac_nids[0] = 0x02;
6887
6888 nid = cfg->line_out_pins[0];
6889 if (nid) {
23112d6d
TI
6890 const char *pfx;
6891 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6892 pfx = "Master";
6893 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6894 pfx = "Speaker";
6895 else
6896 pfx = "Front";
6897 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6898 if (err < 0)
6899 return err;
6900 }
6901
82bc955f 6902 nid = cfg->speaker_pins[0];
df694daa 6903 if (nid) {
863b4518 6904 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6905 if (err < 0)
6906 return err;
6907 }
6908
eb06ed8f 6909 nid = cfg->hp_pins[0];
df694daa 6910 if (nid) {
863b4518
TI
6911 err = alc260_add_playback_controls(spec, nid, "Headphone",
6912 &vols);
df694daa
KY
6913 if (err < 0)
6914 return err;
6915 }
f12ab1e0 6916 return 0;
df694daa
KY
6917}
6918
6919/* create playback/capture controls for input pins */
05f5f477 6920static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6921 const struct auto_pin_cfg *cfg)
6922{
05f5f477 6923 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6924}
6925
6926static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6927 hda_nid_t nid, int pin_type,
6928 int sel_idx)
6929{
f6c7e546 6930 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6931 /* need the manual connection? */
6932 if (nid >= 0x12) {
6933 int idx = nid - 0x12;
6934 snd_hda_codec_write(codec, idx + 0x0b, 0,
6935 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6936 }
6937}
6938
6939static void alc260_auto_init_multi_out(struct hda_codec *codec)
6940{
6941 struct alc_spec *spec = codec->spec;
6942 hda_nid_t nid;
6943
f12ab1e0 6944 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6945 if (nid) {
6946 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6947 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6948 }
ea1fb29a 6949
82bc955f 6950 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6951 if (nid)
6952 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6953
eb06ed8f 6954 nid = spec->autocfg.hp_pins[0];
df694daa 6955 if (nid)
baba8ee9 6956 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6957}
df694daa
KY
6958
6959#define ALC260_PIN_CD_NID 0x16
6960static void alc260_auto_init_analog_input(struct hda_codec *codec)
6961{
6962 struct alc_spec *spec = codec->spec;
66ceeb6b 6963 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6964 int i;
6965
66ceeb6b
TI
6966 for (i = 0; i < cfg->num_inputs; i++) {
6967 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6968 if (nid >= 0x12) {
30ea098f 6969 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6970 if (nid != ALC260_PIN_CD_NID &&
6971 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6972 snd_hda_codec_write(codec, nid, 0,
6973 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6974 AMP_OUT_MUTE);
6975 }
6976 }
6977}
6978
7f311a46
TI
6979#define alc260_auto_init_input_src alc880_auto_init_input_src
6980
df694daa
KY
6981/*
6982 * generic initialization of ADC, input mixers and output mixers
6983 */
6984static struct hda_verb alc260_volume_init_verbs[] = {
6985 /*
6986 * Unmute ADC0-1 and set the default input to mic-in
6987 */
6988 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6989 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6990 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6991 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6992
df694daa
KY
6993 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6994 * mixer widget
f12ab1e0
TI
6995 * Note: PASD motherboards uses the Line In 2 as the input for
6996 * front panel mic (mic 2)
df694daa
KY
6997 */
6998 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6999 /* mute analog inputs */
7000 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7001 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7002 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7003 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7004 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7005
7006 /*
7007 * Set up output mixers (0x08 - 0x0a)
7008 */
7009 /* set vol=0 to output mixers */
7010 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7011 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7012 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7013 /* set up input amps for analog loopback */
7014 /* Amp Indices: DAC = 0, mixer = 1 */
7015 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7016 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7017 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7018 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7019 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7020 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7021
df694daa
KY
7022 { }
7023};
7024
7025static int alc260_parse_auto_config(struct hda_codec *codec)
7026{
7027 struct alc_spec *spec = codec->spec;
df694daa
KY
7028 int err;
7029 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7030
f12ab1e0
TI
7031 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7032 alc260_ignore);
7033 if (err < 0)
df694daa 7034 return err;
f12ab1e0
TI
7035 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7036 if (err < 0)
4a471b7d 7037 return err;
603c4019 7038 if (!spec->kctls.list)
df694daa 7039 return 0; /* can't find valid BIOS pin config */
05f5f477 7040 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7041 if (err < 0)
df694daa
KY
7042 return err;
7043
7044 spec->multiout.max_channels = 2;
7045
0852d7a6 7046 if (spec->autocfg.dig_outs)
df694daa 7047 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7048 if (spec->kctls.list)
d88897ea 7049 add_mixer(spec, spec->kctls.list);
df694daa 7050
d88897ea 7051 add_verb(spec, alc260_volume_init_verbs);
df694daa 7052
a1e8d2da 7053 spec->num_mux_defs = 1;
61b9b9b1 7054 spec->input_mux = &spec->private_imux[0];
df694daa 7055
6227cdce 7056 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7057
df694daa
KY
7058 return 1;
7059}
7060
ae6b813a
TI
7061/* additional initialization for auto-configuration model */
7062static void alc260_auto_init(struct hda_codec *codec)
df694daa 7063{
f6c7e546 7064 struct alc_spec *spec = codec->spec;
df694daa
KY
7065 alc260_auto_init_multi_out(codec);
7066 alc260_auto_init_analog_input(codec);
7f311a46 7067 alc260_auto_init_input_src(codec);
757899ac 7068 alc_auto_init_digital(codec);
f6c7e546 7069 if (spec->unsol_event)
7fb0d78f 7070 alc_inithook(codec);
df694daa
KY
7071}
7072
cb53c626
TI
7073#ifdef CONFIG_SND_HDA_POWER_SAVE
7074static struct hda_amp_list alc260_loopbacks[] = {
7075 { 0x07, HDA_INPUT, 0 },
7076 { 0x07, HDA_INPUT, 1 },
7077 { 0x07, HDA_INPUT, 2 },
7078 { 0x07, HDA_INPUT, 3 },
7079 { 0x07, HDA_INPUT, 4 },
7080 { } /* end */
7081};
7082#endif
7083
fc091769
TI
7084/*
7085 * Pin config fixes
7086 */
7087enum {
7088 PINFIX_HP_DC5750,
7089};
7090
fc091769
TI
7091static const struct alc_fixup alc260_fixups[] = {
7092 [PINFIX_HP_DC5750] = {
73413b12
TI
7093 .pins = (const struct alc_pincfg[]) {
7094 { 0x11, 0x90130110 }, /* speaker */
7095 { }
7096 }
fc091769
TI
7097 },
7098};
7099
7100static struct snd_pci_quirk alc260_fixup_tbl[] = {
7101 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7102 {}
7103};
7104
df694daa
KY
7105/*
7106 * ALC260 configurations
7107 */
f5fcc13c
TI
7108static const char *alc260_models[ALC260_MODEL_LAST] = {
7109 [ALC260_BASIC] = "basic",
7110 [ALC260_HP] = "hp",
7111 [ALC260_HP_3013] = "hp-3013",
2922c9af 7112 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7113 [ALC260_FUJITSU_S702X] = "fujitsu",
7114 [ALC260_ACER] = "acer",
bc9f98a9
KY
7115 [ALC260_WILL] = "will",
7116 [ALC260_REPLACER_672V] = "replacer",
cc959489 7117 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7118#ifdef CONFIG_SND_DEBUG
f5fcc13c 7119 [ALC260_TEST] = "test",
7cf51e48 7120#endif
f5fcc13c
TI
7121 [ALC260_AUTO] = "auto",
7122};
7123
7124static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7125 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7126 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7127 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7128 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7129 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7130 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7131 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7132 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7133 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7134 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7135 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7136 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7137 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7138 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7139 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7140 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7141 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7142 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7143 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7144 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7145 {}
7146};
7147
7148static struct alc_config_preset alc260_presets[] = {
7149 [ALC260_BASIC] = {
7150 .mixers = { alc260_base_output_mixer,
45bdd1c1 7151 alc260_input_mixer },
df694daa
KY
7152 .init_verbs = { alc260_init_verbs },
7153 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7154 .dac_nids = alc260_dac_nids,
f9e336f6 7155 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7156 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7157 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7158 .channel_mode = alc260_modes,
7159 .input_mux = &alc260_capture_source,
7160 },
7161 [ALC260_HP] = {
bec15c3a 7162 .mixers = { alc260_hp_output_mixer,
f9e336f6 7163 alc260_input_mixer },
bec15c3a
TI
7164 .init_verbs = { alc260_init_verbs,
7165 alc260_hp_unsol_verbs },
df694daa
KY
7166 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7167 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7168 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7169 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7170 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7171 .channel_mode = alc260_modes,
7172 .input_mux = &alc260_capture_source,
bec15c3a
TI
7173 .unsol_event = alc260_hp_unsol_event,
7174 .init_hook = alc260_hp_automute,
df694daa 7175 },
3f878308
KY
7176 [ALC260_HP_DC7600] = {
7177 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7178 alc260_input_mixer },
3f878308
KY
7179 .init_verbs = { alc260_init_verbs,
7180 alc260_hp_dc7600_verbs },
7181 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7182 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7183 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7184 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7185 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7186 .channel_mode = alc260_modes,
7187 .input_mux = &alc260_capture_source,
7188 .unsol_event = alc260_hp_3012_unsol_event,
7189 .init_hook = alc260_hp_3012_automute,
7190 },
df694daa
KY
7191 [ALC260_HP_3013] = {
7192 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7193 alc260_input_mixer },
bec15c3a
TI
7194 .init_verbs = { alc260_hp_3013_init_verbs,
7195 alc260_hp_3013_unsol_verbs },
df694daa
KY
7196 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7197 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7198 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7199 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7200 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7201 .channel_mode = alc260_modes,
7202 .input_mux = &alc260_capture_source,
bec15c3a
TI
7203 .unsol_event = alc260_hp_3013_unsol_event,
7204 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7205 },
7206 [ALC260_FUJITSU_S702X] = {
f9e336f6 7207 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7208 .init_verbs = { alc260_fujitsu_init_verbs },
7209 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7210 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7211 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7212 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7213 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7214 .channel_mode = alc260_modes,
a1e8d2da
JW
7215 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7216 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7217 },
0bfc90e9 7218 [ALC260_ACER] = {
f9e336f6 7219 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7220 .init_verbs = { alc260_acer_init_verbs },
7221 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7222 .dac_nids = alc260_dac_nids,
7223 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7224 .adc_nids = alc260_dual_adc_nids,
7225 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7226 .channel_mode = alc260_modes,
a1e8d2da
JW
7227 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7228 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7229 },
cc959489
MS
7230 [ALC260_FAVORIT100] = {
7231 .mixers = { alc260_favorit100_mixer },
7232 .init_verbs = { alc260_favorit100_init_verbs },
7233 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7234 .dac_nids = alc260_dac_nids,
7235 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7236 .adc_nids = alc260_dual_adc_nids,
7237 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7238 .channel_mode = alc260_modes,
7239 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7240 .input_mux = alc260_favorit100_capture_sources,
7241 },
bc9f98a9 7242 [ALC260_WILL] = {
f9e336f6 7243 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7244 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7245 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7246 .dac_nids = alc260_dac_nids,
7247 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7248 .adc_nids = alc260_adc_nids,
7249 .dig_out_nid = ALC260_DIGOUT_NID,
7250 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7251 .channel_mode = alc260_modes,
7252 .input_mux = &alc260_capture_source,
7253 },
7254 [ALC260_REPLACER_672V] = {
f9e336f6 7255 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7256 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7257 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7258 .dac_nids = alc260_dac_nids,
7259 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7260 .adc_nids = alc260_adc_nids,
7261 .dig_out_nid = ALC260_DIGOUT_NID,
7262 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7263 .channel_mode = alc260_modes,
7264 .input_mux = &alc260_capture_source,
7265 .unsol_event = alc260_replacer_672v_unsol_event,
7266 .init_hook = alc260_replacer_672v_automute,
7267 },
7cf51e48
JW
7268#ifdef CONFIG_SND_DEBUG
7269 [ALC260_TEST] = {
f9e336f6 7270 .mixers = { alc260_test_mixer },
7cf51e48
JW
7271 .init_verbs = { alc260_test_init_verbs },
7272 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7273 .dac_nids = alc260_test_dac_nids,
7274 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7275 .adc_nids = alc260_test_adc_nids,
7276 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7277 .channel_mode = alc260_modes,
a1e8d2da
JW
7278 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7279 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7280 },
7281#endif
df694daa
KY
7282};
7283
7284static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7285{
7286 struct alc_spec *spec;
df694daa 7287 int err, board_config;
1da177e4 7288
e560d8d8 7289 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7290 if (spec == NULL)
7291 return -ENOMEM;
7292
7293 codec->spec = spec;
7294
f5fcc13c
TI
7295 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7296 alc260_models,
7297 alc260_cfg_tbl);
7298 if (board_config < 0) {
9a11f1aa 7299 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7300 codec->chip_name);
df694daa 7301 board_config = ALC260_AUTO;
16ded525 7302 }
1da177e4 7303
fc091769
TI
7304 if (board_config == ALC260_AUTO)
7305 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1);
7306
df694daa
KY
7307 if (board_config == ALC260_AUTO) {
7308 /* automatic parse from the BIOS config */
7309 err = alc260_parse_auto_config(codec);
7310 if (err < 0) {
7311 alc_free(codec);
7312 return err;
f12ab1e0 7313 } else if (!err) {
9c7f852e
TI
7314 printk(KERN_INFO
7315 "hda_codec: Cannot set up configuration "
7316 "from BIOS. Using base mode...\n");
df694daa
KY
7317 board_config = ALC260_BASIC;
7318 }
a9430dd8 7319 }
e9edcee0 7320
680cd536
KK
7321 err = snd_hda_attach_beep_device(codec, 0x1);
7322 if (err < 0) {
7323 alc_free(codec);
7324 return err;
7325 }
7326
df694daa 7327 if (board_config != ALC260_AUTO)
e9c364c0 7328 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7329
1da177e4
LT
7330 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7331 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7332 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7333
a3bcba38
TI
7334 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7335 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7336
4ef0ef19
TI
7337 if (!spec->adc_nids && spec->input_mux) {
7338 /* check whether NID 0x04 is valid */
7339 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7340 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7341 /* get type */
7342 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7343 spec->adc_nids = alc260_adc_nids_alt;
7344 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7345 } else {
7346 spec->adc_nids = alc260_adc_nids;
7347 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7348 }
7349 }
b59bdf3b 7350 set_capture_mixer(codec);
45bdd1c1 7351 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7352
fc091769
TI
7353 if (board_config == ALC260_AUTO)
7354 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0);
7355
2134ea4f
TI
7356 spec->vmaster_nid = 0x08;
7357
1da177e4 7358 codec->patch_ops = alc_patch_ops;
df694daa 7359 if (board_config == ALC260_AUTO)
ae6b813a 7360 spec->init_hook = alc260_auto_init;
cb53c626
TI
7361#ifdef CONFIG_SND_HDA_POWER_SAVE
7362 if (!spec->loopback.amplist)
7363 spec->loopback.amplist = alc260_loopbacks;
7364#endif
1da177e4
LT
7365
7366 return 0;
7367}
7368
e9edcee0 7369
1da177e4 7370/*
4953550a 7371 * ALC882/883/885/888/889 support
1da177e4
LT
7372 *
7373 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7374 * configuration. Each pin widget can choose any input DACs and a mixer.
7375 * Each ADC is connected from a mixer of all inputs. This makes possible
7376 * 6-channel independent captures.
7377 *
7378 * In addition, an independent DAC for the multi-playback (not used in this
7379 * driver yet).
7380 */
df694daa
KY
7381#define ALC882_DIGOUT_NID 0x06
7382#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7383#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7384#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7385#define ALC1200_DIGOUT_NID 0x10
7386
1da177e4 7387
d2a6d7dc 7388static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7389 { 8, NULL }
7390};
7391
4953550a 7392/* DACs */
1da177e4
LT
7393static hda_nid_t alc882_dac_nids[4] = {
7394 /* front, rear, clfe, rear_surr */
7395 0x02, 0x03, 0x04, 0x05
7396};
4953550a 7397#define alc883_dac_nids alc882_dac_nids
1da177e4 7398
4953550a 7399/* ADCs */
df694daa
KY
7400#define alc882_adc_nids alc880_adc_nids
7401#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7402#define alc883_adc_nids alc882_adc_nids_alt
7403static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7404static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7405#define alc889_adc_nids alc880_adc_nids
1da177e4 7406
e1406348
TI
7407static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7408static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7409#define alc883_capsrc_nids alc882_capsrc_nids_alt
7410static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7411#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7412
1da177e4
LT
7413/* input MUX */
7414/* FIXME: should be a matrix-type input source selection */
7415
7416static struct hda_input_mux alc882_capture_source = {
7417 .num_items = 4,
7418 .items = {
7419 { "Mic", 0x0 },
7420 { "Front Mic", 0x1 },
7421 { "Line", 0x2 },
7422 { "CD", 0x4 },
7423 },
7424};
41d5545d 7425
4953550a
TI
7426#define alc883_capture_source alc882_capture_source
7427
87a8c370
JK
7428static struct hda_input_mux alc889_capture_source = {
7429 .num_items = 3,
7430 .items = {
7431 { "Front Mic", 0x0 },
7432 { "Mic", 0x3 },
7433 { "Line", 0x2 },
7434 },
7435};
7436
41d5545d
KS
7437static struct hda_input_mux mb5_capture_source = {
7438 .num_items = 3,
7439 .items = {
7440 { "Mic", 0x1 },
b8f171e7 7441 { "Line", 0x7 },
41d5545d
KS
7442 { "CD", 0x4 },
7443 },
7444};
7445
e458b1fa
LY
7446static struct hda_input_mux macmini3_capture_source = {
7447 .num_items = 2,
7448 .items = {
7449 { "Line", 0x2 },
7450 { "CD", 0x4 },
7451 },
7452};
7453
4953550a
TI
7454static struct hda_input_mux alc883_3stack_6ch_intel = {
7455 .num_items = 4,
7456 .items = {
7457 { "Mic", 0x1 },
7458 { "Front Mic", 0x0 },
7459 { "Line", 0x2 },
7460 { "CD", 0x4 },
7461 },
7462};
7463
7464static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7465 .num_items = 2,
7466 .items = {
7467 { "Mic", 0x1 },
7468 { "Line", 0x2 },
7469 },
7470};
7471
7472static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7473 .num_items = 4,
7474 .items = {
7475 { "Mic", 0x0 },
28c4edb7 7476 { "Internal Mic", 0x1 },
4953550a
TI
7477 { "Line", 0x2 },
7478 { "CD", 0x4 },
7479 },
7480};
7481
7482static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7483 .num_items = 2,
7484 .items = {
7485 { "Mic", 0x0 },
28c4edb7 7486 { "Internal Mic", 0x1 },
4953550a
TI
7487 },
7488};
7489
7490static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7491 .num_items = 3,
7492 .items = {
7493 { "Mic", 0x0 },
7494 { "Front Mic", 0x1 },
7495 { "Line", 0x4 },
7496 },
7497};
7498
7499static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7500 .num_items = 2,
7501 .items = {
7502 { "Mic", 0x0 },
7503 { "Line", 0x2 },
7504 },
7505};
7506
7507static struct hda_input_mux alc889A_mb31_capture_source = {
7508 .num_items = 2,
7509 .items = {
7510 { "Mic", 0x0 },
7511 /* Front Mic (0x01) unused */
7512 { "Line", 0x2 },
7513 /* Line 2 (0x03) unused */
af901ca1 7514 /* CD (0x04) unused? */
4953550a
TI
7515 },
7516};
7517
b7cccc52
JM
7518static struct hda_input_mux alc889A_imac91_capture_source = {
7519 .num_items = 2,
7520 .items = {
7521 { "Mic", 0x01 },
7522 { "Line", 0x2 }, /* Not sure! */
7523 },
7524};
7525
4953550a
TI
7526/*
7527 * 2ch mode
7528 */
7529static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7530 { 2, NULL }
7531};
7532
272a527c
KY
7533/*
7534 * 2ch mode
7535 */
7536static struct hda_verb alc882_3ST_ch2_init[] = {
7537 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7538 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7539 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7540 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7541 { } /* end */
7542};
7543
4953550a
TI
7544/*
7545 * 4ch mode
7546 */
7547static struct hda_verb alc882_3ST_ch4_init[] = {
7548 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7549 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7550 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7551 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7552 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7553 { } /* end */
7554};
7555
272a527c
KY
7556/*
7557 * 6ch mode
7558 */
7559static struct hda_verb alc882_3ST_ch6_init[] = {
7560 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7561 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7562 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7563 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7564 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7565 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7566 { } /* end */
7567};
7568
4953550a 7569static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7570 { 2, alc882_3ST_ch2_init },
4953550a 7571 { 4, alc882_3ST_ch4_init },
272a527c
KY
7572 { 6, alc882_3ST_ch6_init },
7573};
7574
4953550a
TI
7575#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7576
a65cc60f 7577/*
7578 * 2ch mode
7579 */
7580static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7581 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7582 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7583 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7584 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7585 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7586 { } /* end */
7587};
7588
7589/*
7590 * 4ch mode
7591 */
7592static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7593 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7594 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7595 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7596 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7597 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7598 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7599 { } /* end */
7600};
7601
7602/*
7603 * 6ch mode
7604 */
7605static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7606 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7607 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7608 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7609 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7610 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7611 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7612 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7613 { } /* end */
7614};
7615
7616static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7617 { 2, alc883_3ST_ch2_clevo_init },
7618 { 4, alc883_3ST_ch4_clevo_init },
7619 { 6, alc883_3ST_ch6_clevo_init },
7620};
7621
7622
df694daa
KY
7623/*
7624 * 6ch mode
7625 */
7626static struct hda_verb alc882_sixstack_ch6_init[] = {
7627 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7628 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7629 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7630 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7631 { } /* end */
7632};
7633
7634/*
7635 * 8ch mode
7636 */
7637static struct hda_verb alc882_sixstack_ch8_init[] = {
7638 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7639 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7640 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7641 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7642 { } /* end */
7643};
7644
7645static struct hda_channel_mode alc882_sixstack_modes[2] = {
7646 { 6, alc882_sixstack_ch6_init },
7647 { 8, alc882_sixstack_ch8_init },
7648};
7649
76e6f5a9
RH
7650
7651/* Macbook Air 2,1 */
7652
7653static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7654 { 2, NULL },
7655};
7656
87350ad0 7657/*
def319f9 7658 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7659 */
7660
7661/*
7662 * 2ch mode
7663 */
7664static struct hda_verb alc885_mbp_ch2_init[] = {
7665 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7666 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7667 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7668 { } /* end */
7669};
7670
7671/*
a3f730af 7672 * 4ch mode
87350ad0 7673 */
a3f730af 7674static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7675 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7676 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7677 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7678 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7679 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7680 { } /* end */
7681};
7682
a3f730af 7683static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7684 { 2, alc885_mbp_ch2_init },
a3f730af 7685 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7686};
7687
92b9de83
KS
7688/*
7689 * 2ch
7690 * Speakers/Woofer/HP = Front
7691 * LineIn = Input
7692 */
7693static struct hda_verb alc885_mb5_ch2_init[] = {
7694 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7695 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7696 { } /* end */
7697};
7698
7699/*
7700 * 6ch mode
7701 * Speakers/HP = Front
7702 * Woofer = LFE
7703 * LineIn = Surround
7704 */
7705static struct hda_verb alc885_mb5_ch6_init[] = {
7706 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7707 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7708 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7709 { } /* end */
7710};
7711
7712static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7713 { 2, alc885_mb5_ch2_init },
7714 { 6, alc885_mb5_ch6_init },
7715};
87350ad0 7716
d01aecdf 7717#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7718
7719/*
7720 * 2ch mode
7721 */
7722static struct hda_verb alc883_4ST_ch2_init[] = {
7723 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7724 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7725 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7726 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7727 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7728 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7729 { } /* end */
7730};
7731
7732/*
7733 * 4ch mode
7734 */
7735static struct hda_verb alc883_4ST_ch4_init[] = {
7736 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7737 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7738 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7739 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7740 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7741 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7742 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7743 { } /* end */
7744};
7745
7746/*
7747 * 6ch mode
7748 */
7749static struct hda_verb alc883_4ST_ch6_init[] = {
7750 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7751 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7752 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7753 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7754 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7755 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7756 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7757 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7758 { } /* end */
7759};
7760
7761/*
7762 * 8ch mode
7763 */
7764static struct hda_verb alc883_4ST_ch8_init[] = {
7765 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7766 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7767 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7768 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7769 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7770 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7771 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7772 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7773 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7774 { } /* end */
7775};
7776
7777static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7778 { 2, alc883_4ST_ch2_init },
7779 { 4, alc883_4ST_ch4_init },
7780 { 6, alc883_4ST_ch6_init },
7781 { 8, alc883_4ST_ch8_init },
7782};
7783
7784
7785/*
7786 * 2ch mode
7787 */
7788static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7789 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7790 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7791 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7792 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7793 { } /* end */
7794};
7795
7796/*
7797 * 4ch mode
7798 */
7799static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7800 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7801 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7802 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7803 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7804 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7805 { } /* end */
7806};
7807
7808/*
7809 * 6ch mode
7810 */
7811static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7812 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7813 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7814 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7815 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7816 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7817 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7818 { } /* end */
7819};
7820
7821static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7822 { 2, alc883_3ST_ch2_intel_init },
7823 { 4, alc883_3ST_ch4_intel_init },
7824 { 6, alc883_3ST_ch6_intel_init },
7825};
7826
dd7714c9
WF
7827/*
7828 * 2ch mode
7829 */
7830static struct hda_verb alc889_ch2_intel_init[] = {
7831 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7832 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7833 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7834 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7835 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7836 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7837 { } /* end */
7838};
7839
87a8c370
JK
7840/*
7841 * 6ch mode
7842 */
7843static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7844 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7845 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7846 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7847 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7848 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7849 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7850 { } /* end */
7851};
7852
7853/*
7854 * 8ch mode
7855 */
7856static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7857 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7858 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7859 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7860 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7861 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7862 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7863 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7864 { } /* end */
7865};
7866
dd7714c9
WF
7867static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7868 { 2, alc889_ch2_intel_init },
87a8c370
JK
7869 { 6, alc889_ch6_intel_init },
7870 { 8, alc889_ch8_intel_init },
7871};
7872
4953550a
TI
7873/*
7874 * 6ch mode
7875 */
7876static struct hda_verb alc883_sixstack_ch6_init[] = {
7877 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7878 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7879 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7880 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7881 { } /* end */
7882};
7883
7884/*
7885 * 8ch mode
7886 */
7887static struct hda_verb alc883_sixstack_ch8_init[] = {
7888 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7889 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7890 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7891 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7892 { } /* end */
7893};
7894
7895static struct hda_channel_mode alc883_sixstack_modes[2] = {
7896 { 6, alc883_sixstack_ch6_init },
7897 { 8, alc883_sixstack_ch8_init },
7898};
7899
7900
1da177e4
LT
7901/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7902 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7903 */
c8b6bf9b 7904static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7905 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7906 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7907 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7908 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7909 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7910 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7911 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7912 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7913 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7914 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7915 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7916 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7917 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7920 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 7921 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
7922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7923 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 7924 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 7925 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7926 { } /* end */
7927};
7928
76e6f5a9
RH
7929/* Macbook Air 2,1 same control for HP and internal Speaker */
7930
7931static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7932 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7933 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7934 { }
7935};
7936
7937
87350ad0 7938static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7939 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7940 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7941 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7942 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7943 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7944 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7945 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7946 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7947 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
7948 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
7950 { } /* end */
7951};
41d5545d
KS
7952
7953static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7954 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7955 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7956 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7957 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7958 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7959 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7960 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7961 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7962 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7963 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7964 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7965 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
7966 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7967 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
7968 { } /* end */
7969};
92b9de83 7970
e458b1fa
LY
7971static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7972 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7973 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7974 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7975 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7976 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7977 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7978 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7979 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7980 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7981 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 7982 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
7983 { } /* end */
7984};
7985
4b7e1803 7986static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7987 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7988 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7989 { } /* end */
7990};
7991
7992
bdd148a3
KY
7993static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7994 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7995 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7996 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7997 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8001 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8003 { } /* end */
8004};
8005
272a527c
KY
8006static struct snd_kcontrol_new alc882_targa_mixer[] = {
8007 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8010 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8011 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8012 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8013 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8014 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8015 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8016 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8017 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8018 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8019 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8020 { } /* end */
8021};
8022
8023/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8024 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8025 */
8026static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8027 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8028 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8030 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8031 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8032 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8033 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8034 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8035 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8036 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8039 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8040 { } /* end */
8041};
8042
914759b7
TI
8043static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8044 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8045 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8046 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8047 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8048 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8049 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8050 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8052 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8054 { } /* end */
8055};
8056
df694daa
KY
8057static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8058 {
8059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8060 .name = "Channel Mode",
8061 .info = alc_ch_mode_info,
8062 .get = alc_ch_mode_get,
8063 .put = alc_ch_mode_put,
8064 },
8065 { } /* end */
8066};
8067
4953550a 8068static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8069 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8070 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8071 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8072 /* Rear mixer */
05acb863
TI
8073 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8074 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8075 /* CLFE mixer */
05acb863
TI
8076 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8077 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8078 /* Side mixer */
05acb863
TI
8079 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8080 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8081
e9edcee0 8082 /* Front Pin: output 0 (0x0c) */
05acb863 8083 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8084 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8085 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8086 /* Rear Pin: output 1 (0x0d) */
05acb863 8087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8089 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8090 /* CLFE Pin: output 2 (0x0e) */
05acb863 8091 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8092 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8093 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8094 /* Side Pin: output 3 (0x0f) */
05acb863 8095 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8096 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8097 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8098 /* Mic (rear) pin: input vref at 80% */
16ded525 8099 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8100 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8101 /* Front Mic pin: input vref at 80% */
16ded525 8102 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8103 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8104 /* Line In pin: input */
05acb863 8105 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8106 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8107 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8108 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8109 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8110 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8111 /* CD pin widget for input */
05acb863 8112 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8113
8114 /* FIXME: use matrix-type input source selection */
8115 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8116 /* Input mixer2 */
05acb863 8117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8118 /* Input mixer3 */
05acb863 8119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8120 /* ADC2: mute amp left and right */
8121 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8122 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8123 /* ADC3: mute amp left and right */
8124 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8125 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8126
8127 { }
8128};
8129
4953550a
TI
8130static struct hda_verb alc882_adc1_init_verbs[] = {
8131 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8132 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8133 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8134 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8135 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8136 /* ADC1: mute amp left and right */
8137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8138 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8139 { }
8140};
8141
4b146cb0
TI
8142static struct hda_verb alc882_eapd_verbs[] = {
8143 /* change to EAPD mode */
8144 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8145 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8146 { }
4b146cb0
TI
8147};
8148
87a8c370
JK
8149static struct hda_verb alc889_eapd_verbs[] = {
8150 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8151 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8152 { }
8153};
8154
6732bd0d
WF
8155static struct hda_verb alc_hp15_unsol_verbs[] = {
8156 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8157 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8158 {}
8159};
87a8c370
JK
8160
8161static struct hda_verb alc885_init_verbs[] = {
8162 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8164 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8165 /* Rear mixer */
88102f3f
KY
8166 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8167 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8168 /* CLFE mixer */
88102f3f
KY
8169 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8170 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8171 /* Side mixer */
88102f3f
KY
8172 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8173 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8174
8175 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8177 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8178 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8179 /* Front Pin: output 0 (0x0c) */
8180 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8181 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8182 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8183 /* Rear Pin: output 1 (0x0d) */
8184 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8185 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8186 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8187 /* CLFE Pin: output 2 (0x0e) */
8188 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8189 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8190 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8191 /* Side Pin: output 3 (0x0f) */
8192 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8193 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8194 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8195 /* Mic (rear) pin: input vref at 80% */
8196 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8197 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8198 /* Front Mic pin: input vref at 80% */
8199 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8200 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8201 /* Line In pin: input */
8202 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8203 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8204
8205 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8206 /* Input mixer1 */
88102f3f 8207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8208 /* Input mixer2 */
8209 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8210 /* Input mixer3 */
88102f3f 8211 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8212 /* ADC2: mute amp left and right */
8213 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8214 /* ADC3: mute amp left and right */
8215 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8216
8217 { }
8218};
8219
8220static struct hda_verb alc885_init_input_verbs[] = {
8221 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8222 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8223 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8224 { }
8225};
8226
8227
8228/* Unmute Selector 24h and set the default input to front mic */
8229static struct hda_verb alc889_init_input_verbs[] = {
8230 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8231 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8232 { }
8233};
8234
8235
4953550a
TI
8236#define alc883_init_verbs alc882_base_init_verbs
8237
9102cd1c
TD
8238/* Mac Pro test */
8239static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8241 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8242 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8243 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8244 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8245 /* FIXME: this looks suspicious...
d355c82a
JK
8246 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8247 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8248 */
9102cd1c
TD
8249 { } /* end */
8250};
8251
8252static struct hda_verb alc882_macpro_init_verbs[] = {
8253 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8257 /* Front Pin: output 0 (0x0c) */
8258 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8259 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8260 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8261 /* Front Mic pin: input vref at 80% */
8262 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8263 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8264 /* Speaker: output */
8265 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8266 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8267 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8268 /* Headphone output (output 0 - 0x0c) */
8269 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8270 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8271 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8272
8273 /* FIXME: use matrix-type input source selection */
8274 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8275 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8276 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8277 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8278 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8279 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8280 /* Input mixer2 */
8281 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8282 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8283 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8284 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8285 /* Input mixer3 */
8286 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8288 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8290 /* ADC1: mute amp left and right */
8291 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8292 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8293 /* ADC2: mute amp left and right */
8294 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8295 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8296 /* ADC3: mute amp left and right */
8297 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8298 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8299
8300 { }
8301};
f12ab1e0 8302
41d5545d
KS
8303/* Macbook 5,1 */
8304static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8305 /* DACs */
8306 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8307 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8308 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8309 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8310 /* Front mixer */
41d5545d
KS
8311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8313 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8314 /* Surround mixer */
8315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8316 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8317 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8318 /* LFE mixer */
8319 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8320 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8321 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8322 /* HP mixer */
8323 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8324 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8325 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8326 /* Front Pin (0x0c) */
41d5545d
KS
8327 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8328 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8329 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8330 /* LFE Pin (0x0e) */
8331 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8332 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8333 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8334 /* HP Pin (0x0f) */
41d5545d
KS
8335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8337 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8338 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8339 /* Front Mic pin: input vref at 80% */
8340 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8341 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8342 /* Line In pin */
8343 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8345
b8f171e7
AM
8346 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8348 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8349 { }
8350};
8351
e458b1fa
LY
8352/* Macmini 3,1 */
8353static struct hda_verb alc885_macmini3_init_verbs[] = {
8354 /* DACs */
8355 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8356 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8357 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8358 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8359 /* Front mixer */
8360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8363 /* Surround mixer */
8364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8365 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8366 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8367 /* LFE mixer */
8368 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8369 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8370 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8371 /* HP mixer */
8372 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8373 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8374 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8375 /* Front Pin (0x0c) */
8376 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8377 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8378 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8379 /* LFE Pin (0x0e) */
8380 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8381 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8382 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8383 /* HP Pin (0x0f) */
8384 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8385 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8386 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8387 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8388 /* Line In pin */
8389 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8390 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8391
8392 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8393 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8394 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8395 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8396 { }
8397};
8398
76e6f5a9
RH
8399
8400static struct hda_verb alc885_mba21_init_verbs[] = {
8401 /*Internal and HP Speaker Mixer*/
8402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8404 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8405 /*Internal Speaker Pin (0x0c)*/
8406 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8407 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8408 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8409 /* HP Pin: output 0 (0x0e) */
8410 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8411 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8412 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8413 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8414 /* Line in (is hp when jack connected)*/
8415 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8416 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8417
8418 { }
8419 };
8420
8421
87350ad0
TI
8422/* Macbook Pro rev3 */
8423static struct hda_verb alc885_mbp3_init_verbs[] = {
8424 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8428 /* Rear mixer */
8429 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8431 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8432 /* HP mixer */
8433 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8434 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8435 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8436 /* Front Pin: output 0 (0x0c) */
8437 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8438 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8439 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8440 /* HP Pin: output 0 (0x0e) */
87350ad0 8441 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8442 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8443 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8444 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8445 /* Mic (rear) pin: input vref at 80% */
8446 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8447 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8448 /* Front Mic pin: input vref at 80% */
8449 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8450 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8451 /* Line In pin: use output 1 when in LineOut mode */
8452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8453 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8454 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8455
8456 /* FIXME: use matrix-type input source selection */
8457 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8458 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8459 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8461 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8462 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8463 /* Input mixer2 */
8464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8467 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8468 /* Input mixer3 */
8469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8473 /* ADC1: mute amp left and right */
8474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8475 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8476 /* ADC2: mute amp left and right */
8477 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8478 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8479 /* ADC3: mute amp left and right */
8480 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8481 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8482
8483 { }
8484};
8485
4b7e1803
JM
8486/* iMac 9,1 */
8487static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8488 /* Internal Speaker Pin (0x0c) */
8489 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8490 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8491 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8492 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8493 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8494 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8495 /* HP Pin: Rear */
4b7e1803
JM
8496 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8497 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8498 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8499 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8500 /* Line in Rear */
8501 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8502 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8503 /* Front Mic pin: input vref at 80% */
8504 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8505 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8506 /* Rear mixer */
8507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8508 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8509 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8510 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8514 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8515 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8518 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8519 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8523 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8524 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8529 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8531 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8532 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8533 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8534 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8535 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8536 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8537 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8538 { }
8539};
8540
c54728d8
NF
8541/* iMac 24 mixer. */
8542static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8543 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8544 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8545 { } /* end */
8546};
8547
8548/* iMac 24 init verbs. */
8549static struct hda_verb alc885_imac24_init_verbs[] = {
8550 /* Internal speakers: output 0 (0x0c) */
8551 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8552 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8553 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8554 /* Internal speakers: output 0 (0x0c) */
8555 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8556 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8557 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8558 /* Headphone: output 0 (0x0c) */
8559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8560 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8561 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8562 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8563 /* Front Mic: input vref at 80% */
8564 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8565 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8566 { }
8567};
8568
8569/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8570static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8571{
a9fd4f3f 8572 struct alc_spec *spec = codec->spec;
c54728d8 8573
a9fd4f3f
TI
8574 spec->autocfg.hp_pins[0] = 0x14;
8575 spec->autocfg.speaker_pins[0] = 0x18;
8576 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8577}
8578
9d54f08b
TI
8579#define alc885_mb5_setup alc885_imac24_setup
8580#define alc885_macmini3_setup alc885_imac24_setup
8581
76e6f5a9
RH
8582/* Macbook Air 2,1 */
8583static void alc885_mba21_setup(struct hda_codec *codec)
8584{
8585 struct alc_spec *spec = codec->spec;
8586
8587 spec->autocfg.hp_pins[0] = 0x14;
8588 spec->autocfg.speaker_pins[0] = 0x18;
8589}
8590
8591
8592
4f5d1706 8593static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8594{
a9fd4f3f 8595 struct alc_spec *spec = codec->spec;
87350ad0 8596
a9fd4f3f
TI
8597 spec->autocfg.hp_pins[0] = 0x15;
8598 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8599}
8600
9d54f08b 8601static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8602{
9d54f08b 8603 struct alc_spec *spec = codec->spec;
4b7e1803 8604
9d54f08b 8605 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8606 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8607 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8608}
87350ad0 8609
272a527c
KY
8610static struct hda_verb alc882_targa_verbs[] = {
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8613
8614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8615 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8616
272a527c
KY
8617 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8618 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8619 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8620
8621 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8622 { } /* end */
8623};
8624
8625/* toggle speaker-output according to the hp-jack state */
8626static void alc882_targa_automute(struct hda_codec *codec)
8627{
a9fd4f3f
TI
8628 struct alc_spec *spec = codec->spec;
8629 alc_automute_amp(codec);
82beb8fd 8630 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8631 spec->jack_present ? 1 : 3);
8632}
8633
4f5d1706 8634static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8635{
8636 struct alc_spec *spec = codec->spec;
8637
8638 spec->autocfg.hp_pins[0] = 0x14;
8639 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8640}
8641
8642static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8643{
a9fd4f3f 8644 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8645 alc882_targa_automute(codec);
272a527c
KY
8646}
8647
8648static struct hda_verb alc882_asus_a7j_verbs[] = {
8649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8651
8652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8653 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8654 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8655
272a527c
KY
8656 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8657 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8658 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8659
8660 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8661 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8662 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8663 { } /* end */
8664};
8665
914759b7
TI
8666static struct hda_verb alc882_asus_a7m_verbs[] = {
8667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8668 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8669
8670 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8671 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8672 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8673
914759b7
TI
8674 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8675 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8676 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8677
8678 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8679 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8680 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8681 { } /* end */
8682};
8683
9102cd1c
TD
8684static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8685{
8686 unsigned int gpiostate, gpiomask, gpiodir;
8687
8688 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8689 AC_VERB_GET_GPIO_DATA, 0);
8690
8691 if (!muted)
8692 gpiostate |= (1 << pin);
8693 else
8694 gpiostate &= ~(1 << pin);
8695
8696 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8697 AC_VERB_GET_GPIO_MASK, 0);
8698 gpiomask |= (1 << pin);
8699
8700 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8701 AC_VERB_GET_GPIO_DIRECTION, 0);
8702 gpiodir |= (1 << pin);
8703
8704
8705 snd_hda_codec_write(codec, codec->afg, 0,
8706 AC_VERB_SET_GPIO_MASK, gpiomask);
8707 snd_hda_codec_write(codec, codec->afg, 0,
8708 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8709
8710 msleep(1);
8711
8712 snd_hda_codec_write(codec, codec->afg, 0,
8713 AC_VERB_SET_GPIO_DATA, gpiostate);
8714}
8715
7debbe51
TI
8716/* set up GPIO at initialization */
8717static void alc885_macpro_init_hook(struct hda_codec *codec)
8718{
8719 alc882_gpio_mute(codec, 0, 0);
8720 alc882_gpio_mute(codec, 1, 0);
8721}
8722
8723/* set up GPIO and update auto-muting at initialization */
8724static void alc885_imac24_init_hook(struct hda_codec *codec)
8725{
8726 alc885_macpro_init_hook(codec);
4f5d1706 8727 alc_automute_amp(codec);
7debbe51
TI
8728}
8729
df694daa
KY
8730/*
8731 * generic initialization of ADC, input mixers and output mixers
8732 */
4953550a 8733static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8734 /*
8735 * Unmute ADC0-2 and set the default input to mic-in
8736 */
4953550a
TI
8737 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8738 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8739 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8741
4953550a
TI
8742 /*
8743 * Set up output mixers (0x0c - 0x0f)
8744 */
8745 /* set vol=0 to output mixers */
8746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8750 /* set up input amps for analog loopback */
8751 /* Amp Indices: DAC = 0, mixer = 1 */
8752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8754 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8756 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8757 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8758 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8759 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8760 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8761 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8762
4953550a
TI
8763 /* FIXME: use matrix-type input source selection */
8764 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8765 /* Input mixer2 */
88102f3f 8766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8767 /* Input mixer3 */
88102f3f 8768 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8769 { }
9c7f852e
TI
8770};
8771
eb4c41d3
TS
8772/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8773static struct hda_verb alc889A_mb31_ch2_init[] = {
8774 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8775 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8778 { } /* end */
8779};
8780
8781/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8782static struct hda_verb alc889A_mb31_ch4_init[] = {
8783 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8784 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8785 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8786 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8787 { } /* end */
8788};
8789
8790/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8791static struct hda_verb alc889A_mb31_ch5_init[] = {
8792 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8793 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8794 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8795 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8796 { } /* end */
8797};
8798
8799/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8800static struct hda_verb alc889A_mb31_ch6_init[] = {
8801 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8802 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8803 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8804 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8805 { } /* end */
8806};
8807
8808static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8809 { 2, alc889A_mb31_ch2_init },
8810 { 4, alc889A_mb31_ch4_init },
8811 { 5, alc889A_mb31_ch5_init },
8812 { 6, alc889A_mb31_ch6_init },
8813};
8814
b373bdeb
AN
8815static struct hda_verb alc883_medion_eapd_verbs[] = {
8816 /* eanable EAPD on medion laptop */
8817 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8818 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8819 { }
8820};
8821
4953550a 8822#define alc883_base_mixer alc882_base_mixer
834be88d 8823
a8848bd6
AS
8824static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8825 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8826 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8827 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8828 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8829 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8830 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8831 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8833 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8835 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8836 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8837 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8838 { } /* end */
8839};
8840
0c4cc443 8841static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8842 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8843 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8844 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8845 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8846 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8847 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8848 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8849 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8850 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8851 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8852 { } /* end */
8853};
8854
fb97dc67
J
8855static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8856 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8857 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8858 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8859 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8861 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8863 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8864 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8865 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8866 { } /* end */
8867};
8868
9c7f852e
TI
8869static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8870 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8871 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8872 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8873 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8874 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8875 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8876 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8877 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8878 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8879 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8880 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8881 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8882 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8883 { } /* end */
8884};
df694daa 8885
9c7f852e
TI
8886static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8888 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8889 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8890 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8891 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8892 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8893 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8894 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8895 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8896 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8897 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8898 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8899 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8900 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8901 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8903 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8904 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8905 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8906 { } /* end */
8907};
8908
17bba1b7
J
8909static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8910 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8911 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8912 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8913 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8914 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8915 HDA_OUTPUT),
8916 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8917 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8918 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8919 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8920 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8921 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8922 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8923 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8924 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8925 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
8926 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8927 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8928 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 8929 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8930 { } /* end */
8931};
8932
87a8c370
JK
8933static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8934 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8935 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8936 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8937 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8938 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8939 HDA_OUTPUT),
8940 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8941 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8942 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8943 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8944 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 8949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
8950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8952 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
8953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8954 { } /* end */
8955};
8956
d1d985f0 8957static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8958 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8959 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8960 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8961 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8962 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8963 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8964 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8965 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8966 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8967 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8968 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8972 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
8973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8974 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8975 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 8976 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8977 { } /* end */
8978};
8979
c259249f 8980static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8981 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8982 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8983 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8984 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8985 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8986 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8987 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8991 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8992 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8994 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8996 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 8997 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8998 { } /* end */
f12ab1e0 8999};
ccc656ce 9000
c259249f 9001static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9002 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9003 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9005 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9006 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9007 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9008 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9009 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9010 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9011 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9012 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9013 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9014 { } /* end */
f12ab1e0 9015};
ccc656ce 9016
b99dba34
TI
9017static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9018 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9019 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9020 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9021 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9022 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9023 { } /* end */
9024};
9025
bc9f98a9
KY
9026static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9027 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9028 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9029 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9030 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9032 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9033 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9034 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9035 { } /* end */
f12ab1e0 9036};
bc9f98a9 9037
272a527c
KY
9038static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9039 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9040 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9041 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9042 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9043 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9046 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9047 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
9048 { } /* end */
9049};
9050
7ad7b218
MC
9051static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9052 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9053 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9054 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9055 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9056 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9057 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9058 { } /* end */
9059};
9060
9061static struct hda_verb alc883_medion_wim2160_verbs[] = {
9062 /* Unmute front mixer */
9063 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9064 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9065
9066 /* Set speaker pin to front mixer */
9067 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9068
9069 /* Init headphone pin */
9070 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9071 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9072 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9073 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9074
9075 { } /* end */
9076};
9077
9078/* toggle speaker-output according to the hp-jack state */
9079static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9080{
9081 struct alc_spec *spec = codec->spec;
9082
9083 spec->autocfg.hp_pins[0] = 0x1a;
9084 spec->autocfg.speaker_pins[0] = 0x15;
9085}
9086
2880a867 9087static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9088 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9089 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9090 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9091 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9092 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9094 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9095 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9096 { } /* end */
d1a991a6 9097};
2880a867 9098
d2fd4b09
TV
9099static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9100 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9101 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9102 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9103 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9104 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9105 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9106 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9107 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9108 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9109 { } /* end */
9110};
9111
e2757d5e
KY
9112static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9113 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9114 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9115 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9116 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9117 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9118 0x0d, 1, 0x0, HDA_OUTPUT),
9119 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9120 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9121 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9122 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9123 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9124 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9125 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9126 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9127 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9129 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9131 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9132 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9133 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9134 { } /* end */
9135};
9136
eb4c41d3
TS
9137static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9138 /* Output mixers */
9139 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9140 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9141 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9142 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9143 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9144 HDA_OUTPUT),
9145 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9146 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9147 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9148 /* Output switches */
9149 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9150 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9151 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9152 /* Boost mixers */
5f99f86a
DH
9153 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9154 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9155 /* Input mixers */
9156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9158 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9159 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9160 { } /* end */
9161};
9162
3e1647c5
GG
9163static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9165 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9168 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9169 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9170 { } /* end */
9171};
9172
e2757d5e
KY
9173static struct hda_bind_ctls alc883_bind_cap_vol = {
9174 .ops = &snd_hda_bind_vol,
9175 .values = {
9176 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9177 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9178 0
9179 },
9180};
9181
9182static struct hda_bind_ctls alc883_bind_cap_switch = {
9183 .ops = &snd_hda_bind_sw,
9184 .values = {
9185 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9186 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9187 0
9188 },
9189};
9190
9191static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9195 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9196 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9197 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9198 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9200 { } /* end */
9201};
df694daa 9202
4953550a
TI
9203static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9204 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9205 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9206 {
9207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9208 /* .name = "Capture Source", */
9209 .name = "Input Source",
9210 .count = 1,
9211 .info = alc_mux_enum_info,
9212 .get = alc_mux_enum_get,
9213 .put = alc_mux_enum_put,
9214 },
9215 { } /* end */
9216};
9c7f852e 9217
4953550a
TI
9218static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9219 {
9220 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9221 .name = "Channel Mode",
9222 .info = alc_ch_mode_info,
9223 .get = alc_ch_mode_get,
9224 .put = alc_ch_mode_put,
9225 },
9226 { } /* end */
9c7f852e
TI
9227};
9228
a8848bd6 9229/* toggle speaker-output according to the hp-jack state */
4f5d1706 9230static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9231{
a9fd4f3f 9232 struct alc_spec *spec = codec->spec;
a8848bd6 9233
a9fd4f3f
TI
9234 spec->autocfg.hp_pins[0] = 0x15;
9235 spec->autocfg.speaker_pins[0] = 0x14;
9236 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9237}
9238
a8848bd6
AS
9239static struct hda_verb alc883_mitac_verbs[] = {
9240 /* HP */
9241 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9242 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9243 /* Subwoofer */
9244 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9245 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9246
9247 /* enable unsolicited event */
9248 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9249 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9250
9251 { } /* end */
9252};
9253
a65cc60f 9254static struct hda_verb alc883_clevo_m540r_verbs[] = {
9255 /* HP */
9256 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9258 /* Int speaker */
9259 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9260
9261 /* enable unsolicited event */
9262 /*
9263 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9264 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9265 */
9266
9267 { } /* end */
9268};
9269
0c4cc443 9270static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9271 /* HP */
9272 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9273 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9274 /* Int speaker */
9275 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9276 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9277
9278 /* enable unsolicited event */
9279 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9280 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9281
9282 { } /* end */
9283};
9284
fb97dc67
J
9285static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9286 /* HP */
9287 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9289 /* Subwoofer */
9290 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9292
9293 /* enable unsolicited event */
9294 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9295
9296 { } /* end */
9297};
9298
c259249f 9299static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9302
9303 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9304 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9305
64a8be74
DH
9306/* Connect Line-Out side jack (SPDIF) to Side */
9307 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9308 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9309 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9310/* Connect Mic jack to CLFE */
9311 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9312 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9313 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9314/* Connect Line-in jack to Surround */
9315 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9316 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9317 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9318/* Connect HP out jack to Front */
9319 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9320 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9321 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9322
9323 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9324
9325 { } /* end */
9326};
9327
bc9f98a9
KY
9328static struct hda_verb alc883_lenovo_101e_verbs[] = {
9329 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9330 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9331 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9332 { } /* end */
9333};
9334
272a527c
KY
9335static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9336 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9338 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9340 { } /* end */
9341};
9342
9343static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9344 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9347 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9348 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9349 { } /* end */
9350};
9351
189609ae
KY
9352static struct hda_verb alc883_haier_w66_verbs[] = {
9353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9355
9356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9357
9358 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9359 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9360 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9361 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9362 { } /* end */
9363};
9364
e2757d5e
KY
9365static struct hda_verb alc888_lenovo_sky_verbs[] = {
9366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9368 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9369 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9370 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9371 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9372 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9373 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9374 { } /* end */
9375};
9376
8718b700
HRK
9377static struct hda_verb alc888_6st_dell_verbs[] = {
9378 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9379 { }
9380};
9381
3e1647c5
GG
9382static struct hda_verb alc883_vaiott_verbs[] = {
9383 /* HP */
9384 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9385 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9386
9387 /* enable unsolicited event */
9388 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9389
9390 { } /* end */
9391};
9392
4f5d1706 9393static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9394{
a9fd4f3f 9395 struct alc_spec *spec = codec->spec;
8718b700 9396
a9fd4f3f
TI
9397 spec->autocfg.hp_pins[0] = 0x1b;
9398 spec->autocfg.speaker_pins[0] = 0x14;
9399 spec->autocfg.speaker_pins[1] = 0x16;
9400 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9401}
9402
4723c022 9403static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9404 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9405 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9406 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9407 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9408 { } /* end */
5795b9e6
CM
9409};
9410
3ea0d7cf
HRK
9411/*
9412 * 2ch mode
9413 */
4723c022 9414static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9415 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9416 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9417 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9418 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9419 { } /* end */
8341de60
CM
9420};
9421
3ea0d7cf
HRK
9422/*
9423 * 4ch mode
9424 */
9425static struct hda_verb alc888_3st_hp_4ch_init[] = {
9426 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9427 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9428 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9429 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9430 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9431 { } /* end */
9432};
9433
9434/*
9435 * 6ch mode
9436 */
4723c022 9437static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9438 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9439 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9440 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9441 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9442 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9443 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9444 { } /* end */
8341de60
CM
9445};
9446
3ea0d7cf 9447static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9448 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9449 { 4, alc888_3st_hp_4ch_init },
4723c022 9450 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9451};
9452
272a527c
KY
9453/* toggle front-jack and RCA according to the hp-jack state */
9454static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9455{
864f92be 9456 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9457
47fd830a
TI
9458 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9459 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9460 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9461 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9462}
9463
9464/* toggle RCA according to the front-jack state */
9465static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9466{
864f92be 9467 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9468
47fd830a
TI
9469 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9470 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9471}
47fd830a 9472
272a527c
KY
9473static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9474 unsigned int res)
9475{
9476 if ((res >> 26) == ALC880_HP_EVENT)
9477 alc888_lenovo_ms7195_front_automute(codec);
9478 if ((res >> 26) == ALC880_FRONT_EVENT)
9479 alc888_lenovo_ms7195_rca_automute(codec);
9480}
9481
272a527c 9482/* toggle speaker-output according to the hp-jack state */
dc427170 9483static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9484{
a9fd4f3f 9485 struct alc_spec *spec = codec->spec;
272a527c 9486
a9fd4f3f
TI
9487 spec->autocfg.hp_pins[0] = 0x14;
9488 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9489}
9490
ccc656ce 9491/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9492#define alc883_targa_init_hook alc882_targa_init_hook
9493#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9494
4f5d1706 9495static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9496{
a9fd4f3f
TI
9497 struct alc_spec *spec = codec->spec;
9498
9499 spec->autocfg.hp_pins[0] = 0x15;
9500 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9501}
9502
9503static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9504{
a9fd4f3f 9505 alc_automute_amp(codec);
eeb43387 9506 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9507}
9508
9509static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9510 unsigned int res)
9511{
0c4cc443 9512 switch (res >> 26) {
0c4cc443 9513 case ALC880_MIC_EVENT:
eeb43387 9514 alc88x_simple_mic_automute(codec);
0c4cc443 9515 break;
a9fd4f3f
TI
9516 default:
9517 alc_automute_amp_unsol_event(codec, res);
9518 break;
0c4cc443 9519 }
368c7a95
J
9520}
9521
fb97dc67 9522/* toggle speaker-output according to the hp-jack state */
4f5d1706 9523static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9524{
a9fd4f3f 9525 struct alc_spec *spec = codec->spec;
fb97dc67 9526
a9fd4f3f
TI
9527 spec->autocfg.hp_pins[0] = 0x14;
9528 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9529}
9530
4f5d1706 9531static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9532{
a9fd4f3f 9533 struct alc_spec *spec = codec->spec;
189609ae 9534
a9fd4f3f
TI
9535 spec->autocfg.hp_pins[0] = 0x1b;
9536 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9537}
9538
bc9f98a9
KY
9539static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9540{
864f92be 9541 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9542
47fd830a
TI
9543 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9544 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9545}
9546
9547static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9548{
864f92be 9549 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9550
47fd830a
TI
9551 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9552 HDA_AMP_MUTE, bits);
9553 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9554 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9555}
9556
9557static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9558 unsigned int res)
9559{
9560 if ((res >> 26) == ALC880_HP_EVENT)
9561 alc883_lenovo_101e_all_automute(codec);
9562 if ((res >> 26) == ALC880_FRONT_EVENT)
9563 alc883_lenovo_101e_ispeaker_automute(codec);
9564}
9565
676a9b53 9566/* toggle speaker-output according to the hp-jack state */
4f5d1706 9567static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9568{
a9fd4f3f 9569 struct alc_spec *spec = codec->spec;
676a9b53 9570
a9fd4f3f
TI
9571 spec->autocfg.hp_pins[0] = 0x14;
9572 spec->autocfg.speaker_pins[0] = 0x15;
9573 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9574}
9575
d1a991a6
KY
9576static struct hda_verb alc883_acer_eapd_verbs[] = {
9577 /* HP Pin: output 0 (0x0c) */
9578 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9579 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9580 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9581 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9582 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9583 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9584 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9585 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9586 /* eanable EAPD on medion laptop */
9587 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9588 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9589 /* enable unsolicited event */
9590 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9591 { }
9592};
9593
4f5d1706 9594static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9595{
a9fd4f3f 9596 struct alc_spec *spec = codec->spec;
5795b9e6 9597
a9fd4f3f
TI
9598 spec->autocfg.hp_pins[0] = 0x1b;
9599 spec->autocfg.speaker_pins[0] = 0x14;
9600 spec->autocfg.speaker_pins[1] = 0x15;
9601 spec->autocfg.speaker_pins[2] = 0x16;
9602 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9603}
9604
4f5d1706 9605static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9606{
a9fd4f3f 9607 struct alc_spec *spec = codec->spec;
e2757d5e 9608
a9fd4f3f
TI
9609 spec->autocfg.hp_pins[0] = 0x1b;
9610 spec->autocfg.speaker_pins[0] = 0x14;
9611 spec->autocfg.speaker_pins[1] = 0x15;
9612 spec->autocfg.speaker_pins[2] = 0x16;
9613 spec->autocfg.speaker_pins[3] = 0x17;
9614 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9615}
9616
4f5d1706 9617static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9618{
9619 struct alc_spec *spec = codec->spec;
9620
9621 spec->autocfg.hp_pins[0] = 0x15;
9622 spec->autocfg.speaker_pins[0] = 0x14;
9623 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9624}
9625
e2757d5e
KY
9626static struct hda_verb alc888_asus_m90v_verbs[] = {
9627 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9628 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9629 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9630 /* enable unsolicited event */
9631 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9632 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9633 { } /* end */
9634};
9635
4f5d1706 9636static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9637{
a9fd4f3f 9638 struct alc_spec *spec = codec->spec;
e2757d5e 9639
a9fd4f3f
TI
9640 spec->autocfg.hp_pins[0] = 0x1b;
9641 spec->autocfg.speaker_pins[0] = 0x14;
9642 spec->autocfg.speaker_pins[1] = 0x15;
9643 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9644 spec->ext_mic.pin = 0x18;
9645 spec->int_mic.pin = 0x19;
9646 spec->ext_mic.mux_idx = 0;
9647 spec->int_mic.mux_idx = 1;
9648 spec->auto_mic = 1;
e2757d5e
KY
9649}
9650
9651static struct hda_verb alc888_asus_eee1601_verbs[] = {
9652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9653 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9654 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9656 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9657 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9658 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9659 /* enable unsolicited event */
9660 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9661 { } /* end */
9662};
9663
e2757d5e
KY
9664static void alc883_eee1601_inithook(struct hda_codec *codec)
9665{
a9fd4f3f
TI
9666 struct alc_spec *spec = codec->spec;
9667
9668 spec->autocfg.hp_pins[0] = 0x14;
9669 spec->autocfg.speaker_pins[0] = 0x1b;
9670 alc_automute_pin(codec);
e2757d5e
KY
9671}
9672
eb4c41d3
TS
9673static struct hda_verb alc889A_mb31_verbs[] = {
9674 /* Init rear pin (used as headphone output) */
9675 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9676 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9677 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9678 /* Init line pin (used as output in 4ch and 6ch mode) */
9679 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9680 /* Init line 2 pin (used as headphone out by default) */
9681 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9682 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9683 { } /* end */
9684};
9685
9686/* Mute speakers according to the headphone jack state */
9687static void alc889A_mb31_automute(struct hda_codec *codec)
9688{
9689 unsigned int present;
9690
9691 /* Mute only in 2ch or 4ch mode */
9692 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9693 == 0x00) {
864f92be 9694 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9695 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9696 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9697 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9698 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9699 }
9700}
9701
9702static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9703{
9704 if ((res >> 26) == ALC880_HP_EVENT)
9705 alc889A_mb31_automute(codec);
9706}
9707
4953550a 9708
cb53c626 9709#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9710#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9711#endif
9712
def319f9 9713/* pcm configuration: identical with ALC880 */
4953550a
TI
9714#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9715#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9716#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9717#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9718
9719static hda_nid_t alc883_slave_dig_outs[] = {
9720 ALC1200_DIGOUT_NID, 0,
9721};
9722
9723static hda_nid_t alc1200_slave_dig_outs[] = {
9724 ALC883_DIGOUT_NID, 0,
9725};
9c7f852e
TI
9726
9727/*
9728 * configuration and preset
9729 */
4953550a
TI
9730static const char *alc882_models[ALC882_MODEL_LAST] = {
9731 [ALC882_3ST_DIG] = "3stack-dig",
9732 [ALC882_6ST_DIG] = "6stack-dig",
9733 [ALC882_ARIMA] = "arima",
9734 [ALC882_W2JC] = "w2jc",
9735 [ALC882_TARGA] = "targa",
9736 [ALC882_ASUS_A7J] = "asus-a7j",
9737 [ALC882_ASUS_A7M] = "asus-a7m",
9738 [ALC885_MACPRO] = "macpro",
9739 [ALC885_MB5] = "mb5",
e458b1fa 9740 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9741 [ALC885_MBA21] = "mba21",
4953550a
TI
9742 [ALC885_MBP3] = "mbp3",
9743 [ALC885_IMAC24] = "imac24",
4b7e1803 9744 [ALC885_IMAC91] = "imac91",
4953550a 9745 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9746 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9747 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9748 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9749 [ALC883_TARGA_DIG] = "targa-dig",
9750 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9751 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9752 [ALC883_ACER] = "acer",
2880a867 9753 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9754 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9755 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9756 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9757 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9758 [ALC883_MEDION] = "medion",
7ad7b218 9759 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9760 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9761 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9762 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9763 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9764 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9765 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9766 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9767 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9768 [ALC883_MITAC] = "mitac",
a65cc60f 9769 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9770 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9771 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9772 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9773 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9774 [ALC889A_INTEL] = "intel-alc889a",
9775 [ALC889_INTEL] = "intel-x58",
3ab90935 9776 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9777 [ALC889A_MB31] = "mb31",
3e1647c5 9778 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9779 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9780};
9781
4953550a
TI
9782static struct snd_pci_quirk alc882_cfg_tbl[] = {
9783 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9784
ac3e3741 9785 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9786 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9787 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9788 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9789 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9790 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9791 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9792 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9793 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9794 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9795 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9796 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9797 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9798 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9799 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9800 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9801 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9802 ALC888_ACER_ASPIRE_6530G),
cc374c47 9803 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9804 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9805 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9806 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9807 /* default Acer -- disabled as it causes more problems.
9808 * model=auto should work fine now
9809 */
9810 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9811
5795b9e6 9812 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9813
febe3375 9814 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9815 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9816 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9817 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9818 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9819 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9820
9821 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9822 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9823 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9824 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9825 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9826 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9827 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9828 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9829 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9830 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9831 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9832
9833 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9834 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9835 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9836 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9837 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9838 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9839 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9840 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9841 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9842
6f3bf657 9843 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9844 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9845 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9846 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9847 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9848 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9849 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9850 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9851 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9852 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9853 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9854 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9855 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9856 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9857 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9858 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9859 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9860 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9861 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9862 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9863 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9864 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9865 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9866 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9867 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9868 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9869 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9870 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9871 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9872 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9873 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9874
ac3e3741 9875 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9876 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9877 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9878 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9879 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9880 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9881 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9882 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9883 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9884 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9885 ALC883_FUJITSU_PI2515),
bfb53037 9886 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9887 ALC888_FUJITSU_XA3530),
272a527c 9888 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9889 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9890 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9891 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9892 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9893 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9894 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9895 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9896
17bba1b7
J
9897 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9898 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9899 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9900 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9901 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9902 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9903 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9904
4953550a 9905 {}
f3cd3f5d
WF
9906};
9907
4953550a
TI
9908/* codec SSID table for Intel Mac */
9909static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9910 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9911 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9912 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9913 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9914 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9915 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9916 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9917 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9918 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9919 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9920 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9921 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9922 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9923 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9924 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9925 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9926 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9927 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9928 * so apparently no perfect solution yet
4953550a
TI
9929 */
9930 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9931 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9932 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9933 {} /* terminator */
b25c9da1
WF
9934};
9935
4953550a
TI
9936static struct alc_config_preset alc882_presets[] = {
9937 [ALC882_3ST_DIG] = {
9938 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9939 .init_verbs = { alc882_base_init_verbs,
9940 alc882_adc1_init_verbs },
4953550a
TI
9941 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9942 .dac_nids = alc882_dac_nids,
9943 .dig_out_nid = ALC882_DIGOUT_NID,
9944 .dig_in_nid = ALC882_DIGIN_NID,
9945 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9946 .channel_mode = alc882_ch_modes,
9947 .need_dac_fix = 1,
9948 .input_mux = &alc882_capture_source,
9949 },
9950 [ALC882_6ST_DIG] = {
9951 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9952 .init_verbs = { alc882_base_init_verbs,
9953 alc882_adc1_init_verbs },
4953550a
TI
9954 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9955 .dac_nids = alc882_dac_nids,
9956 .dig_out_nid = ALC882_DIGOUT_NID,
9957 .dig_in_nid = ALC882_DIGIN_NID,
9958 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9959 .channel_mode = alc882_sixstack_modes,
9960 .input_mux = &alc882_capture_source,
9961 },
9962 [ALC882_ARIMA] = {
9963 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9964 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9965 alc882_eapd_verbs },
4953550a
TI
9966 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9967 .dac_nids = alc882_dac_nids,
9968 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9969 .channel_mode = alc882_sixstack_modes,
9970 .input_mux = &alc882_capture_source,
9971 },
9972 [ALC882_W2JC] = {
9973 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9974 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9975 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9976 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9977 .dac_nids = alc882_dac_nids,
9978 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9979 .channel_mode = alc880_threestack_modes,
9980 .need_dac_fix = 1,
9981 .input_mux = &alc882_capture_source,
9982 .dig_out_nid = ALC882_DIGOUT_NID,
9983 },
76e6f5a9
RH
9984 [ALC885_MBA21] = {
9985 .mixers = { alc885_mba21_mixer },
9986 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9987 .num_dacs = 2,
9988 .dac_nids = alc882_dac_nids,
9989 .channel_mode = alc885_mba21_ch_modes,
9990 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9991 .input_mux = &alc882_capture_source,
9992 .unsol_event = alc_automute_amp_unsol_event,
9993 .setup = alc885_mba21_setup,
9994 .init_hook = alc_automute_amp,
9995 },
4953550a
TI
9996 [ALC885_MBP3] = {
9997 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9998 .init_verbs = { alc885_mbp3_init_verbs,
9999 alc880_gpio1_init_verbs },
be0ae923 10000 .num_dacs = 2,
4953550a 10001 .dac_nids = alc882_dac_nids,
be0ae923
TI
10002 .hp_nid = 0x04,
10003 .channel_mode = alc885_mbp_4ch_modes,
10004 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10005 .input_mux = &alc882_capture_source,
10006 .dig_out_nid = ALC882_DIGOUT_NID,
10007 .dig_in_nid = ALC882_DIGIN_NID,
10008 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10009 .setup = alc885_mbp3_setup,
10010 .init_hook = alc_automute_amp,
4953550a
TI
10011 },
10012 [ALC885_MB5] = {
10013 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10014 .init_verbs = { alc885_mb5_init_verbs,
10015 alc880_gpio1_init_verbs },
10016 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10017 .dac_nids = alc882_dac_nids,
10018 .channel_mode = alc885_mb5_6ch_modes,
10019 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10020 .input_mux = &mb5_capture_source,
10021 .dig_out_nid = ALC882_DIGOUT_NID,
10022 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10023 .unsol_event = alc_automute_amp_unsol_event,
10024 .setup = alc885_mb5_setup,
10025 .init_hook = alc_automute_amp,
4953550a 10026 },
e458b1fa
LY
10027 [ALC885_MACMINI3] = {
10028 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10029 .init_verbs = { alc885_macmini3_init_verbs,
10030 alc880_gpio1_init_verbs },
10031 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10032 .dac_nids = alc882_dac_nids,
10033 .channel_mode = alc885_macmini3_6ch_modes,
10034 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10035 .input_mux = &macmini3_capture_source,
10036 .dig_out_nid = ALC882_DIGOUT_NID,
10037 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10038 .unsol_event = alc_automute_amp_unsol_event,
10039 .setup = alc885_macmini3_setup,
10040 .init_hook = alc_automute_amp,
e458b1fa 10041 },
4953550a
TI
10042 [ALC885_MACPRO] = {
10043 .mixers = { alc882_macpro_mixer },
10044 .init_verbs = { alc882_macpro_init_verbs },
10045 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10046 .dac_nids = alc882_dac_nids,
10047 .dig_out_nid = ALC882_DIGOUT_NID,
10048 .dig_in_nid = ALC882_DIGIN_NID,
10049 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10050 .channel_mode = alc882_ch_modes,
10051 .input_mux = &alc882_capture_source,
10052 .init_hook = alc885_macpro_init_hook,
10053 },
10054 [ALC885_IMAC24] = {
10055 .mixers = { alc885_imac24_mixer },
10056 .init_verbs = { alc885_imac24_init_verbs },
10057 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10058 .dac_nids = alc882_dac_nids,
10059 .dig_out_nid = ALC882_DIGOUT_NID,
10060 .dig_in_nid = ALC882_DIGIN_NID,
10061 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10062 .channel_mode = alc882_ch_modes,
10063 .input_mux = &alc882_capture_source,
10064 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 10065 .setup = alc885_imac24_setup,
4953550a
TI
10066 .init_hook = alc885_imac24_init_hook,
10067 },
4b7e1803 10068 [ALC885_IMAC91] = {
b7cccc52 10069 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10070 .init_verbs = { alc885_imac91_init_verbs,
10071 alc880_gpio1_init_verbs },
10072 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10073 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10074 .channel_mode = alc885_mba21_ch_modes,
10075 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10076 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10077 .dig_out_nid = ALC882_DIGOUT_NID,
10078 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10079 .unsol_event = alc_automute_amp_unsol_event,
10080 .setup = alc885_imac91_setup,
10081 .init_hook = alc_automute_amp,
4b7e1803 10082 },
4953550a
TI
10083 [ALC882_TARGA] = {
10084 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10085 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10086 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10087 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10088 .dac_nids = alc882_dac_nids,
10089 .dig_out_nid = ALC882_DIGOUT_NID,
10090 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10091 .adc_nids = alc882_adc_nids,
10092 .capsrc_nids = alc882_capsrc_nids,
10093 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10094 .channel_mode = alc882_3ST_6ch_modes,
10095 .need_dac_fix = 1,
10096 .input_mux = &alc882_capture_source,
10097 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10098 .setup = alc882_targa_setup,
10099 .init_hook = alc882_targa_automute,
4953550a
TI
10100 },
10101 [ALC882_ASUS_A7J] = {
10102 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10103 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10104 alc882_asus_a7j_verbs},
4953550a
TI
10105 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10106 .dac_nids = alc882_dac_nids,
10107 .dig_out_nid = ALC882_DIGOUT_NID,
10108 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10109 .adc_nids = alc882_adc_nids,
10110 .capsrc_nids = alc882_capsrc_nids,
10111 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10112 .channel_mode = alc882_3ST_6ch_modes,
10113 .need_dac_fix = 1,
10114 .input_mux = &alc882_capture_source,
10115 },
10116 [ALC882_ASUS_A7M] = {
10117 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10118 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10119 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10120 alc882_asus_a7m_verbs },
10121 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10122 .dac_nids = alc882_dac_nids,
10123 .dig_out_nid = ALC882_DIGOUT_NID,
10124 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10125 .channel_mode = alc880_threestack_modes,
10126 .need_dac_fix = 1,
10127 .input_mux = &alc882_capture_source,
10128 },
9c7f852e
TI
10129 [ALC883_3ST_2ch_DIG] = {
10130 .mixers = { alc883_3ST_2ch_mixer },
10131 .init_verbs = { alc883_init_verbs },
10132 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10133 .dac_nids = alc883_dac_nids,
10134 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10135 .dig_in_nid = ALC883_DIGIN_NID,
10136 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10137 .channel_mode = alc883_3ST_2ch_modes,
10138 .input_mux = &alc883_capture_source,
10139 },
10140 [ALC883_3ST_6ch_DIG] = {
10141 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10142 .init_verbs = { alc883_init_verbs },
10143 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10144 .dac_nids = alc883_dac_nids,
10145 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10146 .dig_in_nid = ALC883_DIGIN_NID,
10147 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10148 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10149 .need_dac_fix = 1,
9c7f852e 10150 .input_mux = &alc883_capture_source,
f12ab1e0 10151 },
9c7f852e
TI
10152 [ALC883_3ST_6ch] = {
10153 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10154 .init_verbs = { alc883_init_verbs },
10155 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10156 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10157 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10158 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10159 .need_dac_fix = 1,
9c7f852e 10160 .input_mux = &alc883_capture_source,
f12ab1e0 10161 },
17bba1b7
J
10162 [ALC883_3ST_6ch_INTEL] = {
10163 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10164 .init_verbs = { alc883_init_verbs },
10165 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10166 .dac_nids = alc883_dac_nids,
10167 .dig_out_nid = ALC883_DIGOUT_NID,
10168 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10169 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10170 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10171 .channel_mode = alc883_3ST_6ch_intel_modes,
10172 .need_dac_fix = 1,
10173 .input_mux = &alc883_3stack_6ch_intel,
10174 },
87a8c370
JK
10175 [ALC889A_INTEL] = {
10176 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10177 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10178 alc_hp15_unsol_verbs },
87a8c370
JK
10179 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10180 .dac_nids = alc883_dac_nids,
10181 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10182 .adc_nids = alc889_adc_nids,
10183 .dig_out_nid = ALC883_DIGOUT_NID,
10184 .dig_in_nid = ALC883_DIGIN_NID,
10185 .slave_dig_outs = alc883_slave_dig_outs,
10186 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10187 .channel_mode = alc889_8ch_intel_modes,
10188 .capsrc_nids = alc889_capsrc_nids,
10189 .input_mux = &alc889_capture_source,
4f5d1706
TI
10190 .setup = alc889_automute_setup,
10191 .init_hook = alc_automute_amp,
6732bd0d 10192 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10193 .need_dac_fix = 1,
10194 },
10195 [ALC889_INTEL] = {
10196 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10197 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10198 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10199 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10200 .dac_nids = alc883_dac_nids,
10201 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10202 .adc_nids = alc889_adc_nids,
10203 .dig_out_nid = ALC883_DIGOUT_NID,
10204 .dig_in_nid = ALC883_DIGIN_NID,
10205 .slave_dig_outs = alc883_slave_dig_outs,
10206 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10207 .channel_mode = alc889_8ch_intel_modes,
10208 .capsrc_nids = alc889_capsrc_nids,
10209 .input_mux = &alc889_capture_source,
4f5d1706 10210 .setup = alc889_automute_setup,
6732bd0d
WF
10211 .init_hook = alc889_intel_init_hook,
10212 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10213 .need_dac_fix = 1,
10214 },
9c7f852e
TI
10215 [ALC883_6ST_DIG] = {
10216 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10217 .init_verbs = { alc883_init_verbs },
10218 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10219 .dac_nids = alc883_dac_nids,
10220 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10221 .dig_in_nid = ALC883_DIGIN_NID,
10222 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10223 .channel_mode = alc883_sixstack_modes,
10224 .input_mux = &alc883_capture_source,
10225 },
ccc656ce 10226 [ALC883_TARGA_DIG] = {
c259249f 10227 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10228 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10229 alc883_targa_verbs},
ccc656ce
KY
10230 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10231 .dac_nids = alc883_dac_nids,
10232 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10233 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10234 .channel_mode = alc883_3ST_6ch_modes,
10235 .need_dac_fix = 1,
10236 .input_mux = &alc883_capture_source,
c259249f 10237 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10238 .setup = alc882_targa_setup,
10239 .init_hook = alc882_targa_automute,
ccc656ce
KY
10240 },
10241 [ALC883_TARGA_2ch_DIG] = {
c259249f 10242 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10243 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10244 alc883_targa_verbs},
ccc656ce
KY
10245 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10246 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10247 .adc_nids = alc883_adc_nids_alt,
10248 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10249 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10250 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10251 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10252 .channel_mode = alc883_3ST_2ch_modes,
10253 .input_mux = &alc883_capture_source,
c259249f 10254 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10255 .setup = alc882_targa_setup,
10256 .init_hook = alc882_targa_automute,
ccc656ce 10257 },
64a8be74 10258 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10259 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10260 alc883_chmode_mixer },
64a8be74 10261 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10262 alc883_targa_verbs },
64a8be74
DH
10263 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10264 .dac_nids = alc883_dac_nids,
10265 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10266 .adc_nids = alc883_adc_nids_rev,
10267 .capsrc_nids = alc883_capsrc_nids_rev,
10268 .dig_out_nid = ALC883_DIGOUT_NID,
10269 .dig_in_nid = ALC883_DIGIN_NID,
10270 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10271 .channel_mode = alc883_4ST_8ch_modes,
10272 .need_dac_fix = 1,
10273 .input_mux = &alc883_capture_source,
c259249f 10274 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10275 .setup = alc882_targa_setup,
10276 .init_hook = alc882_targa_automute,
64a8be74 10277 },
bab282b9 10278 [ALC883_ACER] = {
676a9b53 10279 .mixers = { alc883_base_mixer },
bab282b9
VA
10280 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10281 * and the headphone jack. Turn this on and rely on the
10282 * standard mute methods whenever the user wants to turn
10283 * these outputs off.
10284 */
10285 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10286 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10287 .dac_nids = alc883_dac_nids,
bab282b9
VA
10288 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10289 .channel_mode = alc883_3ST_2ch_modes,
10290 .input_mux = &alc883_capture_source,
10291 },
2880a867 10292 [ALC883_ACER_ASPIRE] = {
676a9b53 10293 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10294 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10295 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10296 .dac_nids = alc883_dac_nids,
10297 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10298 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10299 .channel_mode = alc883_3ST_2ch_modes,
10300 .input_mux = &alc883_capture_source,
a9fd4f3f 10301 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10302 .setup = alc883_acer_aspire_setup,
10303 .init_hook = alc_automute_amp,
d1a991a6 10304 },
5b2d1eca 10305 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10306 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10307 alc883_chmode_mixer },
10308 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10309 alc888_acer_aspire_4930g_verbs },
10310 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10311 .dac_nids = alc883_dac_nids,
10312 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10313 .adc_nids = alc883_adc_nids_rev,
10314 .capsrc_nids = alc883_capsrc_nids_rev,
10315 .dig_out_nid = ALC883_DIGOUT_NID,
10316 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10317 .channel_mode = alc883_3ST_6ch_modes,
10318 .need_dac_fix = 1,
973b8cb0 10319 .const_channel_count = 6,
5b2d1eca 10320 .num_mux_defs =
ef8ef5fb
VP
10321 ARRAY_SIZE(alc888_2_capture_sources),
10322 .input_mux = alc888_2_capture_sources,
d2fd4b09 10323 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10324 .setup = alc888_acer_aspire_4930g_setup,
10325 .init_hook = alc_automute_amp,
d2fd4b09
TV
10326 },
10327 [ALC888_ACER_ASPIRE_6530G] = {
10328 .mixers = { alc888_acer_aspire_6530_mixer },
10329 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10330 alc888_acer_aspire_6530g_verbs },
10331 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10332 .dac_nids = alc883_dac_nids,
10333 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10334 .adc_nids = alc883_adc_nids_rev,
10335 .capsrc_nids = alc883_capsrc_nids_rev,
10336 .dig_out_nid = ALC883_DIGOUT_NID,
10337 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10338 .channel_mode = alc883_3ST_2ch_modes,
10339 .num_mux_defs =
10340 ARRAY_SIZE(alc888_2_capture_sources),
10341 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10342 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10343 .setup = alc888_acer_aspire_6530g_setup,
10344 .init_hook = alc_automute_amp,
5b2d1eca 10345 },
3b315d70 10346 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10347 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10348 alc883_chmode_mixer },
10349 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10350 alc889_acer_aspire_8930g_verbs,
10351 alc889_eapd_verbs},
3b315d70
HM
10352 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10353 .dac_nids = alc883_dac_nids,
018df418
HM
10354 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10355 .adc_nids = alc889_adc_nids,
10356 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10357 .dig_out_nid = ALC883_DIGOUT_NID,
10358 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10359 .channel_mode = alc883_3ST_6ch_modes,
10360 .need_dac_fix = 1,
10361 .const_channel_count = 6,
10362 .num_mux_defs =
018df418
HM
10363 ARRAY_SIZE(alc889_capture_sources),
10364 .input_mux = alc889_capture_sources,
3b315d70 10365 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10366 .setup = alc889_acer_aspire_8930g_setup,
10367 .init_hook = alc_automute_amp,
f5de24b0 10368#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10369 .power_hook = alc_power_eapd,
f5de24b0 10370#endif
3b315d70 10371 },
fc86f954
DK
10372 [ALC888_ACER_ASPIRE_7730G] = {
10373 .mixers = { alc883_3ST_6ch_mixer,
10374 alc883_chmode_mixer },
10375 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10376 alc888_acer_aspire_7730G_verbs },
10377 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10378 .dac_nids = alc883_dac_nids,
10379 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10380 .adc_nids = alc883_adc_nids_rev,
10381 .capsrc_nids = alc883_capsrc_nids_rev,
10382 .dig_out_nid = ALC883_DIGOUT_NID,
10383 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10384 .channel_mode = alc883_3ST_6ch_modes,
10385 .need_dac_fix = 1,
10386 .const_channel_count = 6,
10387 .input_mux = &alc883_capture_source,
10388 .unsol_event = alc_automute_amp_unsol_event,
d9477207 10389 .setup = alc888_acer_aspire_7730g_setup,
fc86f954
DK
10390 .init_hook = alc_automute_amp,
10391 },
c07584c8
TD
10392 [ALC883_MEDION] = {
10393 .mixers = { alc883_fivestack_mixer,
10394 alc883_chmode_mixer },
10395 .init_verbs = { alc883_init_verbs,
b373bdeb 10396 alc883_medion_eapd_verbs },
c07584c8
TD
10397 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10398 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10399 .adc_nids = alc883_adc_nids_alt,
10400 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10401 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10402 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10403 .channel_mode = alc883_sixstack_modes,
10404 .input_mux = &alc883_capture_source,
b373bdeb 10405 },
7ad7b218
MC
10406 [ALC883_MEDION_WIM2160] = {
10407 .mixers = { alc883_medion_wim2160_mixer },
10408 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10409 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10410 .dac_nids = alc883_dac_nids,
10411 .dig_out_nid = ALC883_DIGOUT_NID,
10412 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10413 .adc_nids = alc883_adc_nids,
10414 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10415 .channel_mode = alc883_3ST_2ch_modes,
10416 .input_mux = &alc883_capture_source,
10417 .unsol_event = alc_automute_amp_unsol_event,
10418 .setup = alc883_medion_wim2160_setup,
10419 .init_hook = alc_automute_amp,
10420 },
b373bdeb 10421 [ALC883_LAPTOP_EAPD] = {
676a9b53 10422 .mixers = { alc883_base_mixer },
b373bdeb
AN
10423 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10424 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10425 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10426 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10427 .channel_mode = alc883_3ST_2ch_modes,
10428 .input_mux = &alc883_capture_source,
10429 },
a65cc60f 10430 [ALC883_CLEVO_M540R] = {
10431 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10432 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10433 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10434 .dac_nids = alc883_dac_nids,
10435 .dig_out_nid = ALC883_DIGOUT_NID,
10436 .dig_in_nid = ALC883_DIGIN_NID,
10437 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10438 .channel_mode = alc883_3ST_6ch_clevo_modes,
10439 .need_dac_fix = 1,
10440 .input_mux = &alc883_capture_source,
10441 /* This machine has the hardware HP auto-muting, thus
10442 * we need no software mute via unsol event
10443 */
10444 },
0c4cc443
HRK
10445 [ALC883_CLEVO_M720] = {
10446 .mixers = { alc883_clevo_m720_mixer },
10447 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10448 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10449 .dac_nids = alc883_dac_nids,
10450 .dig_out_nid = ALC883_DIGOUT_NID,
10451 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10452 .channel_mode = alc883_3ST_2ch_modes,
10453 .input_mux = &alc883_capture_source,
0c4cc443 10454 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10455 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10456 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10457 },
bc9f98a9
KY
10458 [ALC883_LENOVO_101E_2ch] = {
10459 .mixers = { alc883_lenovo_101e_2ch_mixer},
10460 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10461 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10462 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10463 .adc_nids = alc883_adc_nids_alt,
10464 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10465 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10466 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10467 .channel_mode = alc883_3ST_2ch_modes,
10468 .input_mux = &alc883_lenovo_101e_capture_source,
10469 .unsol_event = alc883_lenovo_101e_unsol_event,
10470 .init_hook = alc883_lenovo_101e_all_automute,
10471 },
272a527c
KY
10472 [ALC883_LENOVO_NB0763] = {
10473 .mixers = { alc883_lenovo_nb0763_mixer },
10474 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10475 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10476 .dac_nids = alc883_dac_nids,
272a527c
KY
10477 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10478 .channel_mode = alc883_3ST_2ch_modes,
10479 .need_dac_fix = 1,
10480 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10481 .unsol_event = alc_automute_amp_unsol_event,
dc427170 10482 .setup = alc883_lenovo_nb0763_setup,
4f5d1706 10483 .init_hook = alc_automute_amp,
272a527c
KY
10484 },
10485 [ALC888_LENOVO_MS7195_DIG] = {
10486 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10487 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10488 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10489 .dac_nids = alc883_dac_nids,
10490 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10491 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10492 .channel_mode = alc883_3ST_6ch_modes,
10493 .need_dac_fix = 1,
10494 .input_mux = &alc883_capture_source,
10495 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10496 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10497 },
10498 [ALC883_HAIER_W66] = {
c259249f 10499 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10500 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10501 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10502 .dac_nids = alc883_dac_nids,
10503 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10504 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10505 .channel_mode = alc883_3ST_2ch_modes,
10506 .input_mux = &alc883_capture_source,
a9fd4f3f 10507 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10508 .setup = alc883_haier_w66_setup,
10509 .init_hook = alc_automute_amp,
eea6419e 10510 },
4723c022 10511 [ALC888_3ST_HP] = {
eea6419e 10512 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10513 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10514 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10515 .dac_nids = alc883_dac_nids,
4723c022
CM
10516 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10517 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10518 .need_dac_fix = 1,
10519 .input_mux = &alc883_capture_source,
a9fd4f3f 10520 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10521 .setup = alc888_3st_hp_setup,
10522 .init_hook = alc_automute_amp,
8341de60 10523 },
5795b9e6 10524 [ALC888_6ST_DELL] = {
f24dbdc6 10525 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10526 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10527 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10528 .dac_nids = alc883_dac_nids,
10529 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10530 .dig_in_nid = ALC883_DIGIN_NID,
10531 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10532 .channel_mode = alc883_sixstack_modes,
10533 .input_mux = &alc883_capture_source,
a9fd4f3f 10534 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10535 .setup = alc888_6st_dell_setup,
10536 .init_hook = alc_automute_amp,
5795b9e6 10537 },
a8848bd6
AS
10538 [ALC883_MITAC] = {
10539 .mixers = { alc883_mitac_mixer },
10540 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10541 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10542 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10543 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10544 .channel_mode = alc883_3ST_2ch_modes,
10545 .input_mux = &alc883_capture_source,
a9fd4f3f 10546 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10547 .setup = alc883_mitac_setup,
10548 .init_hook = alc_automute_amp,
a8848bd6 10549 },
fb97dc67
J
10550 [ALC883_FUJITSU_PI2515] = {
10551 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10552 .init_verbs = { alc883_init_verbs,
10553 alc883_2ch_fujitsu_pi2515_verbs},
10554 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10555 .dac_nids = alc883_dac_nids,
10556 .dig_out_nid = ALC883_DIGOUT_NID,
10557 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10558 .channel_mode = alc883_3ST_2ch_modes,
10559 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10560 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10561 .setup = alc883_2ch_fujitsu_pi2515_setup,
10562 .init_hook = alc_automute_amp,
fb97dc67 10563 },
ef8ef5fb
VP
10564 [ALC888_FUJITSU_XA3530] = {
10565 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10566 .init_verbs = { alc883_init_verbs,
10567 alc888_fujitsu_xa3530_verbs },
10568 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10569 .dac_nids = alc883_dac_nids,
10570 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10571 .adc_nids = alc883_adc_nids_rev,
10572 .capsrc_nids = alc883_capsrc_nids_rev,
10573 .dig_out_nid = ALC883_DIGOUT_NID,
10574 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10575 .channel_mode = alc888_4ST_8ch_intel_modes,
10576 .num_mux_defs =
10577 ARRAY_SIZE(alc888_2_capture_sources),
10578 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10579 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10580 .setup = alc888_fujitsu_xa3530_setup,
10581 .init_hook = alc_automute_amp,
ef8ef5fb 10582 },
e2757d5e
KY
10583 [ALC888_LENOVO_SKY] = {
10584 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10585 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10586 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10587 .dac_nids = alc883_dac_nids,
10588 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10589 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10590 .channel_mode = alc883_sixstack_modes,
10591 .need_dac_fix = 1,
10592 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10593 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10594 .setup = alc888_lenovo_sky_setup,
10595 .init_hook = alc_automute_amp,
e2757d5e
KY
10596 },
10597 [ALC888_ASUS_M90V] = {
10598 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10599 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10600 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10601 .dac_nids = alc883_dac_nids,
10602 .dig_out_nid = ALC883_DIGOUT_NID,
10603 .dig_in_nid = ALC883_DIGIN_NID,
10604 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10605 .channel_mode = alc883_3ST_6ch_modes,
10606 .need_dac_fix = 1,
10607 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10608 .unsol_event = alc_sku_unsol_event,
10609 .setup = alc883_mode2_setup,
10610 .init_hook = alc_inithook,
e2757d5e
KY
10611 },
10612 [ALC888_ASUS_EEE1601] = {
10613 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10614 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10615 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10616 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10617 .dac_nids = alc883_dac_nids,
10618 .dig_out_nid = ALC883_DIGOUT_NID,
10619 .dig_in_nid = ALC883_DIGIN_NID,
10620 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10621 .channel_mode = alc883_3ST_2ch_modes,
10622 .need_dac_fix = 1,
10623 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10624 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10625 .init_hook = alc883_eee1601_inithook,
10626 },
3ab90935
WF
10627 [ALC1200_ASUS_P5Q] = {
10628 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10629 .init_verbs = { alc883_init_verbs },
10630 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10631 .dac_nids = alc883_dac_nids,
10632 .dig_out_nid = ALC1200_DIGOUT_NID,
10633 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10634 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10635 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10636 .channel_mode = alc883_sixstack_modes,
10637 .input_mux = &alc883_capture_source,
10638 },
eb4c41d3
TS
10639 [ALC889A_MB31] = {
10640 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10641 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10642 alc880_gpio1_init_verbs },
10643 .adc_nids = alc883_adc_nids,
10644 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10645 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10646 .dac_nids = alc883_dac_nids,
10647 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10648 .channel_mode = alc889A_mb31_6ch_modes,
10649 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10650 .input_mux = &alc889A_mb31_capture_source,
10651 .dig_out_nid = ALC883_DIGOUT_NID,
10652 .unsol_event = alc889A_mb31_unsol_event,
10653 .init_hook = alc889A_mb31_automute,
10654 },
3e1647c5
GG
10655 [ALC883_SONY_VAIO_TT] = {
10656 .mixers = { alc883_vaiott_mixer },
10657 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10658 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10659 .dac_nids = alc883_dac_nids,
10660 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10661 .channel_mode = alc883_3ST_2ch_modes,
10662 .input_mux = &alc883_capture_source,
10663 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10664 .setup = alc883_vaiott_setup,
10665 .init_hook = alc_automute_amp,
3e1647c5 10666 },
9c7f852e
TI
10667};
10668
10669
4953550a
TI
10670/*
10671 * Pin config fixes
10672 */
10673enum {
954a29c8
TI
10674 PINFIX_ABIT_AW9D_MAX,
10675 PINFIX_PB_M5210,
c3d226ab 10676 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10677};
10678
f8f25ba3
TI
10679static const struct alc_fixup alc882_fixups[] = {
10680 [PINFIX_ABIT_AW9D_MAX] = {
73413b12
TI
10681 .pins = (const struct alc_pincfg[]) {
10682 { 0x15, 0x01080104 }, /* side */
10683 { 0x16, 0x01011012 }, /* rear */
10684 { 0x17, 0x01016011 }, /* clfe */
10685 { }
10686 }
f8f25ba3 10687 },
954a29c8 10688 [PINFIX_PB_M5210] = {
73413b12
TI
10689 .verbs = (const struct hda_verb[]) {
10690 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10691 {}
10692 }
954a29c8 10693 },
c3d226ab
DH
10694 [PINFIX_ACER_ASPIRE_7736] = {
10695 .sku = ALC_FIXUP_SKU_IGNORE,
10696 },
4953550a
TI
10697};
10698
f8f25ba3 10699static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10700 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a 10701 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10702 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10703 {}
10704};
10705
9c7f852e
TI
10706/*
10707 * BIOS auto configuration
10708 */
05f5f477
TI
10709static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10710 const struct auto_pin_cfg *cfg)
10711{
10712 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10713}
10714
4953550a 10715static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10716 hda_nid_t nid, int pin_type,
489008cd 10717 hda_nid_t dac)
9c7f852e 10718{
f12ab1e0
TI
10719 int idx;
10720
489008cd 10721 /* set as output */
f6c7e546 10722 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10723
10724 if (dac == 0x25)
9c7f852e 10725 idx = 4;
489008cd
TI
10726 else if (dac >= 0x02 && dac <= 0x05)
10727 idx = dac - 2;
f9700d5a 10728 else
489008cd 10729 return;
9c7f852e 10730 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10731}
10732
4953550a 10733static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10734{
10735 struct alc_spec *spec = codec->spec;
10736 int i;
10737
10738 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10739 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10740 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10741 if (nid)
4953550a 10742 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10743 spec->multiout.dac_nids[i]);
9c7f852e
TI
10744 }
10745}
10746
4953550a 10747static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10748{
10749 struct alc_spec *spec = codec->spec;
489008cd 10750 hda_nid_t pin, dac;
5855fb80 10751 int i;
9c7f852e 10752
5855fb80
TI
10753 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10754 pin = spec->autocfg.hp_pins[i];
10755 if (!pin)
10756 break;
489008cd
TI
10757 dac = spec->multiout.hp_nid;
10758 if (!dac)
10759 dac = spec->multiout.dac_nids[0]; /* to front */
10760 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10761 }
5855fb80
TI
10762 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10763 pin = spec->autocfg.speaker_pins[i];
10764 if (!pin)
10765 break;
489008cd
TI
10766 dac = spec->multiout.extra_out_nid[0];
10767 if (!dac)
10768 dac = spec->multiout.dac_nids[0]; /* to front */
10769 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10770 }
9c7f852e
TI
10771}
10772
4953550a 10773static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10774{
10775 struct alc_spec *spec = codec->spec;
66ceeb6b 10776 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10777 int i;
10778
66ceeb6b
TI
10779 for (i = 0; i < cfg->num_inputs; i++) {
10780 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10781 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10782 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10783 snd_hda_codec_write(codec, nid, 0,
10784 AC_VERB_SET_AMP_GAIN_MUTE,
10785 AMP_OUT_MUTE);
10786 }
10787}
10788
10789static void alc882_auto_init_input_src(struct hda_codec *codec)
10790{
10791 struct alc_spec *spec = codec->spec;
10792 int c;
10793
10794 for (c = 0; c < spec->num_adc_nids; c++) {
10795 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10796 hda_nid_t nid = spec->capsrc_nids[c];
10797 unsigned int mux_idx;
10798 const struct hda_input_mux *imux;
10799 int conns, mute, idx, item;
10800
10801 conns = snd_hda_get_connections(codec, nid, conn_list,
10802 ARRAY_SIZE(conn_list));
10803 if (conns < 0)
10804 continue;
10805 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10806 imux = &spec->input_mux[mux_idx];
5311114d
TI
10807 if (!imux->num_items && mux_idx > 0)
10808 imux = &spec->input_mux[0];
4953550a
TI
10809 for (idx = 0; idx < conns; idx++) {
10810 /* if the current connection is the selected one,
10811 * unmute it as default - otherwise mute it
10812 */
10813 mute = AMP_IN_MUTE(idx);
10814 for (item = 0; item < imux->num_items; item++) {
10815 if (imux->items[item].index == idx) {
10816 if (spec->cur_mux[c] == item)
10817 mute = AMP_IN_UNMUTE(idx);
10818 break;
10819 }
10820 }
10821 /* check if we have a selector or mixer
10822 * we could check for the widget type instead, but
10823 * just check for Amp-In presence (in case of mixer
10824 * without amp-in there is something wrong, this
10825 * function shouldn't be used or capsrc nid is wrong)
10826 */
10827 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10828 snd_hda_codec_write(codec, nid, 0,
10829 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10830 mute);
10831 else if (mute != AMP_IN_MUTE(idx))
10832 snd_hda_codec_write(codec, nid, 0,
10833 AC_VERB_SET_CONNECT_SEL,
10834 idx);
9c7f852e
TI
10835 }
10836 }
10837}
10838
4953550a
TI
10839/* add mic boosts if needed */
10840static int alc_auto_add_mic_boost(struct hda_codec *codec)
10841{
10842 struct alc_spec *spec = codec->spec;
66ceeb6b 10843 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10844 int i, err;
53e8c323 10845 int type_idx = 0;
4953550a 10846 hda_nid_t nid;
5322bf27 10847 const char *prev_label = NULL;
4953550a 10848
66ceeb6b 10849 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10850 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10851 break;
10852 nid = cfg->inputs[i].pin;
10853 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10854 const char *label;
10855 char boost_label[32];
10856
10857 label = hda_get_autocfg_input_label(codec, cfg, i);
10858 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10859 type_idx++;
10860 else
10861 type_idx = 0;
5322bf27
DH
10862 prev_label = label;
10863
10864 snprintf(boost_label, sizeof(boost_label),
10865 "%s Boost Volume", label);
10866 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10867 boost_label, type_idx,
4953550a 10868 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10869 if (err < 0)
10870 return err;
10871 }
4953550a
TI
10872 }
10873 return 0;
10874}
f511b01c 10875
9c7f852e 10876/* almost identical with ALC880 parser... */
4953550a 10877static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10878{
10879 struct alc_spec *spec = codec->spec;
05f5f477 10880 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10881 int err;
9c7f852e 10882
05f5f477
TI
10883 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10884 alc882_ignore);
9c7f852e
TI
10885 if (err < 0)
10886 return err;
05f5f477
TI
10887 if (!spec->autocfg.line_outs)
10888 return 0; /* can't find valid BIOS pin config */
776e184e 10889
05f5f477
TI
10890 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10891 if (err < 0)
10892 return err;
10893 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10894 if (err < 0)
10895 return err;
10896 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10897 "Headphone");
05f5f477
TI
10898 if (err < 0)
10899 return err;
10900 err = alc880_auto_create_extra_out(spec,
10901 spec->autocfg.speaker_pins[0],
10902 "Speaker");
10903 if (err < 0)
10904 return err;
05f5f477 10905 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10906 if (err < 0)
10907 return err;
10908
05f5f477
TI
10909 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10910
757899ac 10911 alc_auto_parse_digital(codec);
05f5f477
TI
10912
10913 if (spec->kctls.list)
10914 add_mixer(spec, spec->kctls.list);
10915
10916 add_verb(spec, alc883_auto_init_verbs);
4953550a 10917 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10918 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10919 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10920
05f5f477
TI
10921 spec->num_mux_defs = 1;
10922 spec->input_mux = &spec->private_imux[0];
10923
6227cdce 10924 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10925
10926 err = alc_auto_add_mic_boost(codec);
10927 if (err < 0)
10928 return err;
61b9b9b1 10929
776e184e 10930 return 1; /* config found */
9c7f852e
TI
10931}
10932
10933/* additional initialization for auto-configuration model */
4953550a 10934static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10935{
f6c7e546 10936 struct alc_spec *spec = codec->spec;
4953550a
TI
10937 alc882_auto_init_multi_out(codec);
10938 alc882_auto_init_hp_out(codec);
10939 alc882_auto_init_analog_input(codec);
10940 alc882_auto_init_input_src(codec);
757899ac 10941 alc_auto_init_digital(codec);
f6c7e546 10942 if (spec->unsol_event)
7fb0d78f 10943 alc_inithook(codec);
9c7f852e
TI
10944}
10945
4953550a 10946static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10947{
10948 struct alc_spec *spec;
10949 int err, board_config;
10950
10951 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10952 if (spec == NULL)
10953 return -ENOMEM;
10954
10955 codec->spec = spec;
10956
4953550a
TI
10957 switch (codec->vendor_id) {
10958 case 0x10ec0882:
10959 case 0x10ec0885:
10960 break;
10961 default:
10962 /* ALC883 and variants */
10963 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10964 break;
10965 }
2c3bf9ab 10966
4953550a
TI
10967 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10968 alc882_models,
10969 alc882_cfg_tbl);
10970
10971 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10972 board_config = snd_hda_check_board_codec_sid_config(codec,
10973 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10974
10975 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10976 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10977 codec->chip_name);
10978 board_config = ALC882_AUTO;
9c7f852e
TI
10979 }
10980
7fa90e87
TI
10981 if (board_config == ALC882_AUTO)
10982 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a 10983
90622917
DH
10984 alc_auto_parse_customize_define(codec);
10985
4953550a 10986 if (board_config == ALC882_AUTO) {
9c7f852e 10987 /* automatic parse from the BIOS config */
4953550a 10988 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10989 if (err < 0) {
10990 alc_free(codec);
10991 return err;
f12ab1e0 10992 } else if (!err) {
9c7f852e
TI
10993 printk(KERN_INFO
10994 "hda_codec: Cannot set up configuration "
10995 "from BIOS. Using base mode...\n");
4953550a 10996 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10997 }
10998 }
10999
dc1eae25 11000 if (has_cdefine_beep(codec)) {
8af2591d
TI
11001 err = snd_hda_attach_beep_device(codec, 0x1);
11002 if (err < 0) {
11003 alc_free(codec);
11004 return err;
11005 }
680cd536
KK
11006 }
11007
4953550a 11008 if (board_config != ALC882_AUTO)
e9c364c0 11009 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11010
4953550a
TI
11011 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11012 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11013 /* FIXME: setup DAC5 */
11014 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11015 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11016
11017 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11018 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11019
4953550a 11020 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11021 int i, j;
4953550a
TI
11022 spec->num_adc_nids = 0;
11023 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11024 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11025 hda_nid_t cap;
d11f74c6 11026 hda_nid_t items[16];
4953550a
TI
11027 hda_nid_t nid = alc882_adc_nids[i];
11028 unsigned int wcap = get_wcaps(codec, nid);
11029 /* get type */
a22d543a 11030 wcap = get_wcaps_type(wcap);
4953550a
TI
11031 if (wcap != AC_WID_AUD_IN)
11032 continue;
11033 spec->private_adc_nids[spec->num_adc_nids] = nid;
11034 err = snd_hda_get_connections(codec, nid, &cap, 1);
11035 if (err < 0)
11036 continue;
d11f74c6
TI
11037 err = snd_hda_get_connections(codec, cap, items,
11038 ARRAY_SIZE(items));
11039 if (err < 0)
11040 continue;
11041 for (j = 0; j < imux->num_items; j++)
11042 if (imux->items[j].index >= err)
11043 break;
11044 if (j < imux->num_items)
11045 continue;
4953550a
TI
11046 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11047 spec->num_adc_nids++;
61b9b9b1 11048 }
4953550a
TI
11049 spec->adc_nids = spec->private_adc_nids;
11050 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11051 }
11052
b59bdf3b 11053 set_capture_mixer(codec);
da00c244 11054
dc1eae25 11055 if (has_cdefine_beep(codec))
da00c244 11056 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11057
7fa90e87
TI
11058 if (board_config == ALC882_AUTO)
11059 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
11060
2134ea4f
TI
11061 spec->vmaster_nid = 0x0c;
11062
9c7f852e 11063 codec->patch_ops = alc_patch_ops;
4953550a
TI
11064 if (board_config == ALC882_AUTO)
11065 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11066
11067 alc_init_jacks(codec);
cb53c626
TI
11068#ifdef CONFIG_SND_HDA_POWER_SAVE
11069 if (!spec->loopback.amplist)
4953550a 11070 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11071#endif
9c7f852e
TI
11072
11073 return 0;
11074}
11075
4953550a 11076
9c7f852e
TI
11077/*
11078 * ALC262 support
11079 */
11080
11081#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11082#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11083
11084#define alc262_dac_nids alc260_dac_nids
11085#define alc262_adc_nids alc882_adc_nids
11086#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11087#define alc262_capsrc_nids alc882_capsrc_nids
11088#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11089
11090#define alc262_modes alc260_modes
11091#define alc262_capture_source alc882_capture_source
11092
4e555fe5
KY
11093static hda_nid_t alc262_dmic_adc_nids[1] = {
11094 /* ADC0 */
11095 0x09
11096};
11097
11098static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11099
9c7f852e
TI
11100static struct snd_kcontrol_new alc262_base_mixer[] = {
11101 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11102 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11103 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11104 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11105 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11106 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11107 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11108 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11109 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11110 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11111 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11112 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11113 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11115 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11116 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11117 { } /* end */
11118};
11119
ce875f07
TI
11120/* update HP, line and mono-out pins according to the master switch */
11121static void alc262_hp_master_update(struct hda_codec *codec)
11122{
11123 struct alc_spec *spec = codec->spec;
11124 int val = spec->master_sw;
11125
11126 /* HP & line-out */
11127 snd_hda_codec_write_cache(codec, 0x1b, 0,
11128 AC_VERB_SET_PIN_WIDGET_CONTROL,
11129 val ? PIN_HP : 0);
11130 snd_hda_codec_write_cache(codec, 0x15, 0,
11131 AC_VERB_SET_PIN_WIDGET_CONTROL,
11132 val ? PIN_HP : 0);
11133 /* mono (speaker) depending on the HP jack sense */
11134 val = val && !spec->jack_present;
11135 snd_hda_codec_write_cache(codec, 0x16, 0,
11136 AC_VERB_SET_PIN_WIDGET_CONTROL,
11137 val ? PIN_OUT : 0);
11138}
11139
11140static void alc262_hp_bpc_automute(struct hda_codec *codec)
11141{
11142 struct alc_spec *spec = codec->spec;
864f92be
WF
11143
11144 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11145 alc262_hp_master_update(codec);
11146}
11147
11148static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11149{
11150 if ((res >> 26) != ALC880_HP_EVENT)
11151 return;
11152 alc262_hp_bpc_automute(codec);
11153}
11154
11155static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11156{
11157 struct alc_spec *spec = codec->spec;
864f92be
WF
11158
11159 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11160 alc262_hp_master_update(codec);
11161}
11162
11163static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11164 unsigned int res)
11165{
11166 if ((res >> 26) != ALC880_HP_EVENT)
11167 return;
11168 alc262_hp_wildwest_automute(codec);
11169}
11170
b72519b5 11171#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11172
11173static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11174 struct snd_ctl_elem_value *ucontrol)
11175{
11176 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11177 struct alc_spec *spec = codec->spec;
11178 int val = !!*ucontrol->value.integer.value;
11179
11180 if (val == spec->master_sw)
11181 return 0;
11182 spec->master_sw = val;
11183 alc262_hp_master_update(codec);
11184 return 1;
11185}
11186
b72519b5
TI
11187#define ALC262_HP_MASTER_SWITCH \
11188 { \
11189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11190 .name = "Master Playback Switch", \
11191 .info = snd_ctl_boolean_mono_info, \
11192 .get = alc262_hp_master_sw_get, \
11193 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11194 }, \
11195 { \
11196 .iface = NID_MAPPING, \
11197 .name = "Master Playback Switch", \
11198 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11199 }
11200
5b0cb1d8 11201
9c7f852e 11202static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11203 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11204 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11205 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11206 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11207 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11208 HDA_OUTPUT),
11209 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11210 HDA_OUTPUT),
9c7f852e
TI
11211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11213 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11214 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11215 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11216 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11217 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11218 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11219 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11220 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11221 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11222 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11223 { } /* end */
11224};
11225
cd7509a4 11226static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11227 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11228 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11229 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11230 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11232 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11233 HDA_OUTPUT),
11234 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11235 HDA_OUTPUT),
cd7509a4
KY
11236 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11237 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11238 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11239 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11240 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11241 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11242 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11243 { } /* end */
11244};
11245
11246static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11247 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11248 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11249 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11250 { } /* end */
11251};
11252
66d2a9d6 11253/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11254static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11255{
11256 struct alc_spec *spec = codec->spec;
66d2a9d6 11257
a9fd4f3f 11258 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11259 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11260}
11261
66d2a9d6 11262static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11263 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11264 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11265 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11266 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11267 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11269 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11270 { } /* end */
11271};
11272
11273static struct hda_verb alc262_hp_t5735_verbs[] = {
11274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11276
11277 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11278 { }
11279};
11280
8c427226 11281static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11282 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11283 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11284 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11285 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11286 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11287 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11288 { } /* end */
11289};
11290
11291static struct hda_verb alc262_hp_rp5700_verbs[] = {
11292 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11293 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11294 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11295 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11296 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11297 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11298 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11300 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11302 {}
11303};
11304
11305static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11306 .num_items = 1,
11307 .items = {
11308 { "Line", 0x1 },
11309 },
11310};
11311
42171c17
TI
11312/* bind hp and internal speaker mute (with plug check) as master switch */
11313static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11314{
42171c17
TI
11315 struct alc_spec *spec = codec->spec;
11316 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11317 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11318 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11319 unsigned int mute;
0724ea2a 11320
42171c17
TI
11321 /* HP */
11322 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11323 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11324 HDA_AMP_MUTE, mute);
11325 /* mute internal speaker per jack sense */
11326 if (spec->jack_present)
11327 mute = HDA_AMP_MUTE;
11328 if (line_nid)
11329 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11330 HDA_AMP_MUTE, mute);
11331 if (speaker_nid && speaker_nid != line_nid)
11332 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11333 HDA_AMP_MUTE, mute);
42171c17
TI
11334}
11335
11336#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11337
11338static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11339 struct snd_ctl_elem_value *ucontrol)
11340{
11341 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11342 struct alc_spec *spec = codec->spec;
11343 int val = !!*ucontrol->value.integer.value;
11344
11345 if (val == spec->master_sw)
11346 return 0;
11347 spec->master_sw = val;
11348 alc262_hippo_master_update(codec);
11349 return 1;
11350}
11351
11352#define ALC262_HIPPO_MASTER_SWITCH \
11353 { \
11354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11355 .name = "Master Playback Switch", \
11356 .info = snd_ctl_boolean_mono_info, \
11357 .get = alc262_hippo_master_sw_get, \
11358 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11359 }, \
11360 { \
11361 .iface = NID_MAPPING, \
11362 .name = "Master Playback Switch", \
11363 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11364 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11365 }
42171c17
TI
11366
11367static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11368 ALC262_HIPPO_MASTER_SWITCH,
11369 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11370 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11371 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11373 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11374 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11375 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11376 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11377 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11378 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11379 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11380 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11381 { } /* end */
11382};
11383
11384static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11385 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11386 ALC262_HIPPO_MASTER_SWITCH,
11387 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11388 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11389 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11390 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11391 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11392 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11393 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11394 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11395 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11396 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11397 { } /* end */
11398};
11399
11400/* mute/unmute internal speaker according to the hp jack and mute state */
11401static void alc262_hippo_automute(struct hda_codec *codec)
11402{
11403 struct alc_spec *spec = codec->spec;
11404 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11405
864f92be 11406 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11407 alc262_hippo_master_update(codec);
0724ea2a 11408}
5b31954e 11409
42171c17
TI
11410static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11411{
11412 if ((res >> 26) != ALC880_HP_EVENT)
11413 return;
11414 alc262_hippo_automute(codec);
11415}
11416
4f5d1706 11417static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11418{
11419 struct alc_spec *spec = codec->spec;
11420
11421 spec->autocfg.hp_pins[0] = 0x15;
11422 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11423}
11424
4f5d1706 11425static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11426{
11427 struct alc_spec *spec = codec->spec;
11428
11429 spec->autocfg.hp_pins[0] = 0x1b;
11430 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11431}
11432
11433
272a527c 11434static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11435 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11436 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11439 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11440 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11441 { } /* end */
11442};
11443
83c34218 11444static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11445 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11446 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11447 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11448 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11449 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11450 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11451 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11452 { } /* end */
11453};
272a527c 11454
ba340e82
TV
11455static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11456 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11457 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11458 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11459 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11461 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11463 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11465 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11466 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11467 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11468 { } /* end */
11469};
11470
11471static struct hda_verb alc262_tyan_verbs[] = {
11472 /* Headphone automute */
11473 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11474 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11475 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11476
11477 /* P11 AUX_IN, white 4-pin connector */
11478 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11479 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11480 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11481 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11482
11483 {}
11484};
11485
11486/* unsolicited event for HP jack sensing */
4f5d1706 11487static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11488{
a9fd4f3f 11489 struct alc_spec *spec = codec->spec;
ba340e82 11490
a9fd4f3f
TI
11491 spec->autocfg.hp_pins[0] = 0x1b;
11492 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11493}
11494
ba340e82 11495
9c7f852e
TI
11496#define alc262_capture_mixer alc882_capture_mixer
11497#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11498
11499/*
11500 * generic initialization of ADC, input mixers and output mixers
11501 */
11502static struct hda_verb alc262_init_verbs[] = {
11503 /*
11504 * Unmute ADC0-2 and set the default input to mic-in
11505 */
11506 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11508 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11509 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11510 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11511 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11512
cb53c626 11513 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11514 * mixer widget
f12ab1e0
TI
11515 * Note: PASD motherboards uses the Line In 2 as the input for
11516 * front panel mic (mic 2)
9c7f852e
TI
11517 */
11518 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11524
11525 /*
df694daa
KY
11526 * Set up output mixers (0x0c - 0x0e)
11527 */
11528 /* set vol=0 to output mixers */
11529 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11530 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11531 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11532 /* set up input amps for analog loopback */
11533 /* Amp Indices: DAC = 0, mixer = 1 */
11534 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11535 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11536 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11539 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11540
11541 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11542 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11543 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11544 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11545 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11546 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11547
11548 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11549 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11550 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11551 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11552 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11553
df694daa
KY
11554 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11555 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11556
df694daa
KY
11557 /* FIXME: use matrix-type input source selection */
11558 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11559 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11560 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11561 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11562 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11563 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11564 /* Input mixer2 */
11565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11566 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11567 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11568 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11569 /* Input mixer3 */
11570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11571 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11573 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11574
11575 { }
11576};
1da177e4 11577
4e555fe5
KY
11578static struct hda_verb alc262_eapd_verbs[] = {
11579 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11580 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11581 { }
11582};
11583
ccc656ce
KY
11584static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11585 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11586 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11587 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11588
11589 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11591 {}
11592};
11593
272a527c
KY
11594static struct hda_verb alc262_sony_unsol_verbs[] = {
11595 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11596 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11598
11599 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11601 {}
272a527c
KY
11602};
11603
4e555fe5
KY
11604static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11605 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11606 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11607 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11609 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11610 { } /* end */
11611};
11612
11613static struct hda_verb alc262_toshiba_s06_verbs[] = {
11614 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11615 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11616 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11617 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11618 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11619 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11620 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11621 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11622 {}
11623};
11624
4f5d1706 11625static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11626{
a9fd4f3f
TI
11627 struct alc_spec *spec = codec->spec;
11628
11629 spec->autocfg.hp_pins[0] = 0x15;
11630 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11631 spec->ext_mic.pin = 0x18;
11632 spec->ext_mic.mux_idx = 0;
11633 spec->int_mic.pin = 0x12;
11634 spec->int_mic.mux_idx = 9;
11635 spec->auto_mic = 1;
4e555fe5
KY
11636}
11637
e8f9ae2a
PT
11638/*
11639 * nec model
11640 * 0x15 = headphone
11641 * 0x16 = internal speaker
11642 * 0x18 = external mic
11643 */
11644
11645static struct snd_kcontrol_new alc262_nec_mixer[] = {
11646 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11647 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11648
11649 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11650 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11651 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11652
11653 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11654 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11655 { } /* end */
11656};
11657
11658static struct hda_verb alc262_nec_verbs[] = {
11659 /* Unmute Speaker */
11660 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11661
11662 /* Headphone */
11663 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11664 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11665
11666 /* External mic to headphone */
11667 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11668 /* External mic to speaker */
11669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11670 {}
11671};
11672
834be88d
TI
11673/*
11674 * fujitsu model
5d9fab2d
TV
11675 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11676 * 0x1b = port replicator headphone out
834be88d
TI
11677 */
11678
11679#define ALC_HP_EVENT 0x37
11680
11681static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11682 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11683 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11684 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11685 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11686 {}
11687};
11688
0e31daf7
J
11689static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11690 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11691 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11692 {}
11693};
11694
e2595322
DC
11695static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11696 /* Front Mic pin: input vref at 50% */
11697 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11698 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11699 {}
11700};
11701
834be88d 11702static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11703 .num_items = 3,
834be88d
TI
11704 .items = {
11705 { "Mic", 0x0 },
28c4edb7 11706 { "Internal Mic", 0x1 },
834be88d
TI
11707 { "CD", 0x4 },
11708 },
11709};
11710
9c7f852e
TI
11711static struct hda_input_mux alc262_HP_capture_source = {
11712 .num_items = 5,
11713 .items = {
11714 { "Mic", 0x0 },
accbe498 11715 { "Front Mic", 0x1 },
9c7f852e
TI
11716 { "Line", 0x2 },
11717 { "CD", 0x4 },
11718 { "AUX IN", 0x6 },
11719 },
11720};
11721
accbe498 11722static struct hda_input_mux alc262_HP_D7000_capture_source = {
11723 .num_items = 4,
11724 .items = {
11725 { "Mic", 0x0 },
11726 { "Front Mic", 0x2 },
11727 { "Line", 0x1 },
11728 { "CD", 0x4 },
11729 },
11730};
11731
ebc7a406 11732/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11733static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11734{
11735 struct alc_spec *spec = codec->spec;
11736 unsigned int mute;
11737
f12ab1e0 11738 if (force || !spec->sense_updated) {
864f92be
WF
11739 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11740 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11741 spec->sense_updated = 1;
11742 }
ebc7a406
TI
11743 /* unmute internal speaker only if both HPs are unplugged and
11744 * master switch is on
11745 */
11746 if (spec->jack_present)
11747 mute = HDA_AMP_MUTE;
11748 else
834be88d 11749 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11750 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11751 HDA_AMP_MUTE, mute);
834be88d
TI
11752}
11753
11754/* unsolicited event for HP jack sensing */
11755static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11756 unsigned int res)
11757{
11758 if ((res >> 26) != ALC_HP_EVENT)
11759 return;
11760 alc262_fujitsu_automute(codec, 1);
11761}
11762
ebc7a406
TI
11763static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11764{
11765 alc262_fujitsu_automute(codec, 1);
11766}
11767
834be88d 11768/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11769static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11770 .ops = &snd_hda_bind_vol,
11771 .values = {
11772 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11773 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11774 0
11775 },
11776};
834be88d 11777
0e31daf7
J
11778/* mute/unmute internal speaker according to the hp jack and mute state */
11779static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11780{
11781 struct alc_spec *spec = codec->spec;
11782 unsigned int mute;
11783
11784 if (force || !spec->sense_updated) {
864f92be 11785 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11786 spec->sense_updated = 1;
11787 }
11788 if (spec->jack_present) {
11789 /* mute internal speaker */
11790 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11791 HDA_AMP_MUTE, HDA_AMP_MUTE);
11792 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11793 HDA_AMP_MUTE, HDA_AMP_MUTE);
11794 } else {
11795 /* unmute internal speaker if necessary */
11796 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11797 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11798 HDA_AMP_MUTE, mute);
11799 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11800 HDA_AMP_MUTE, mute);
11801 }
11802}
11803
11804/* unsolicited event for HP jack sensing */
11805static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11806 unsigned int res)
11807{
11808 if ((res >> 26) != ALC_HP_EVENT)
11809 return;
11810 alc262_lenovo_3000_automute(codec, 1);
11811}
11812
8de56b7d
TI
11813static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11814 int dir, int idx, long *valp)
11815{
11816 int i, change = 0;
11817
11818 for (i = 0; i < 2; i++, valp++)
11819 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11820 HDA_AMP_MUTE,
11821 *valp ? 0 : HDA_AMP_MUTE);
11822 return change;
11823}
11824
834be88d
TI
11825/* bind hp and internal speaker mute (with plug check) */
11826static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11827 struct snd_ctl_elem_value *ucontrol)
11828{
11829 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11830 long *valp = ucontrol->value.integer.value;
11831 int change;
11832
8de56b7d
TI
11833 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11834 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11835 if (change)
11836 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11837 return change;
11838}
11839
11840static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11841 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11842 {
11843 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11844 .name = "Master Playback Switch",
5e26dfd0 11845 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11846 .info = snd_hda_mixer_amp_switch_info,
11847 .get = snd_hda_mixer_amp_switch_get,
11848 .put = alc262_fujitsu_master_sw_put,
11849 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11850 },
5b0cb1d8
JK
11851 {
11852 .iface = NID_MAPPING,
11853 .name = "Master Playback Switch",
11854 .private_value = 0x1b,
11855 },
834be88d
TI
11856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11858 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11860 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11861 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11862 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11863 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11864 { } /* end */
11865};
11866
0e31daf7
J
11867/* bind hp and internal speaker mute (with plug check) */
11868static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11869 struct snd_ctl_elem_value *ucontrol)
11870{
11871 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11872 long *valp = ucontrol->value.integer.value;
11873 int change;
11874
8de56b7d 11875 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11876 if (change)
11877 alc262_lenovo_3000_automute(codec, 0);
11878 return change;
11879}
11880
11881static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11882 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11883 {
11884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11885 .name = "Master Playback Switch",
5e26dfd0 11886 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11887 .info = snd_hda_mixer_amp_switch_info,
11888 .get = snd_hda_mixer_amp_switch_get,
11889 .put = alc262_lenovo_3000_master_sw_put,
11890 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11891 },
11892 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11893 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11894 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11896 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11897 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11898 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11899 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11900 { } /* end */
11901};
11902
9f99a638
HM
11903static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11904 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11905 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11906 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11907 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11908 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11909 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11910 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11911 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11912 { } /* end */
11913};
11914
304dcaac
TI
11915/* additional init verbs for Benq laptops */
11916static struct hda_verb alc262_EAPD_verbs[] = {
11917 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11918 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11919 {}
11920};
11921
83c34218
KY
11922static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11923 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11924 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11925
11926 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11927 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11928 {}
11929};
11930
f651b50b
TD
11931/* Samsung Q1 Ultra Vista model setup */
11932static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11933 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11934 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11935 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11937 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11938 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11939 { } /* end */
11940};
11941
11942static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11943 /* output mixer */
11944 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11946 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11947 /* speaker */
11948 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11949 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11950 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11951 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11952 /* HP */
f651b50b 11953 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11954 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11955 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11956 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11957 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11958 /* internal mic */
11959 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11960 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11961 /* ADC, choose mic */
11962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11963 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11964 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11965 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11966 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11967 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11968 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11969 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11970 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11971 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11972 {}
11973};
11974
f651b50b
TD
11975/* mute/unmute internal speaker according to the hp jack and mute state */
11976static void alc262_ultra_automute(struct hda_codec *codec)
11977{
11978 struct alc_spec *spec = codec->spec;
11979 unsigned int mute;
f651b50b 11980
bb9f76cd
TI
11981 mute = 0;
11982 /* auto-mute only when HP is used as HP */
11983 if (!spec->cur_mux[0]) {
864f92be 11984 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11985 if (spec->jack_present)
11986 mute = HDA_AMP_MUTE;
f651b50b 11987 }
bb9f76cd
TI
11988 /* mute/unmute internal speaker */
11989 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11990 HDA_AMP_MUTE, mute);
11991 /* mute/unmute HP */
11992 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11993 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11994}
11995
11996/* unsolicited event for HP jack sensing */
11997static void alc262_ultra_unsol_event(struct hda_codec *codec,
11998 unsigned int res)
11999{
12000 if ((res >> 26) != ALC880_HP_EVENT)
12001 return;
12002 alc262_ultra_automute(codec);
12003}
12004
bb9f76cd
TI
12005static struct hda_input_mux alc262_ultra_capture_source = {
12006 .num_items = 2,
12007 .items = {
12008 { "Mic", 0x1 },
12009 { "Headphone", 0x7 },
12010 },
12011};
12012
12013static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12014 struct snd_ctl_elem_value *ucontrol)
12015{
12016 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12017 struct alc_spec *spec = codec->spec;
12018 int ret;
12019
54cbc9ab 12020 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12021 if (!ret)
12022 return 0;
12023 /* reprogram the HP pin as mic or HP according to the input source */
12024 snd_hda_codec_write_cache(codec, 0x15, 0,
12025 AC_VERB_SET_PIN_WIDGET_CONTROL,
12026 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12027 alc262_ultra_automute(codec); /* mute/unmute HP */
12028 return ret;
12029}
12030
12031static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12032 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12033 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12034 {
12035 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12036 .name = "Capture Source",
54cbc9ab
TI
12037 .info = alc_mux_enum_info,
12038 .get = alc_mux_enum_get,
bb9f76cd
TI
12039 .put = alc262_ultra_mux_enum_put,
12040 },
5b0cb1d8
JK
12041 {
12042 .iface = NID_MAPPING,
12043 .name = "Capture Source",
12044 .private_value = 0x15,
12045 },
bb9f76cd
TI
12046 { } /* end */
12047};
12048
c3fc1f50
TI
12049/* We use two mixers depending on the output pin; 0x16 is a mono output
12050 * and thus it's bound with a different mixer.
12051 * This function returns which mixer amp should be used.
12052 */
12053static int alc262_check_volbit(hda_nid_t nid)
12054{
12055 if (!nid)
12056 return 0;
12057 else if (nid == 0x16)
12058 return 2;
12059 else
12060 return 1;
12061}
12062
12063static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12064 const char *pfx, int *vbits, int idx)
c3fc1f50 12065{
c3fc1f50
TI
12066 unsigned long val;
12067 int vbit;
12068
12069 vbit = alc262_check_volbit(nid);
12070 if (!vbit)
12071 return 0;
12072 if (*vbits & vbit) /* a volume control for this mixer already there */
12073 return 0;
12074 *vbits |= vbit;
c3fc1f50
TI
12075 if (vbit == 2)
12076 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12077 else
12078 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12079 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12080}
12081
12082static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12083 const char *pfx, int idx)
c3fc1f50 12084{
c3fc1f50
TI
12085 unsigned long val;
12086
12087 if (!nid)
12088 return 0;
c3fc1f50
TI
12089 if (nid == 0x16)
12090 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12091 else
12092 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12093 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12094}
12095
df694daa 12096/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12097static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12098 const struct auto_pin_cfg *cfg)
df694daa 12099{
c3fc1f50
TI
12100 const char *pfx;
12101 int vbits;
033688a5 12102 int i, err;
df694daa
KY
12103
12104 spec->multiout.num_dacs = 1; /* only use one dac */
12105 spec->multiout.dac_nids = spec->private_dac_nids;
12106 spec->multiout.dac_nids[0] = 2;
12107
bcb2f0f5
TI
12108 pfx = alc_get_line_out_pfx(cfg, true);
12109 if (!pfx)
c3fc1f50 12110 pfx = "Front";
033688a5
TI
12111 for (i = 0; i < 2; i++) {
12112 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12113 if (err < 0)
12114 return err;
12115 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12116 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12117 "Speaker", i);
12118 if (err < 0)
12119 return err;
12120 }
12121 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12122 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12123 "Headphone", i);
12124 if (err < 0)
12125 return err;
12126 }
12127 }
df694daa 12128
c3fc1f50
TI
12129 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12130 alc262_check_volbit(cfg->speaker_pins[0]) |
12131 alc262_check_volbit(cfg->hp_pins[0]);
12132 if (vbits == 1 || vbits == 2)
12133 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12134 vbits = 0;
033688a5
TI
12135 for (i = 0; i < 2; i++) {
12136 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12137 &vbits, i);
12138 if (err < 0)
12139 return err;
12140 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12141 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12142 "Speaker", &vbits, i);
12143 if (err < 0)
12144 return err;
12145 }
12146 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12147 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12148 "Headphone", &vbits, i);
12149 if (err < 0)
12150 return err;
12151 }
12152 }
f12ab1e0 12153 return 0;
df694daa
KY
12154}
12155
05f5f477 12156#define alc262_auto_create_input_ctls \
eaa9b3a7 12157 alc882_auto_create_input_ctls
df694daa
KY
12158
12159/*
12160 * generic initialization of ADC, input mixers and output mixers
12161 */
12162static struct hda_verb alc262_volume_init_verbs[] = {
12163 /*
12164 * Unmute ADC0-2 and set the default input to mic-in
12165 */
12166 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12168 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12169 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12170 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12171 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12172
cb53c626 12173 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12174 * mixer widget
f12ab1e0
TI
12175 * Note: PASD motherboards uses the Line In 2 as the input for
12176 * front panel mic (mic 2)
df694daa
KY
12177 */
12178 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12179 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12180 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12181 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12182 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12183 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12184
12185 /*
12186 * Set up output mixers (0x0c - 0x0f)
12187 */
12188 /* set vol=0 to output mixers */
12189 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12190 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12191 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12192
df694daa
KY
12193 /* set up input amps for analog loopback */
12194 /* Amp Indices: DAC = 0, mixer = 1 */
12195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12197 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12198 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12199 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12200 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12201
12202 /* FIXME: use matrix-type input source selection */
12203 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12204 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12205 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12209 /* Input mixer2 */
12210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12211 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12213 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12214 /* Input mixer3 */
12215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12217 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12218 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12219
12220 { }
12221};
12222
9c7f852e
TI
12223static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12224 /*
12225 * Unmute ADC0-2 and set the default input to mic-in
12226 */
12227 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12229 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12230 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12231 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12232 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12233
cb53c626 12234 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12235 * mixer widget
f12ab1e0
TI
12236 * Note: PASD motherboards uses the Line In 2 as the input for
12237 * front panel mic (mic 2)
9c7f852e
TI
12238 */
12239 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12247
9c7f852e
TI
12248 /*
12249 * Set up output mixers (0x0c - 0x0e)
12250 */
12251 /* set vol=0 to output mixers */
12252 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12254 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12255
12256 /* set up input amps for analog loopback */
12257 /* Amp Indices: DAC = 0, mixer = 1 */
12258 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12259 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12260 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12261 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12262 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12263 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12264
ce875f07 12265 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12266 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12267 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12268
12269 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12271
12272 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12273 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12274
12275 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12276 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12277 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12278 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12279 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12280
0e4835c1 12281 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12282 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12283 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12284 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12285 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12286 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12287
12288
12289 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12290 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12291 /* Input mixer1: only unmute Mic */
9c7f852e 12292 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12293 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12294 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12296 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12300 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12301 /* Input mixer2 */
12302 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12303 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12310 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12311 /* Input mixer3 */
12312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12318 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12319 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12320 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12321
ce875f07
TI
12322 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12323
9c7f852e
TI
12324 { }
12325};
12326
cd7509a4
KY
12327static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12328 /*
12329 * Unmute ADC0-2 and set the default input to mic-in
12330 */
12331 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12333 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12334 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12335 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12336 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12337
cb53c626 12338 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12339 * mixer widget
12340 * Note: PASD motherboards uses the Line In 2 as the input for front
12341 * panel mic (mic 2)
12342 */
12343 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12344 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12345 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12346 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12347 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12348 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12349 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12350 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12351 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12352 /*
12353 * Set up output mixers (0x0c - 0x0e)
12354 */
12355 /* set vol=0 to output mixers */
12356 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12357 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12358 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12359
12360 /* set up input amps for analog loopback */
12361 /* Amp Indices: DAC = 0, mixer = 1 */
12362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12365 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12366 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12367 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12368
12369
12370 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12371 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12372 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12373 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12374 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12375 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12376 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12377
12378 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12379 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12380
12381 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12382 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12383
12384 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12385 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12386 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12387 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12388 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12389 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12390
12391 /* FIXME: use matrix-type input source selection */
12392 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12393 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12394 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12395 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12396 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12397 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12398 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12399 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12400 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12401 /* Input mixer2 */
12402 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12403 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12404 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12405 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12406 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12407 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12408 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12409 /* Input mixer3 */
12410 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12411 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12412 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12413 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12414 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12415 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12416 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12417
ce875f07
TI
12418 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12419
cd7509a4
KY
12420 { }
12421};
12422
9f99a638
HM
12423static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12424
12425 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12426 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12427 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12428
12429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12430 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12431 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12432 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12433
12434 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12435 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12436 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12437 {}
12438};
12439
18675e42
TI
12440/*
12441 * Pin config fixes
12442 */
12443enum {
12444 PINFIX_FSC_H270,
12445};
12446
12447static const struct alc_fixup alc262_fixups[] = {
12448 [PINFIX_FSC_H270] = {
12449 .pins = (const struct alc_pincfg[]) {
12450 { 0x14, 0x99130110 }, /* speaker */
12451 { 0x15, 0x0221142f }, /* front HP */
12452 { 0x1b, 0x0121141f }, /* rear HP */
12453 { }
12454 }
12455 },
18675e42
TI
12456};
12457
12458static struct snd_pci_quirk alc262_fixup_tbl[] = {
12459 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12460 {}
12461};
12462
9f99a638 12463
cb53c626
TI
12464#ifdef CONFIG_SND_HDA_POWER_SAVE
12465#define alc262_loopbacks alc880_loopbacks
12466#endif
12467
def319f9 12468/* pcm configuration: identical with ALC880 */
df694daa
KY
12469#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12470#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12471#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12472#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12473
12474/*
12475 * BIOS auto configuration
12476 */
12477static int alc262_parse_auto_config(struct hda_codec *codec)
12478{
12479 struct alc_spec *spec = codec->spec;
12480 int err;
12481 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12482
f12ab1e0
TI
12483 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12484 alc262_ignore);
12485 if (err < 0)
df694daa 12486 return err;
e64f14f4 12487 if (!spec->autocfg.line_outs) {
0852d7a6 12488 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12489 spec->multiout.max_channels = 2;
12490 spec->no_analog = 1;
12491 goto dig_only;
12492 }
df694daa 12493 return 0; /* can't find valid BIOS pin config */
e64f14f4 12494 }
f12ab1e0
TI
12495 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12496 if (err < 0)
12497 return err;
05f5f477 12498 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12499 if (err < 0)
df694daa
KY
12500 return err;
12501
12502 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12503
e64f14f4 12504 dig_only:
757899ac 12505 alc_auto_parse_digital(codec);
df694daa 12506
603c4019 12507 if (spec->kctls.list)
d88897ea 12508 add_mixer(spec, spec->kctls.list);
df694daa 12509
d88897ea 12510 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12511 spec->num_mux_defs = 1;
61b9b9b1 12512 spec->input_mux = &spec->private_imux[0];
df694daa 12513
776e184e
TI
12514 err = alc_auto_add_mic_boost(codec);
12515 if (err < 0)
12516 return err;
12517
6227cdce 12518 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12519
df694daa
KY
12520 return 1;
12521}
12522
12523#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12524#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12525#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12526#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12527
12528
12529/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12530static void alc262_auto_init(struct hda_codec *codec)
df694daa 12531{
f6c7e546 12532 struct alc_spec *spec = codec->spec;
df694daa
KY
12533 alc262_auto_init_multi_out(codec);
12534 alc262_auto_init_hp_out(codec);
12535 alc262_auto_init_analog_input(codec);
f511b01c 12536 alc262_auto_init_input_src(codec);
757899ac 12537 alc_auto_init_digital(codec);
f6c7e546 12538 if (spec->unsol_event)
7fb0d78f 12539 alc_inithook(codec);
df694daa
KY
12540}
12541
12542/*
12543 * configuration and preset
12544 */
f5fcc13c
TI
12545static const char *alc262_models[ALC262_MODEL_LAST] = {
12546 [ALC262_BASIC] = "basic",
12547 [ALC262_HIPPO] = "hippo",
12548 [ALC262_HIPPO_1] = "hippo_1",
12549 [ALC262_FUJITSU] = "fujitsu",
12550 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12551 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12552 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12553 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12554 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12555 [ALC262_BENQ_T31] = "benq-t31",
12556 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12557 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12558 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12559 [ALC262_ULTRA] = "ultra",
0e31daf7 12560 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12561 [ALC262_NEC] = "nec",
ba340e82 12562 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12563 [ALC262_AUTO] = "auto",
12564};
12565
12566static struct snd_pci_quirk alc262_cfg_tbl[] = {
12567 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12568 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12569 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12570 ALC262_HP_BPC),
12571 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12572 ALC262_HP_BPC),
53eff7e1
TI
12573 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12574 ALC262_HP_BPC),
cd7509a4 12575 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12576 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12577 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12578 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12579 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12580 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12581 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12582 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12583 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12584 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12585 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12586 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12587 ALC262_HP_TC_T5735),
8c427226 12588 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12589 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12590 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12591 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12592 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12593 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12594 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12595 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12596#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12597 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12598 ALC262_SONY_ASSAMD),
c5b5165c 12599#endif
36ca6e13 12600 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12601 ALC262_TOSHIBA_RX1),
80ffe869 12602 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12603 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12604 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12605 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12606 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12607 ALC262_ULTRA),
3e420e78 12608 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12609 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12610 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12611 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12612 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12613 {}
12614};
12615
12616static struct alc_config_preset alc262_presets[] = {
12617 [ALC262_BASIC] = {
12618 .mixers = { alc262_base_mixer },
12619 .init_verbs = { alc262_init_verbs },
12620 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12621 .dac_nids = alc262_dac_nids,
12622 .hp_nid = 0x03,
12623 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12624 .channel_mode = alc262_modes,
a3bcba38 12625 .input_mux = &alc262_capture_source,
df694daa 12626 },
ccc656ce 12627 [ALC262_HIPPO] = {
42171c17 12628 .mixers = { alc262_hippo_mixer },
6732bd0d 12629 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12630 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12631 .dac_nids = alc262_dac_nids,
12632 .hp_nid = 0x03,
12633 .dig_out_nid = ALC262_DIGOUT_NID,
12634 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12635 .channel_mode = alc262_modes,
12636 .input_mux = &alc262_capture_source,
12637 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12638 .setup = alc262_hippo_setup,
12639 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12640 },
12641 [ALC262_HIPPO_1] = {
12642 .mixers = { alc262_hippo1_mixer },
12643 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12644 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12645 .dac_nids = alc262_dac_nids,
12646 .hp_nid = 0x02,
12647 .dig_out_nid = ALC262_DIGOUT_NID,
12648 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12649 .channel_mode = alc262_modes,
12650 .input_mux = &alc262_capture_source,
42171c17 12651 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12652 .setup = alc262_hippo1_setup,
12653 .init_hook = alc262_hippo_automute,
ccc656ce 12654 },
834be88d
TI
12655 [ALC262_FUJITSU] = {
12656 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12657 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12658 alc262_fujitsu_unsol_verbs },
834be88d
TI
12659 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12660 .dac_nids = alc262_dac_nids,
12661 .hp_nid = 0x03,
12662 .dig_out_nid = ALC262_DIGOUT_NID,
12663 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12664 .channel_mode = alc262_modes,
12665 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12666 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12667 .init_hook = alc262_fujitsu_init_hook,
834be88d 12668 },
9c7f852e
TI
12669 [ALC262_HP_BPC] = {
12670 .mixers = { alc262_HP_BPC_mixer },
12671 .init_verbs = { alc262_HP_BPC_init_verbs },
12672 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12673 .dac_nids = alc262_dac_nids,
12674 .hp_nid = 0x03,
12675 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12676 .channel_mode = alc262_modes,
12677 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12678 .unsol_event = alc262_hp_bpc_unsol_event,
12679 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12680 },
cd7509a4
KY
12681 [ALC262_HP_BPC_D7000_WF] = {
12682 .mixers = { alc262_HP_BPC_WildWest_mixer },
12683 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12684 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12685 .dac_nids = alc262_dac_nids,
12686 .hp_nid = 0x03,
12687 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12688 .channel_mode = alc262_modes,
accbe498 12689 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12690 .unsol_event = alc262_hp_wildwest_unsol_event,
12691 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12692 },
cd7509a4
KY
12693 [ALC262_HP_BPC_D7000_WL] = {
12694 .mixers = { alc262_HP_BPC_WildWest_mixer,
12695 alc262_HP_BPC_WildWest_option_mixer },
12696 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12697 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12698 .dac_nids = alc262_dac_nids,
12699 .hp_nid = 0x03,
12700 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12701 .channel_mode = alc262_modes,
accbe498 12702 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12703 .unsol_event = alc262_hp_wildwest_unsol_event,
12704 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12705 },
66d2a9d6
KY
12706 [ALC262_HP_TC_T5735] = {
12707 .mixers = { alc262_hp_t5735_mixer },
12708 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12709 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12710 .dac_nids = alc262_dac_nids,
12711 .hp_nid = 0x03,
12712 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12713 .channel_mode = alc262_modes,
12714 .input_mux = &alc262_capture_source,
dc99be47 12715 .unsol_event = alc_sku_unsol_event,
4f5d1706 12716 .setup = alc262_hp_t5735_setup,
dc99be47 12717 .init_hook = alc_inithook,
8c427226
KY
12718 },
12719 [ALC262_HP_RP5700] = {
12720 .mixers = { alc262_hp_rp5700_mixer },
12721 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12722 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12723 .dac_nids = alc262_dac_nids,
12724 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12725 .channel_mode = alc262_modes,
12726 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12727 },
304dcaac
TI
12728 [ALC262_BENQ_ED8] = {
12729 .mixers = { alc262_base_mixer },
12730 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12731 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12732 .dac_nids = alc262_dac_nids,
12733 .hp_nid = 0x03,
12734 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12735 .channel_mode = alc262_modes,
12736 .input_mux = &alc262_capture_source,
f12ab1e0 12737 },
272a527c
KY
12738 [ALC262_SONY_ASSAMD] = {
12739 .mixers = { alc262_sony_mixer },
12740 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12741 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12742 .dac_nids = alc262_dac_nids,
12743 .hp_nid = 0x02,
12744 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12745 .channel_mode = alc262_modes,
12746 .input_mux = &alc262_capture_source,
12747 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12748 .setup = alc262_hippo_setup,
12749 .init_hook = alc262_hippo_automute,
83c34218
KY
12750 },
12751 [ALC262_BENQ_T31] = {
12752 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12753 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12754 alc_hp15_unsol_verbs },
83c34218
KY
12755 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12756 .dac_nids = alc262_dac_nids,
12757 .hp_nid = 0x03,
12758 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12759 .channel_mode = alc262_modes,
12760 .input_mux = &alc262_capture_source,
12761 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12762 .setup = alc262_hippo_setup,
12763 .init_hook = alc262_hippo_automute,
ea1fb29a 12764 },
f651b50b 12765 [ALC262_ULTRA] = {
f9e336f6
TI
12766 .mixers = { alc262_ultra_mixer },
12767 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12768 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12769 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12770 .dac_nids = alc262_dac_nids,
f651b50b
TD
12771 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12772 .channel_mode = alc262_modes,
12773 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12774 .adc_nids = alc262_adc_nids, /* ADC0 */
12775 .capsrc_nids = alc262_capsrc_nids,
12776 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12777 .unsol_event = alc262_ultra_unsol_event,
12778 .init_hook = alc262_ultra_automute,
12779 },
0e31daf7
J
12780 [ALC262_LENOVO_3000] = {
12781 .mixers = { alc262_lenovo_3000_mixer },
12782 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12783 alc262_lenovo_3000_unsol_verbs,
12784 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12785 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12786 .dac_nids = alc262_dac_nids,
12787 .hp_nid = 0x03,
12788 .dig_out_nid = ALC262_DIGOUT_NID,
12789 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12790 .channel_mode = alc262_modes,
12791 .input_mux = &alc262_fujitsu_capture_source,
12792 .unsol_event = alc262_lenovo_3000_unsol_event,
12793 },
e8f9ae2a
PT
12794 [ALC262_NEC] = {
12795 .mixers = { alc262_nec_mixer },
12796 .init_verbs = { alc262_nec_verbs },
12797 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12798 .dac_nids = alc262_dac_nids,
12799 .hp_nid = 0x03,
12800 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12801 .channel_mode = alc262_modes,
12802 .input_mux = &alc262_capture_source,
12803 },
4e555fe5
KY
12804 [ALC262_TOSHIBA_S06] = {
12805 .mixers = { alc262_toshiba_s06_mixer },
12806 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12807 alc262_eapd_verbs },
12808 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12809 .capsrc_nids = alc262_dmic_capsrc_nids,
12810 .dac_nids = alc262_dac_nids,
12811 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12812 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12813 .dig_out_nid = ALC262_DIGOUT_NID,
12814 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12815 .channel_mode = alc262_modes,
4f5d1706
TI
12816 .unsol_event = alc_sku_unsol_event,
12817 .setup = alc262_toshiba_s06_setup,
12818 .init_hook = alc_inithook,
4e555fe5 12819 },
9f99a638
HM
12820 [ALC262_TOSHIBA_RX1] = {
12821 .mixers = { alc262_toshiba_rx1_mixer },
12822 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12823 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12824 .dac_nids = alc262_dac_nids,
12825 .hp_nid = 0x03,
12826 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12827 .channel_mode = alc262_modes,
12828 .input_mux = &alc262_capture_source,
12829 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12830 .setup = alc262_hippo_setup,
12831 .init_hook = alc262_hippo_automute,
9f99a638 12832 },
ba340e82
TV
12833 [ALC262_TYAN] = {
12834 .mixers = { alc262_tyan_mixer },
12835 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12836 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12837 .dac_nids = alc262_dac_nids,
12838 .hp_nid = 0x02,
12839 .dig_out_nid = ALC262_DIGOUT_NID,
12840 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12841 .channel_mode = alc262_modes,
12842 .input_mux = &alc262_capture_source,
a9fd4f3f 12843 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12844 .setup = alc262_tyan_setup,
12845 .init_hook = alc_automute_amp,
ba340e82 12846 },
df694daa
KY
12847};
12848
12849static int patch_alc262(struct hda_codec *codec)
12850{
12851 struct alc_spec *spec;
12852 int board_config;
12853 int err;
12854
dc041e0b 12855 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12856 if (spec == NULL)
12857 return -ENOMEM;
12858
12859 codec->spec = spec;
12860#if 0
f12ab1e0
TI
12861 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12862 * under-run
12863 */
df694daa
KY
12864 {
12865 int tmp;
12866 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12867 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12868 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12869 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12870 }
12871#endif
da00c244 12872 alc_auto_parse_customize_define(codec);
df694daa 12873
2c3bf9ab
TI
12874 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12875
f5fcc13c
TI
12876 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12877 alc262_models,
12878 alc262_cfg_tbl);
cd7509a4 12879
f5fcc13c 12880 if (board_config < 0) {
9a11f1aa
TI
12881 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12882 codec->chip_name);
df694daa
KY
12883 board_config = ALC262_AUTO;
12884 }
12885
18675e42
TI
12886 if (board_config == ALC262_AUTO)
12887 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1);
12888
df694daa
KY
12889 if (board_config == ALC262_AUTO) {
12890 /* automatic parse from the BIOS config */
12891 err = alc262_parse_auto_config(codec);
12892 if (err < 0) {
12893 alc_free(codec);
12894 return err;
f12ab1e0 12895 } else if (!err) {
9c7f852e
TI
12896 printk(KERN_INFO
12897 "hda_codec: Cannot set up configuration "
12898 "from BIOS. Using base mode...\n");
df694daa
KY
12899 board_config = ALC262_BASIC;
12900 }
12901 }
12902
dc1eae25 12903 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12904 err = snd_hda_attach_beep_device(codec, 0x1);
12905 if (err < 0) {
12906 alc_free(codec);
12907 return err;
12908 }
680cd536
KK
12909 }
12910
df694daa 12911 if (board_config != ALC262_AUTO)
e9c364c0 12912 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12913
df694daa
KY
12914 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12915 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12916
df694daa
KY
12917 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12918 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12919
f12ab1e0 12920 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12921 int i;
12922 /* check whether the digital-mic has to be supported */
12923 for (i = 0; i < spec->input_mux->num_items; i++) {
12924 if (spec->input_mux->items[i].index >= 9)
12925 break;
12926 }
12927 if (i < spec->input_mux->num_items) {
12928 /* use only ADC0 */
12929 spec->adc_nids = alc262_dmic_adc_nids;
12930 spec->num_adc_nids = 1;
12931 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12932 } else {
8c927b4a
TI
12933 /* all analog inputs */
12934 /* check whether NID 0x07 is valid */
12935 unsigned int wcap = get_wcaps(codec, 0x07);
12936
12937 /* get type */
a22d543a 12938 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12939 if (wcap != AC_WID_AUD_IN) {
12940 spec->adc_nids = alc262_adc_nids_alt;
12941 spec->num_adc_nids =
12942 ARRAY_SIZE(alc262_adc_nids_alt);
12943 spec->capsrc_nids = alc262_capsrc_nids_alt;
12944 } else {
12945 spec->adc_nids = alc262_adc_nids;
12946 spec->num_adc_nids =
12947 ARRAY_SIZE(alc262_adc_nids);
12948 spec->capsrc_nids = alc262_capsrc_nids;
12949 }
df694daa
KY
12950 }
12951 }
e64f14f4 12952 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12953 set_capture_mixer(codec);
dc1eae25 12954 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12955 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12956
18675e42
TI
12957 if (board_config == ALC262_AUTO)
12958 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0);
12959
2134ea4f
TI
12960 spec->vmaster_nid = 0x0c;
12961
df694daa
KY
12962 codec->patch_ops = alc_patch_ops;
12963 if (board_config == ALC262_AUTO)
ae6b813a 12964 spec->init_hook = alc262_auto_init;
bf1b0225
KY
12965
12966 alc_init_jacks(codec);
cb53c626
TI
12967#ifdef CONFIG_SND_HDA_POWER_SAVE
12968 if (!spec->loopback.amplist)
12969 spec->loopback.amplist = alc262_loopbacks;
12970#endif
ea1fb29a 12971
df694daa
KY
12972 return 0;
12973}
12974
a361d84b
KY
12975/*
12976 * ALC268 channel source setting (2 channel)
12977 */
12978#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12979#define alc268_modes alc260_modes
ea1fb29a 12980
a361d84b
KY
12981static hda_nid_t alc268_dac_nids[2] = {
12982 /* front, hp */
12983 0x02, 0x03
12984};
12985
12986static hda_nid_t alc268_adc_nids[2] = {
12987 /* ADC0-1 */
12988 0x08, 0x07
12989};
12990
12991static hda_nid_t alc268_adc_nids_alt[1] = {
12992 /* ADC0 */
12993 0x08
12994};
12995
e1406348
TI
12996static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12997
a361d84b
KY
12998static struct snd_kcontrol_new alc268_base_mixer[] = {
12999 /* output mixer control */
13000 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13001 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13002 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13004 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13005 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13006 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13007 { }
13008};
13009
42171c17
TI
13010static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13011 /* output mixer control */
13012 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13013 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13014 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13015 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13016 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13017 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13018 { }
13019};
13020
aef9d318
TI
13021/* bind Beep switches of both NID 0x0f and 0x10 */
13022static struct hda_bind_ctls alc268_bind_beep_sw = {
13023 .ops = &snd_hda_bind_sw,
13024 .values = {
13025 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13026 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13027 0
13028 },
13029};
13030
13031static struct snd_kcontrol_new alc268_beep_mixer[] = {
13032 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13033 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13034 { }
13035};
13036
d1a991a6
KY
13037static struct hda_verb alc268_eapd_verbs[] = {
13038 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13039 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13040 { }
13041};
13042
d273809e 13043/* Toshiba specific */
d273809e
TI
13044static struct hda_verb alc268_toshiba_verbs[] = {
13045 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13046 { } /* end */
13047};
13048
13049/* Acer specific */
889c4395 13050/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13051static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13052 .ops = &snd_hda_bind_vol,
13053 .values = {
13054 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13055 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13056 0
13057 },
13058};
13059
889c4395
TI
13060/* mute/unmute internal speaker according to the hp jack and mute state */
13061static void alc268_acer_automute(struct hda_codec *codec, int force)
13062{
13063 struct alc_spec *spec = codec->spec;
13064 unsigned int mute;
13065
13066 if (force || !spec->sense_updated) {
864f92be 13067 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
13068 spec->sense_updated = 1;
13069 }
13070 if (spec->jack_present)
13071 mute = HDA_AMP_MUTE; /* mute internal speaker */
13072 else /* unmute internal speaker if necessary */
13073 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13074 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13075 HDA_AMP_MUTE, mute);
13076}
13077
13078
13079/* bind hp and internal speaker mute (with plug check) */
13080static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13081 struct snd_ctl_elem_value *ucontrol)
13082{
13083 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13084 long *valp = ucontrol->value.integer.value;
13085 int change;
13086
8de56b7d 13087 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13088 if (change)
13089 alc268_acer_automute(codec, 0);
13090 return change;
13091}
d273809e 13092
8ef355da
KY
13093static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13094 /* output mixer control */
13095 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13096 {
13097 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13098 .name = "Master Playback Switch",
5e26dfd0 13099 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13100 .info = snd_hda_mixer_amp_switch_info,
13101 .get = snd_hda_mixer_amp_switch_get,
13102 .put = alc268_acer_master_sw_put,
13103 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13104 },
13105 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13106 { }
13107};
13108
d273809e
TI
13109static struct snd_kcontrol_new alc268_acer_mixer[] = {
13110 /* output mixer control */
13111 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13112 {
13113 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13114 .name = "Master Playback Switch",
5e26dfd0 13115 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13116 .info = snd_hda_mixer_amp_switch_info,
13117 .get = snd_hda_mixer_amp_switch_get,
13118 .put = alc268_acer_master_sw_put,
13119 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13120 },
5f99f86a
DH
13121 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13122 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13123 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13124 { }
13125};
13126
c238b4f4
TI
13127static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13128 /* output mixer control */
13129 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13130 {
13131 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13132 .name = "Master Playback Switch",
5e26dfd0 13133 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13134 .info = snd_hda_mixer_amp_switch_info,
13135 .get = snd_hda_mixer_amp_switch_get,
13136 .put = alc268_acer_master_sw_put,
13137 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13138 },
5f99f86a
DH
13139 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13140 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13141 { }
13142};
13143
8ef355da
KY
13144static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13145 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13146 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13147 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13148 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13149 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13150 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13151 { }
13152};
13153
d273809e 13154static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13155 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13156 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13157 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13158 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13159 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13160 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13161 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13162 { }
13163};
13164
13165/* unsolicited event for HP jack sensing */
42171c17 13166#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13167#define alc268_toshiba_setup alc262_hippo_setup
13168#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13169
13170static void alc268_acer_unsol_event(struct hda_codec *codec,
13171 unsigned int res)
13172{
889c4395 13173 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13174 return;
13175 alc268_acer_automute(codec, 1);
13176}
13177
889c4395
TI
13178static void alc268_acer_init_hook(struct hda_codec *codec)
13179{
13180 alc268_acer_automute(codec, 1);
13181}
13182
8ef355da
KY
13183/* toggle speaker-output according to the hp-jack state */
13184static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13185{
13186 unsigned int present;
13187 unsigned char bits;
13188
864f92be 13189 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13190 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13191 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13192 HDA_AMP_MUTE, bits);
8ef355da 13193 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13194 HDA_AMP_MUTE, bits);
8ef355da
KY
13195}
13196
8ef355da
KY
13197static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13198 unsigned int res)
13199{
4f5d1706
TI
13200 switch (res >> 26) {
13201 case ALC880_HP_EVENT:
8ef355da 13202 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13203 break;
13204 case ALC880_MIC_EVENT:
13205 alc_mic_automute(codec);
13206 break;
13207 }
13208}
13209
13210static void alc268_acer_lc_setup(struct hda_codec *codec)
13211{
13212 struct alc_spec *spec = codec->spec;
13213 spec->ext_mic.pin = 0x18;
13214 spec->ext_mic.mux_idx = 0;
13215 spec->int_mic.pin = 0x12;
13216 spec->int_mic.mux_idx = 6;
13217 spec->auto_mic = 1;
8ef355da
KY
13218}
13219
13220static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13221{
13222 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13223 alc_mic_automute(codec);
8ef355da
KY
13224}
13225
3866f0b0
TI
13226static struct snd_kcontrol_new alc268_dell_mixer[] = {
13227 /* output mixer control */
13228 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13229 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13230 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13232 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13233 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13234 { }
13235};
13236
13237static struct hda_verb alc268_dell_verbs[] = {
13238 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13239 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13240 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13241 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13242 { }
13243};
13244
13245/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13246static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13247{
a9fd4f3f 13248 struct alc_spec *spec = codec->spec;
3866f0b0 13249
a9fd4f3f
TI
13250 spec->autocfg.hp_pins[0] = 0x15;
13251 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13252 spec->ext_mic.pin = 0x18;
13253 spec->ext_mic.mux_idx = 0;
13254 spec->int_mic.pin = 0x19;
13255 spec->int_mic.mux_idx = 1;
13256 spec->auto_mic = 1;
3866f0b0
TI
13257}
13258
eb5a6621
HRK
13259static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13260 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13261 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13262 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13263 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13264 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13265 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13266 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13267 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13268 { }
13269};
13270
13271static struct hda_verb alc267_quanta_il1_verbs[] = {
13272 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13273 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13274 { }
13275};
13276
4f5d1706 13277static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13278{
a9fd4f3f 13279 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13280 spec->autocfg.hp_pins[0] = 0x15;
13281 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13282 spec->ext_mic.pin = 0x18;
13283 spec->ext_mic.mux_idx = 0;
13284 spec->int_mic.pin = 0x19;
13285 spec->int_mic.mux_idx = 1;
13286 spec->auto_mic = 1;
eb5a6621
HRK
13287}
13288
a361d84b
KY
13289/*
13290 * generic initialization of ADC, input mixers and output mixers
13291 */
13292static struct hda_verb alc268_base_init_verbs[] = {
13293 /* Unmute DAC0-1 and set vol = 0 */
13294 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13295 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13296
13297 /*
13298 * Set up output mixers (0x0c - 0x0e)
13299 */
13300 /* set vol=0 to output mixers */
13301 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13302 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13303
13304 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13305 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13306
13307 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13308 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13309 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13310 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13311 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13313 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13314 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13315
13316 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13317 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13318 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13319 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13320 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13321
13322 /* set PCBEEP vol = 0, mute connections */
13323 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13324 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13325 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13326
a9b3aa8a 13327 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13328
a9b3aa8a
JZ
13329 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13330 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13331 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13332 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13333
a361d84b
KY
13334 { }
13335};
13336
13337/*
13338 * generic initialization of ADC, input mixers and output mixers
13339 */
13340static struct hda_verb alc268_volume_init_verbs[] = {
13341 /* set output DAC */
4cfb91c6
TI
13342 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13343 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13344
13345 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13346 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13347 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13348 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13349 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13350
a361d84b 13351 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13352 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13353 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13354
13355 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13356 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13357
aef9d318
TI
13358 /* set PCBEEP vol = 0, mute connections */
13359 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13360 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13361 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13362
13363 { }
13364};
13365
fdbc6626
TI
13366static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13367 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13368 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13369 { } /* end */
13370};
13371
a361d84b
KY
13372static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13373 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13374 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13375 _DEFINE_CAPSRC(1),
a361d84b
KY
13376 { } /* end */
13377};
13378
13379static struct snd_kcontrol_new alc268_capture_mixer[] = {
13380 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13381 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13382 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13383 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13384 _DEFINE_CAPSRC(2),
a361d84b
KY
13385 { } /* end */
13386};
13387
13388static struct hda_input_mux alc268_capture_source = {
13389 .num_items = 4,
13390 .items = {
13391 { "Mic", 0x0 },
13392 { "Front Mic", 0x1 },
13393 { "Line", 0x2 },
13394 { "CD", 0x3 },
13395 },
13396};
13397
0ccb541c 13398static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13399 .num_items = 3,
13400 .items = {
13401 { "Mic", 0x0 },
13402 { "Internal Mic", 0x1 },
13403 { "Line", 0x2 },
13404 },
13405};
13406
13407static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13408 .num_items = 3,
13409 .items = {
13410 { "Mic", 0x0 },
13411 { "Internal Mic", 0x6 },
13412 { "Line", 0x2 },
13413 },
13414};
13415
86c53bd2
JW
13416#ifdef CONFIG_SND_DEBUG
13417static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13418 /* Volume widgets */
13419 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13420 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13421 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13422 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13423 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13424 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13425 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13426 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13427 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13428 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13429 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13430 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13431 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13432 /* The below appears problematic on some hardwares */
13433 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13434 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13435 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13436 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13437 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13438
13439 /* Modes for retasking pin widgets */
13440 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13441 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13442 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13443 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13444
13445 /* Controls for GPIO pins, assuming they are configured as outputs */
13446 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13447 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13448 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13449 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13450
13451 /* Switches to allow the digital SPDIF output pin to be enabled.
13452 * The ALC268 does not have an SPDIF input.
13453 */
13454 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13455
13456 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13457 * this output to turn on an external amplifier.
13458 */
13459 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13460 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13461
13462 { } /* end */
13463};
13464#endif
13465
a361d84b
KY
13466/* create input playback/capture controls for the given pin */
13467static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13468 const char *ctlname, int idx)
13469{
3f3b7c1a 13470 hda_nid_t dac;
a361d84b
KY
13471 int err;
13472
3f3b7c1a
TI
13473 switch (nid) {
13474 case 0x14:
13475 case 0x16:
13476 dac = 0x02;
13477 break;
13478 case 0x15:
b08b1637
TI
13479 case 0x1a: /* ALC259/269 only */
13480 case 0x1b: /* ALC259/269 only */
531d8791 13481 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13482 dac = 0x03;
13483 break;
13484 default:
c7a9434d
TI
13485 snd_printd(KERN_WARNING "hda_codec: "
13486 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13487 return 0;
13488 }
13489 if (spec->multiout.dac_nids[0] != dac &&
13490 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13491 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13492 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13493 HDA_OUTPUT));
13494 if (err < 0)
13495 return err;
3f3b7c1a
TI
13496 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13497 }
13498
3f3b7c1a 13499 if (nid != 0x16)
0afe5f89 13500 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13501 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13502 else /* mono */
0afe5f89 13503 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13504 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13505 if (err < 0)
13506 return err;
13507 return 0;
13508}
13509
13510/* add playback controls from the parsed DAC table */
13511static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13512 const struct auto_pin_cfg *cfg)
13513{
13514 hda_nid_t nid;
13515 int err;
13516
a361d84b 13517 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13518
13519 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13520 if (nid) {
13521 const char *name;
13522 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13523 name = "Speaker";
13524 else
13525 name = "Front";
13526 err = alc268_new_analog_output(spec, nid, name, 0);
13527 if (err < 0)
13528 return err;
13529 }
a361d84b
KY
13530
13531 nid = cfg->speaker_pins[0];
13532 if (nid == 0x1d) {
0afe5f89 13533 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13534 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13535 if (err < 0)
13536 return err;
7bfb9c03 13537 } else if (nid) {
3f3b7c1a
TI
13538 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13539 if (err < 0)
13540 return err;
a361d84b
KY
13541 }
13542 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13543 if (nid) {
13544 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13545 if (err < 0)
13546 return err;
13547 }
a361d84b
KY
13548
13549 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13550 if (nid == 0x16) {
0afe5f89 13551 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13552 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13553 if (err < 0)
13554 return err;
13555 }
ea1fb29a 13556 return 0;
a361d84b
KY
13557}
13558
13559/* create playback/capture controls for input pins */
05f5f477 13560static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13561 const struct auto_pin_cfg *cfg)
13562{
05f5f477 13563 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13564}
13565
e9af4f36
TI
13566static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13567 hda_nid_t nid, int pin_type)
13568{
13569 int idx;
13570
13571 alc_set_pin_output(codec, nid, pin_type);
13572 if (nid == 0x14 || nid == 0x16)
13573 idx = 0;
13574 else
13575 idx = 1;
13576 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13577}
13578
13579static void alc268_auto_init_multi_out(struct hda_codec *codec)
13580{
13581 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13582 int i;
13583
13584 for (i = 0; i < spec->autocfg.line_outs; i++) {
13585 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13586 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13587 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13588 }
13589}
13590
13591static void alc268_auto_init_hp_out(struct hda_codec *codec)
13592{
13593 struct alc_spec *spec = codec->spec;
13594 hda_nid_t pin;
e1ca7b4e 13595 int i;
e9af4f36 13596
e1ca7b4e
TI
13597 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13598 pin = spec->autocfg.hp_pins[i];
e9af4f36 13599 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13600 }
13601 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13602 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13603 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13604 }
13605 if (spec->autocfg.mono_out_pin)
13606 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13607 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13608}
13609
a361d84b
KY
13610static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13611{
13612 struct alc_spec *spec = codec->spec;
13613 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13614 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13615 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13616 unsigned int dac_vol1, dac_vol2;
13617
e9af4f36 13618 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13619 snd_hda_codec_write(codec, speaker_nid, 0,
13620 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13621 /* mute mixer inputs from 0x1d */
a361d84b
KY
13622 snd_hda_codec_write(codec, 0x0f, 0,
13623 AC_VERB_SET_AMP_GAIN_MUTE,
13624 AMP_IN_UNMUTE(1));
13625 snd_hda_codec_write(codec, 0x10, 0,
13626 AC_VERB_SET_AMP_GAIN_MUTE,
13627 AMP_IN_UNMUTE(1));
13628 } else {
e9af4f36 13629 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13630 snd_hda_codec_write(codec, 0x0f, 0,
13631 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13632 snd_hda_codec_write(codec, 0x10, 0,
13633 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13634 }
13635
13636 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13637 if (line_nid == 0x14)
a361d84b
KY
13638 dac_vol2 = AMP_OUT_ZERO;
13639 else if (line_nid == 0x15)
13640 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13641 if (hp_nid == 0x14)
a361d84b
KY
13642 dac_vol2 = AMP_OUT_ZERO;
13643 else if (hp_nid == 0x15)
13644 dac_vol1 = AMP_OUT_ZERO;
13645 if (line_nid != 0x16 || hp_nid != 0x16 ||
13646 spec->autocfg.line_out_pins[1] != 0x16 ||
13647 spec->autocfg.line_out_pins[2] != 0x16)
13648 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13649
13650 snd_hda_codec_write(codec, 0x02, 0,
13651 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13652 snd_hda_codec_write(codec, 0x03, 0,
13653 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13654}
13655
def319f9 13656/* pcm configuration: identical with ALC880 */
a361d84b
KY
13657#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13658#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13659#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13660#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13661
13662/*
13663 * BIOS auto configuration
13664 */
13665static int alc268_parse_auto_config(struct hda_codec *codec)
13666{
13667 struct alc_spec *spec = codec->spec;
13668 int err;
13669 static hda_nid_t alc268_ignore[] = { 0 };
13670
13671 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13672 alc268_ignore);
13673 if (err < 0)
13674 return err;
7e0e44d4
TI
13675 if (!spec->autocfg.line_outs) {
13676 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13677 spec->multiout.max_channels = 2;
13678 spec->no_analog = 1;
13679 goto dig_only;
13680 }
a361d84b 13681 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13682 }
a361d84b
KY
13683 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13684 if (err < 0)
13685 return err;
05f5f477 13686 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13687 if (err < 0)
13688 return err;
13689
13690 spec->multiout.max_channels = 2;
13691
7e0e44d4 13692 dig_only:
a361d84b 13693 /* digital only support output */
757899ac 13694 alc_auto_parse_digital(codec);
603c4019 13695 if (spec->kctls.list)
d88897ea 13696 add_mixer(spec, spec->kctls.list);
a361d84b 13697
892981ff 13698 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13699 add_mixer(spec, alc268_beep_mixer);
aef9d318 13700
d88897ea 13701 add_verb(spec, alc268_volume_init_verbs);
5908589f 13702 spec->num_mux_defs = 2;
61b9b9b1 13703 spec->input_mux = &spec->private_imux[0];
a361d84b 13704
776e184e
TI
13705 err = alc_auto_add_mic_boost(codec);
13706 if (err < 0)
13707 return err;
13708
6227cdce 13709 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13710
a361d84b
KY
13711 return 1;
13712}
13713
a361d84b
KY
13714#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13715
13716/* init callback for auto-configuration model -- overriding the default init */
13717static void alc268_auto_init(struct hda_codec *codec)
13718{
f6c7e546 13719 struct alc_spec *spec = codec->spec;
a361d84b
KY
13720 alc268_auto_init_multi_out(codec);
13721 alc268_auto_init_hp_out(codec);
13722 alc268_auto_init_mono_speaker_out(codec);
13723 alc268_auto_init_analog_input(codec);
757899ac 13724 alc_auto_init_digital(codec);
f6c7e546 13725 if (spec->unsol_event)
7fb0d78f 13726 alc_inithook(codec);
a361d84b
KY
13727}
13728
13729/*
13730 * configuration and preset
13731 */
13732static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13733 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13734 [ALC268_3ST] = "3stack",
983f8ae4 13735 [ALC268_TOSHIBA] = "toshiba",
d273809e 13736 [ALC268_ACER] = "acer",
c238b4f4 13737 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13738 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13739 [ALC268_DELL] = "dell",
f12462c5 13740 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13741#ifdef CONFIG_SND_DEBUG
13742 [ALC268_TEST] = "test",
13743#endif
a361d84b
KY
13744 [ALC268_AUTO] = "auto",
13745};
13746
13747static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13748 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13749 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13750 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13751 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13752 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13753 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13754 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13755 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13756 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13757 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13758 /* almost compatible with toshiba but with optional digital outs;
13759 * auto-probing seems working fine
13760 */
8871e5b9 13761 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13762 ALC268_AUTO),
a361d84b 13763 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13764 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13765 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13766 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13767 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13768 {}
13769};
13770
3abf2f36
TI
13771/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13772static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13773 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13774 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13775 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13776 ALC268_TOSHIBA),
13777 {}
13778};
13779
a361d84b 13780static struct alc_config_preset alc268_presets[] = {
eb5a6621 13781 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13782 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13783 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13784 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13785 alc267_quanta_il1_verbs },
13786 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13787 .dac_nids = alc268_dac_nids,
13788 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13789 .adc_nids = alc268_adc_nids_alt,
13790 .hp_nid = 0x03,
13791 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13792 .channel_mode = alc268_modes,
4f5d1706
TI
13793 .unsol_event = alc_sku_unsol_event,
13794 .setup = alc267_quanta_il1_setup,
13795 .init_hook = alc_inithook,
eb5a6621 13796 },
a361d84b 13797 [ALC268_3ST] = {
aef9d318
TI
13798 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13799 alc268_beep_mixer },
a361d84b
KY
13800 .init_verbs = { alc268_base_init_verbs },
13801 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13802 .dac_nids = alc268_dac_nids,
13803 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13804 .adc_nids = alc268_adc_nids_alt,
e1406348 13805 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13806 .hp_nid = 0x03,
13807 .dig_out_nid = ALC268_DIGOUT_NID,
13808 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13809 .channel_mode = alc268_modes,
13810 .input_mux = &alc268_capture_source,
13811 },
d1a991a6 13812 [ALC268_TOSHIBA] = {
42171c17 13813 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13814 alc268_beep_mixer },
d273809e
TI
13815 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13816 alc268_toshiba_verbs },
d1a991a6
KY
13817 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13818 .dac_nids = alc268_dac_nids,
13819 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13820 .adc_nids = alc268_adc_nids_alt,
e1406348 13821 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13822 .hp_nid = 0x03,
13823 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13824 .channel_mode = alc268_modes,
13825 .input_mux = &alc268_capture_source,
d273809e 13826 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13827 .setup = alc268_toshiba_setup,
13828 .init_hook = alc268_toshiba_automute,
d273809e
TI
13829 },
13830 [ALC268_ACER] = {
432fd133 13831 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13832 alc268_beep_mixer },
d273809e
TI
13833 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13834 alc268_acer_verbs },
13835 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13836 .dac_nids = alc268_dac_nids,
13837 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13838 .adc_nids = alc268_adc_nids_alt,
e1406348 13839 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13840 .hp_nid = 0x02,
13841 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13842 .channel_mode = alc268_modes,
0ccb541c 13843 .input_mux = &alc268_acer_capture_source,
d273809e 13844 .unsol_event = alc268_acer_unsol_event,
889c4395 13845 .init_hook = alc268_acer_init_hook,
d1a991a6 13846 },
c238b4f4
TI
13847 [ALC268_ACER_DMIC] = {
13848 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13849 alc268_beep_mixer },
13850 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13851 alc268_acer_verbs },
13852 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13853 .dac_nids = alc268_dac_nids,
13854 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13855 .adc_nids = alc268_adc_nids_alt,
13856 .capsrc_nids = alc268_capsrc_nids,
13857 .hp_nid = 0x02,
13858 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13859 .channel_mode = alc268_modes,
13860 .input_mux = &alc268_acer_dmic_capture_source,
13861 .unsol_event = alc268_acer_unsol_event,
13862 .init_hook = alc268_acer_init_hook,
13863 },
8ef355da
KY
13864 [ALC268_ACER_ASPIRE_ONE] = {
13865 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13866 alc268_beep_mixer,
fdbc6626 13867 alc268_capture_nosrc_mixer },
8ef355da
KY
13868 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13869 alc268_acer_aspire_one_verbs },
13870 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13871 .dac_nids = alc268_dac_nids,
13872 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13873 .adc_nids = alc268_adc_nids_alt,
13874 .capsrc_nids = alc268_capsrc_nids,
13875 .hp_nid = 0x03,
13876 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13877 .channel_mode = alc268_modes,
8ef355da 13878 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13879 .setup = alc268_acer_lc_setup,
8ef355da
KY
13880 .init_hook = alc268_acer_lc_init_hook,
13881 },
3866f0b0 13882 [ALC268_DELL] = {
fdbc6626
TI
13883 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13884 alc268_capture_nosrc_mixer },
3866f0b0
TI
13885 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13886 alc268_dell_verbs },
13887 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13888 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13889 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13890 .adc_nids = alc268_adc_nids_alt,
13891 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13892 .hp_nid = 0x02,
13893 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13894 .channel_mode = alc268_modes,
a9fd4f3f 13895 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13896 .setup = alc268_dell_setup,
13897 .init_hook = alc_inithook,
3866f0b0 13898 },
f12462c5 13899 [ALC268_ZEPTO] = {
aef9d318
TI
13900 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13901 alc268_beep_mixer },
f12462c5
MT
13902 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13903 alc268_toshiba_verbs },
13904 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13905 .dac_nids = alc268_dac_nids,
13906 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13907 .adc_nids = alc268_adc_nids_alt,
e1406348 13908 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13909 .hp_nid = 0x03,
13910 .dig_out_nid = ALC268_DIGOUT_NID,
13911 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13912 .channel_mode = alc268_modes,
13913 .input_mux = &alc268_capture_source,
4f5d1706
TI
13914 .setup = alc268_toshiba_setup,
13915 .init_hook = alc268_toshiba_automute,
f12462c5 13916 },
86c53bd2
JW
13917#ifdef CONFIG_SND_DEBUG
13918 [ALC268_TEST] = {
13919 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13920 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13921 alc268_volume_init_verbs },
13922 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13923 .dac_nids = alc268_dac_nids,
13924 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13925 .adc_nids = alc268_adc_nids_alt,
e1406348 13926 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13927 .hp_nid = 0x03,
13928 .dig_out_nid = ALC268_DIGOUT_NID,
13929 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13930 .channel_mode = alc268_modes,
13931 .input_mux = &alc268_capture_source,
13932 },
13933#endif
a361d84b
KY
13934};
13935
13936static int patch_alc268(struct hda_codec *codec)
13937{
13938 struct alc_spec *spec;
13939 int board_config;
22971e3a 13940 int i, has_beep, err;
a361d84b 13941
ef86f581 13942 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13943 if (spec == NULL)
13944 return -ENOMEM;
13945
13946 codec->spec = spec;
13947
13948 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13949 alc268_models,
13950 alc268_cfg_tbl);
13951
3abf2f36
TI
13952 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13953 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13954 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13955
a361d84b 13956 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13957 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13958 codec->chip_name);
a361d84b
KY
13959 board_config = ALC268_AUTO;
13960 }
13961
13962 if (board_config == ALC268_AUTO) {
13963 /* automatic parse from the BIOS config */
13964 err = alc268_parse_auto_config(codec);
13965 if (err < 0) {
13966 alc_free(codec);
13967 return err;
13968 } else if (!err) {
13969 printk(KERN_INFO
13970 "hda_codec: Cannot set up configuration "
13971 "from BIOS. Using base mode...\n");
13972 board_config = ALC268_3ST;
13973 }
13974 }
13975
13976 if (board_config != ALC268_AUTO)
e9c364c0 13977 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13978
a361d84b
KY
13979 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13980 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13981 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13982
a361d84b
KY
13983 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13984
22971e3a
TI
13985 has_beep = 0;
13986 for (i = 0; i < spec->num_mixers; i++) {
13987 if (spec->mixers[i] == alc268_beep_mixer) {
13988 has_beep = 1;
13989 break;
13990 }
13991 }
13992
13993 if (has_beep) {
13994 err = snd_hda_attach_beep_device(codec, 0x1);
13995 if (err < 0) {
13996 alc_free(codec);
13997 return err;
13998 }
13999 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14000 /* override the amp caps for beep generator */
14001 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14002 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14003 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14004 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14005 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14006 }
aef9d318 14007
7e0e44d4 14008 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14009 /* check whether NID 0x07 is valid */
14010 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 14011 int i;
3866f0b0 14012
defb5ab2 14013 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14014 /* get type */
a22d543a 14015 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14016 if (spec->auto_mic ||
14017 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14018 spec->adc_nids = alc268_adc_nids_alt;
14019 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14020 if (spec->auto_mic)
14021 fixup_automic_adc(codec);
fdbc6626
TI
14022 if (spec->auto_mic || spec->input_mux->num_items == 1)
14023 add_mixer(spec, alc268_capture_nosrc_mixer);
14024 else
14025 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14026 } else {
14027 spec->adc_nids = alc268_adc_nids;
14028 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14029 add_mixer(spec, alc268_capture_mixer);
a361d84b 14030 }
85860c06
TI
14031 /* set default input source */
14032 for (i = 0; i < spec->num_adc_nids; i++)
14033 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14034 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
14035 i < spec->num_mux_defs ?
14036 spec->input_mux[i].items[0].index :
85860c06 14037 spec->input_mux->items[0].index);
a361d84b 14038 }
2134ea4f
TI
14039
14040 spec->vmaster_nid = 0x02;
14041
a361d84b
KY
14042 codec->patch_ops = alc_patch_ops;
14043 if (board_config == ALC268_AUTO)
14044 spec->init_hook = alc268_auto_init;
ea1fb29a 14045
bf1b0225
KY
14046 alc_init_jacks(codec);
14047
a361d84b
KY
14048 return 0;
14049}
14050
f6a92248
KY
14051/*
14052 * ALC269 channel source setting (2 channel)
14053 */
14054#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14055
14056#define alc269_dac_nids alc260_dac_nids
14057
14058static hda_nid_t alc269_adc_nids[1] = {
14059 /* ADC1 */
f53281e6
KY
14060 0x08,
14061};
14062
e01bf509
TI
14063static hda_nid_t alc269_capsrc_nids[1] = {
14064 0x23,
14065};
14066
84898e87
KY
14067static hda_nid_t alc269vb_adc_nids[1] = {
14068 /* ADC1 */
14069 0x09,
14070};
14071
14072static hda_nid_t alc269vb_capsrc_nids[1] = {
14073 0x22,
14074};
14075
6694635d
TI
14076static hda_nid_t alc269_adc_candidates[] = {
14077 0x08, 0x09, 0x07,
14078};
e01bf509 14079
f6a92248
KY
14080#define alc269_modes alc260_modes
14081#define alc269_capture_source alc880_lg_lw_capture_source
14082
14083static struct snd_kcontrol_new alc269_base_mixer[] = {
14084 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14085 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14086 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14087 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14088 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14089 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14090 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14091 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14092 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14093 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14094 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14095 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14096 { } /* end */
14097};
14098
60db6b53
KY
14099static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14100 /* output mixer control */
14101 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14102 {
14103 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14104 .name = "Master Playback Switch",
5e26dfd0 14105 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14106 .info = snd_hda_mixer_amp_switch_info,
14107 .get = snd_hda_mixer_amp_switch_get,
14108 .put = alc268_acer_master_sw_put,
14109 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14110 },
14111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14113 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14114 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14115 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14116 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14117 { }
14118};
14119
64154835
TV
14120static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14121 /* output mixer control */
14122 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14123 {
14124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14125 .name = "Master Playback Switch",
5e26dfd0 14126 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14127 .info = snd_hda_mixer_amp_switch_info,
14128 .get = snd_hda_mixer_amp_switch_get,
14129 .put = alc268_acer_master_sw_put,
14130 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14131 },
14132 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14133 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14134 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14135 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14136 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14137 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14138 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14139 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14140 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14141 { }
14142};
14143
84898e87 14144static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14145 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14146 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14147 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14148 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14149 { } /* end */
14150};
14151
84898e87
KY
14152static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14153 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14154 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14155 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14156 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14157 { } /* end */
14158};
14159
fe3eb0a7
KY
14160static struct snd_kcontrol_new alc269_asus_mixer[] = {
14161 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14162 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14163 { } /* end */
14164};
14165
f53281e6 14166/* capture mixer elements */
84898e87
KY
14167static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14168 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14169 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14170 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14171 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14172 { } /* end */
14173};
14174
14175static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14176 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14177 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14178 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14179 { } /* end */
14180};
14181
84898e87
KY
14182static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14183 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14184 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14185 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14186 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14187 { } /* end */
14188};
14189
14190static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14191 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14192 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14194 { } /* end */
14195};
14196
26f5df26 14197/* FSC amilo */
84898e87 14198#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14199
60db6b53
KY
14200static struct hda_verb alc269_quanta_fl1_verbs[] = {
14201 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14202 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14204 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14205 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14206 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14207 { }
14208};
f6a92248 14209
64154835
TV
14210static struct hda_verb alc269_lifebook_verbs[] = {
14211 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14212 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14213 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14214 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14215 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14216 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14217 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14218 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14219 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14220 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14221 { }
14222};
14223
60db6b53
KY
14224/* toggle speaker-output according to the hp-jack state */
14225static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14226{
14227 unsigned int present;
14228 unsigned char bits;
f6a92248 14229
864f92be 14230 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14231 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14232 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14233 HDA_AMP_MUTE, bits);
60db6b53 14234 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14235 HDA_AMP_MUTE, bits);
f6a92248 14236
60db6b53
KY
14237 snd_hda_codec_write(codec, 0x20, 0,
14238 AC_VERB_SET_COEF_INDEX, 0x0c);
14239 snd_hda_codec_write(codec, 0x20, 0,
14240 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14241
60db6b53
KY
14242 snd_hda_codec_write(codec, 0x20, 0,
14243 AC_VERB_SET_COEF_INDEX, 0x0c);
14244 snd_hda_codec_write(codec, 0x20, 0,
14245 AC_VERB_SET_PROC_COEF, 0x480);
14246}
f6a92248 14247
64154835
TV
14248/* toggle speaker-output according to the hp-jacks state */
14249static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14250{
14251 unsigned int present;
14252 unsigned char bits;
14253
14254 /* Check laptop headphone socket */
864f92be 14255 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14256
14257 /* Check port replicator headphone socket */
864f92be 14258 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14259
5dbd5ec6 14260 bits = present ? HDA_AMP_MUTE : 0;
64154835 14261 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14262 HDA_AMP_MUTE, bits);
64154835 14263 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14264 HDA_AMP_MUTE, bits);
64154835
TV
14265
14266 snd_hda_codec_write(codec, 0x20, 0,
14267 AC_VERB_SET_COEF_INDEX, 0x0c);
14268 snd_hda_codec_write(codec, 0x20, 0,
14269 AC_VERB_SET_PROC_COEF, 0x680);
14270
14271 snd_hda_codec_write(codec, 0x20, 0,
14272 AC_VERB_SET_COEF_INDEX, 0x0c);
14273 snd_hda_codec_write(codec, 0x20, 0,
14274 AC_VERB_SET_PROC_COEF, 0x480);
14275}
14276
64154835
TV
14277static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14278{
14279 unsigned int present_laptop;
14280 unsigned int present_dock;
14281
864f92be
WF
14282 present_laptop = snd_hda_jack_detect(codec, 0x18);
14283 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14284
14285 /* Laptop mic port overrides dock mic port, design decision */
14286 if (present_dock)
14287 snd_hda_codec_write(codec, 0x23, 0,
14288 AC_VERB_SET_CONNECT_SEL, 0x3);
14289 if (present_laptop)
14290 snd_hda_codec_write(codec, 0x23, 0,
14291 AC_VERB_SET_CONNECT_SEL, 0x0);
14292 if (!present_dock && !present_laptop)
14293 snd_hda_codec_write(codec, 0x23, 0,
14294 AC_VERB_SET_CONNECT_SEL, 0x1);
14295}
14296
60db6b53
KY
14297static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14298 unsigned int res)
14299{
4f5d1706
TI
14300 switch (res >> 26) {
14301 case ALC880_HP_EVENT:
60db6b53 14302 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14303 break;
14304 case ALC880_MIC_EVENT:
14305 alc_mic_automute(codec);
14306 break;
14307 }
60db6b53 14308}
f6a92248 14309
64154835
TV
14310static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14311 unsigned int res)
14312{
14313 if ((res >> 26) == ALC880_HP_EVENT)
14314 alc269_lifebook_speaker_automute(codec);
14315 if ((res >> 26) == ALC880_MIC_EVENT)
14316 alc269_lifebook_mic_autoswitch(codec);
14317}
14318
4f5d1706
TI
14319static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14320{
14321 struct alc_spec *spec = codec->spec;
20645d70
TI
14322 spec->autocfg.hp_pins[0] = 0x15;
14323 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14324 spec->ext_mic.pin = 0x18;
14325 spec->ext_mic.mux_idx = 0;
14326 spec->int_mic.pin = 0x19;
14327 spec->int_mic.mux_idx = 1;
14328 spec->auto_mic = 1;
14329}
14330
60db6b53
KY
14331static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14332{
14333 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14334 alc_mic_automute(codec);
60db6b53 14335}
f6a92248 14336
64154835
TV
14337static void alc269_lifebook_init_hook(struct hda_codec *codec)
14338{
14339 alc269_lifebook_speaker_automute(codec);
14340 alc269_lifebook_mic_autoswitch(codec);
14341}
14342
84898e87 14343static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14344 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14345 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14346 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14347 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14348 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14349 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14350 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14351 {}
14352};
14353
84898e87 14354static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14355 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14356 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14357 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14358 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14359 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14360 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14361 {}
14362};
14363
84898e87
KY
14364static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14365 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14366 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14367 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14368 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14369 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14370 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14371 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14372 {}
14373};
14374
14375static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14376 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14377 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14378 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14379 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14380 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14381 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14382 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14383 {}
14384};
14385
fe3eb0a7
KY
14386static struct hda_verb alc271_acer_dmic_verbs[] = {
14387 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14388 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14389 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14390 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14391 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14392 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14393 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14394 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14395 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14396 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14397 { }
14398};
14399
f53281e6
KY
14400/* toggle speaker-output according to the hp-jack state */
14401static void alc269_speaker_automute(struct hda_codec *codec)
14402{
ebb83eeb
KY
14403 struct alc_spec *spec = codec->spec;
14404 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14405 unsigned int present;
60db6b53 14406 unsigned char bits;
f53281e6 14407
ebb83eeb 14408 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14409 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14410 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14411 HDA_AMP_MUTE, bits);
f53281e6 14412 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14413 HDA_AMP_MUTE, bits);
bf1b0225 14414 alc_report_jack(codec, nid);
f53281e6
KY
14415}
14416
f53281e6 14417/* unsolicited event for HP jack sensing */
84898e87 14418static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14419 unsigned int res)
f53281e6 14420{
4f5d1706
TI
14421 switch (res >> 26) {
14422 case ALC880_HP_EVENT:
f53281e6 14423 alc269_speaker_automute(codec);
4f5d1706
TI
14424 break;
14425 case ALC880_MIC_EVENT:
14426 alc_mic_automute(codec);
14427 break;
14428 }
f53281e6
KY
14429}
14430
226b1ec8 14431static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14432{
4f5d1706 14433 struct alc_spec *spec = codec->spec;
20645d70
TI
14434 spec->autocfg.hp_pins[0] = 0x15;
14435 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14436 spec->ext_mic.pin = 0x18;
14437 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14438 spec->int_mic.pin = 0x19;
14439 spec->int_mic.mux_idx = 1;
4f5d1706 14440 spec->auto_mic = 1;
f53281e6
KY
14441}
14442
226b1ec8 14443static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14444{
14445 struct alc_spec *spec = codec->spec;
20645d70
TI
14446 spec->autocfg.hp_pins[0] = 0x15;
14447 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14448 spec->ext_mic.pin = 0x18;
14449 spec->ext_mic.mux_idx = 0;
14450 spec->int_mic.pin = 0x12;
226b1ec8 14451 spec->int_mic.mux_idx = 5;
84898e87
KY
14452 spec->auto_mic = 1;
14453}
14454
226b1ec8 14455static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14456{
4f5d1706 14457 struct alc_spec *spec = codec->spec;
226b1ec8 14458 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14459 spec->autocfg.speaker_pins[0] = 0x14;
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;
14472 spec->ext_mic.pin = 0x18;
14473 spec->ext_mic.mux_idx = 0;
14474 spec->int_mic.pin = 0x12;
14475 spec->int_mic.mux_idx = 6;
14476 spec->auto_mic = 1;
14477}
14478
84898e87 14479static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14480{
14481 alc269_speaker_automute(codec);
4f5d1706 14482 alc_mic_automute(codec);
f53281e6
KY
14483}
14484
60db6b53
KY
14485/*
14486 * generic initialization of ADC, input mixers and output mixers
14487 */
14488static struct hda_verb alc269_init_verbs[] = {
14489 /*
14490 * Unmute ADC0 and set the default input to mic-in
14491 */
84898e87 14492 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14493
14494 /*
84898e87 14495 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14496 */
14497 /* set vol=0 to output mixers */
14498 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14499 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14500
14501 /* set up input amps for analog loopback */
14502 /* Amp Indices: DAC = 0, mixer = 1 */
14503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14504 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14509
14510 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14511 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14512 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14513 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14514 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14515 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14517
14518 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14519 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14520
84898e87
KY
14521 /* FIXME: use Mux-type input source selection */
14522 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14523 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14524 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14525
84898e87
KY
14526 /* set EAPD */
14527 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14528 { }
14529};
14530
14531static struct hda_verb alc269vb_init_verbs[] = {
14532 /*
14533 * Unmute ADC0 and set the default input to mic-in
14534 */
14535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14536
14537 /*
14538 * Set up output mixers (0x02 - 0x03)
14539 */
14540 /* set vol=0 to output mixers */
14541 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14542 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14543
14544 /* set up input amps for analog loopback */
14545 /* Amp Indices: DAC = 0, mixer = 1 */
14546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14548 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14550 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14551 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14552
14553 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14554 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14555 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14556 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14557 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14558 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14559 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14560
14561 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14562 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14563
14564 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14565 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14566 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14567 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14568
14569 /* set EAPD */
14570 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14571 { }
14572};
14573
9d0b71b1
TI
14574#define alc269_auto_create_multi_out_ctls \
14575 alc268_auto_create_multi_out_ctls
05f5f477
TI
14576#define alc269_auto_create_input_ctls \
14577 alc268_auto_create_input_ctls
f6a92248
KY
14578
14579#ifdef CONFIG_SND_HDA_POWER_SAVE
14580#define alc269_loopbacks alc880_loopbacks
14581#endif
14582
def319f9 14583/* pcm configuration: identical with ALC880 */
f6a92248
KY
14584#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14585#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14586#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14587#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14588
f03d3115
TI
14589static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14590 .substreams = 1,
14591 .channels_min = 2,
14592 .channels_max = 8,
14593 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14594 /* NID is set in alc_build_pcms */
14595 .ops = {
14596 .open = alc880_playback_pcm_open,
14597 .prepare = alc880_playback_pcm_prepare,
14598 .cleanup = alc880_playback_pcm_cleanup
14599 },
14600};
14601
14602static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14603 .substreams = 1,
14604 .channels_min = 2,
14605 .channels_max = 2,
14606 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14607 /* NID is set in alc_build_pcms */
14608};
14609
ad35879a
TI
14610#ifdef CONFIG_SND_HDA_POWER_SAVE
14611static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14612{
14613 switch (codec->subsystem_id) {
14614 case 0x103c1586:
14615 return 1;
14616 }
14617 return 0;
14618}
14619
14620static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14621{
14622 /* update mute-LED according to the speaker mute state */
14623 if (nid == 0x01 || nid == 0x14) {
14624 int pinval;
14625 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14626 HDA_AMP_MUTE)
14627 pinval = 0x24;
14628 else
14629 pinval = 0x20;
14630 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14631 snd_hda_codec_update_cache(codec, 0x19, 0,
14632 AC_VERB_SET_PIN_WIDGET_CONTROL,
14633 pinval);
ad35879a
TI
14634 }
14635 return alc_check_power_status(codec, nid);
14636}
14637#endif /* CONFIG_SND_HDA_POWER_SAVE */
14638
840b64c0
TI
14639static int alc275_setup_dual_adc(struct hda_codec *codec)
14640{
14641 struct alc_spec *spec = codec->spec;
14642
14643 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14644 return 0;
14645 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14646 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14647 if (spec->ext_mic.pin <= 0x12) {
14648 spec->private_adc_nids[0] = 0x08;
14649 spec->private_adc_nids[1] = 0x11;
14650 spec->private_capsrc_nids[0] = 0x23;
14651 spec->private_capsrc_nids[1] = 0x22;
14652 } else {
14653 spec->private_adc_nids[0] = 0x11;
14654 spec->private_adc_nids[1] = 0x08;
14655 spec->private_capsrc_nids[0] = 0x22;
14656 spec->private_capsrc_nids[1] = 0x23;
14657 }
14658 spec->adc_nids = spec->private_adc_nids;
14659 spec->capsrc_nids = spec->private_capsrc_nids;
14660 spec->num_adc_nids = 2;
14661 spec->dual_adc_switch = 1;
14662 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14663 spec->adc_nids[0], spec->adc_nids[1]);
14664 return 1;
14665 }
14666 return 0;
14667}
14668
d433a678
TI
14669/* different alc269-variants */
14670enum {
14671 ALC269_TYPE_NORMAL,
48c88e82 14672 ALC269_TYPE_ALC258,
d433a678 14673 ALC269_TYPE_ALC259,
48c88e82
KY
14674 ALC269_TYPE_ALC269VB,
14675 ALC269_TYPE_ALC270,
d433a678
TI
14676 ALC269_TYPE_ALC271X,
14677};
14678
f6a92248
KY
14679/*
14680 * BIOS auto configuration
14681 */
14682static int alc269_parse_auto_config(struct hda_codec *codec)
14683{
14684 struct alc_spec *spec = codec->spec;
cfb9fb55 14685 int err;
f6a92248
KY
14686 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14687
14688 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14689 alc269_ignore);
14690 if (err < 0)
14691 return err;
14692
14693 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14694 if (err < 0)
14695 return err;
f3550d1b
TI
14696 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14697 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14698 else
14699 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14700 0x22, 0);
f6a92248
KY
14701 if (err < 0)
14702 return err;
14703
14704 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14705
757899ac 14706 alc_auto_parse_digital(codec);
f6a92248 14707
603c4019 14708 if (spec->kctls.list)
d88897ea 14709 add_mixer(spec, spec->kctls.list);
f6a92248 14710
d433a678 14711 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14712 add_verb(spec, alc269vb_init_verbs);
6227cdce 14713 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14714 } else {
14715 add_verb(spec, alc269_init_verbs);
6227cdce 14716 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14717 }
14718
f6a92248 14719 spec->num_mux_defs = 1;
61b9b9b1 14720 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14721
14722 if (!alc275_setup_dual_adc(codec))
14723 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14724 sizeof(alc269_adc_candidates));
6694635d 14725
e01bf509 14726 /* set default input source */
840b64c0 14727 if (!spec->dual_adc_switch)
748cce43
TI
14728 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14729 spec->input_mux->items[0].index);
f6a92248
KY
14730
14731 err = alc_auto_add_mic_boost(codec);
14732 if (err < 0)
14733 return err;
14734
7e0e44d4 14735 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14736 set_capture_mixer(codec);
f53281e6 14737
f6a92248
KY
14738 return 1;
14739}
14740
e9af4f36
TI
14741#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14742#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14743#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14744
14745
14746/* init callback for auto-configuration model -- overriding the default init */
14747static void alc269_auto_init(struct hda_codec *codec)
14748{
f6c7e546 14749 struct alc_spec *spec = codec->spec;
f6a92248
KY
14750 alc269_auto_init_multi_out(codec);
14751 alc269_auto_init_hp_out(codec);
14752 alc269_auto_init_analog_input(codec);
757899ac 14753 alc_auto_init_digital(codec);
f6c7e546 14754 if (spec->unsol_event)
7fb0d78f 14755 alc_inithook(codec);
f6a92248
KY
14756}
14757
0ec33d1f
TI
14758#ifdef SND_HDA_NEEDS_RESUME
14759static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14760{
14761 int val = alc_read_coef_idx(codec, 0x04);
14762 if (power_up)
14763 val |= 1 << 11;
14764 else
14765 val &= ~(1 << 11);
14766 alc_write_coef_idx(codec, 0x04, val);
14767}
14768
977ddd6b
KY
14769#ifdef CONFIG_SND_HDA_POWER_SAVE
14770static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14771{
14772 struct alc_spec *spec = codec->spec;
977ddd6b 14773
0ec33d1f
TI
14774 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14775 alc269_toggle_power_output(codec, 0);
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 alc_shutup(codec);
14782 if (spec && spec->power_hook)
14783 spec->power_hook(codec);
14784 return 0;
14785}
0ec33d1f
TI
14786#endif /* CONFIG_SND_HDA_POWER_SAVE */
14787
977ddd6b
KY
14788static int alc269_resume(struct hda_codec *codec)
14789{
977ddd6b 14790 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14791 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14792 msleep(150);
14793 }
14794
14795 codec->patch_ops.init(codec);
14796
14797 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14798 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14799 msleep(200);
14800 }
14801
0ec33d1f
TI
14802 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14803 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14804
14805 snd_hda_codec_resume_amp(codec);
14806 snd_hda_codec_resume_cache(codec);
9e5341b9 14807 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14808 return 0;
14809}
0ec33d1f 14810#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14811
1a99d4a4
KY
14812static void alc269_fixup_hweq(struct hda_codec *codec,
14813 const struct alc_fixup *fix, int pre_init)
14814{
14815 int coef;
14816
14817 coef = alc_read_coef_idx(codec, 0x1e);
14818 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14819}
14820
ff818c24
TI
14821enum {
14822 ALC269_FIXUP_SONY_VAIO,
74dc8909 14823 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14824 ALC269_FIXUP_DELL_M101Z,
022c92be 14825 ALC269_FIXUP_SKU_IGNORE,
ac612407 14826 ALC269_FIXUP_ASUS_G73JW,
357f915e 14827 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14828 ALC275_FIXUP_SONY_HWEQ,
ff818c24
TI
14829};
14830
ff818c24
TI
14831static const struct alc_fixup alc269_fixups[] = {
14832 [ALC269_FIXUP_SONY_VAIO] = {
73413b12
TI
14833 .verbs = (const struct hda_verb[]) {
14834 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14835 {}
14836 }
ff818c24 14837 },
74dc8909 14838 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
2785591a
KY
14839 .verbs = (const struct hda_verb[]) {
14840 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14841 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14842 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
700b65ce 14843 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
2785591a
KY
14844 { }
14845 }
14846 },
145a902b
DH
14847 [ALC269_FIXUP_DELL_M101Z] = {
14848 .verbs = (const struct hda_verb[]) {
14849 /* Enables internal speaker */
14850 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14851 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14852 {}
14853 }
14854 },
022c92be 14855 [ALC269_FIXUP_SKU_IGNORE] = {
fe67b240
DH
14856 .sku = ALC_FIXUP_SKU_IGNORE,
14857 },
ac612407
DH
14858 [ALC269_FIXUP_ASUS_G73JW] = {
14859 .pins = (const struct alc_pincfg[]) {
14860 { 0x17, 0x99130111 }, /* subwoofer */
14861 { }
14862 }
14863 },
357f915e
KY
14864 [ALC269_FIXUP_LENOVO_EAPD] = {
14865 .verbs = (const struct hda_verb[]) {
14866 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14867 {}
14868 }
14869 },
1a99d4a4
KY
14870 [ALC275_FIXUP_SONY_HWEQ] = {
14871 .func = alc269_fixup_hweq,
14872 .verbs = (const struct hda_verb[]) {
14873 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14874 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14875 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14876 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14877 { }
14878 }
14879 }
ff818c24
TI
14880};
14881
14882static struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14883 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14884 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14885 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
abdd8f51 14886 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14887 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
022c92be
DH
14888 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14889 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ac612407 14890 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14891 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14892 {}
14893};
14894
14895
f6a92248
KY
14896/*
14897 * configuration and preset
14898 */
14899static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14900 [ALC269_BASIC] = "basic",
2922c9af 14901 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14902 [ALC269_AMIC] = "laptop-amic",
14903 [ALC269_DMIC] = "laptop-dmic",
64154835 14904 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14905 [ALC269_LIFEBOOK] = "lifebook",
14906 [ALC269_AUTO] = "auto",
f6a92248
KY
14907};
14908
14909static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14910 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14911 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14912 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14913 ALC269_AMIC),
14914 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14915 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14916 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14917 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14918 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14919 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14920 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14921 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14922 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14923 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14924 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14925 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14926 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14927 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14928 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14929 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14930 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14931 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14932 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14933 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14934 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14935 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14936 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14937 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14938 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14939 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14940 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14941 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14942 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14943 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14944 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14945 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14946 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14947 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14948 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14949 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14950 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14951 ALC269_DMIC),
60db6b53 14952 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14953 ALC269_DMIC),
14954 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14955 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14956 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14957 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14958 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14959 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14960 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14961 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14962 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14963 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14964 {}
14965};
14966
14967static struct alc_config_preset alc269_presets[] = {
14968 [ALC269_BASIC] = {
f9e336f6 14969 .mixers = { alc269_base_mixer },
f6a92248
KY
14970 .init_verbs = { alc269_init_verbs },
14971 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14972 .dac_nids = alc269_dac_nids,
14973 .hp_nid = 0x03,
14974 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14975 .channel_mode = alc269_modes,
14976 .input_mux = &alc269_capture_source,
14977 },
60db6b53
KY
14978 [ALC269_QUANTA_FL1] = {
14979 .mixers = { alc269_quanta_fl1_mixer },
14980 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14981 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14982 .dac_nids = alc269_dac_nids,
14983 .hp_nid = 0x03,
14984 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14985 .channel_mode = alc269_modes,
14986 .input_mux = &alc269_capture_source,
14987 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14988 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14989 .init_hook = alc269_quanta_fl1_init_hook,
14990 },
84898e87
KY
14991 [ALC269_AMIC] = {
14992 .mixers = { alc269_laptop_mixer },
14993 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14994 .init_verbs = { alc269_init_verbs,
84898e87 14995 alc269_laptop_amic_init_verbs },
f53281e6
KY
14996 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14997 .dac_nids = alc269_dac_nids,
14998 .hp_nid = 0x03,
14999 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15000 .channel_mode = alc269_modes,
84898e87
KY
15001 .unsol_event = alc269_laptop_unsol_event,
15002 .setup = alc269_laptop_amic_setup,
15003 .init_hook = alc269_laptop_inithook,
f53281e6 15004 },
84898e87
KY
15005 [ALC269_DMIC] = {
15006 .mixers = { alc269_laptop_mixer },
15007 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15008 .init_verbs = { alc269_init_verbs,
84898e87
KY
15009 alc269_laptop_dmic_init_verbs },
15010 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15011 .dac_nids = alc269_dac_nids,
15012 .hp_nid = 0x03,
15013 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15014 .channel_mode = alc269_modes,
15015 .unsol_event = alc269_laptop_unsol_event,
15016 .setup = alc269_laptop_dmic_setup,
15017 .init_hook = alc269_laptop_inithook,
15018 },
15019 [ALC269VB_AMIC] = {
15020 .mixers = { alc269vb_laptop_mixer },
15021 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15022 .init_verbs = { alc269vb_init_verbs,
15023 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15024 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15025 .dac_nids = alc269_dac_nids,
15026 .hp_nid = 0x03,
15027 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15028 .channel_mode = alc269_modes,
84898e87 15029 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 15030 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
15031 .init_hook = alc269_laptop_inithook,
15032 },
15033 [ALC269VB_DMIC] = {
15034 .mixers = { alc269vb_laptop_mixer },
15035 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15036 .init_verbs = { alc269vb_init_verbs,
15037 alc269vb_laptop_dmic_init_verbs },
15038 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15039 .dac_nids = alc269_dac_nids,
15040 .hp_nid = 0x03,
15041 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15042 .channel_mode = alc269_modes,
15043 .unsol_event = alc269_laptop_unsol_event,
15044 .setup = alc269vb_laptop_dmic_setup,
15045 .init_hook = alc269_laptop_inithook,
f53281e6 15046 },
26f5df26 15047 [ALC269_FUJITSU] = {
45bdd1c1 15048 .mixers = { alc269_fujitsu_mixer },
84898e87 15049 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15050 .init_verbs = { alc269_init_verbs,
84898e87 15051 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15052 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15053 .dac_nids = alc269_dac_nids,
15054 .hp_nid = 0x03,
15055 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15056 .channel_mode = alc269_modes,
84898e87
KY
15057 .unsol_event = alc269_laptop_unsol_event,
15058 .setup = alc269_laptop_dmic_setup,
15059 .init_hook = alc269_laptop_inithook,
26f5df26 15060 },
64154835
TV
15061 [ALC269_LIFEBOOK] = {
15062 .mixers = { alc269_lifebook_mixer },
15063 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15064 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15065 .dac_nids = alc269_dac_nids,
15066 .hp_nid = 0x03,
15067 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15068 .channel_mode = alc269_modes,
15069 .input_mux = &alc269_capture_source,
15070 .unsol_event = alc269_lifebook_unsol_event,
15071 .init_hook = alc269_lifebook_init_hook,
15072 },
fe3eb0a7
KY
15073 [ALC271_ACER] = {
15074 .mixers = { alc269_asus_mixer },
15075 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15076 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15077 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15078 .dac_nids = alc269_dac_nids,
15079 .adc_nids = alc262_dmic_adc_nids,
15080 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15081 .capsrc_nids = alc262_dmic_capsrc_nids,
15082 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15083 .channel_mode = alc269_modes,
15084 .input_mux = &alc269_capture_source,
15085 .dig_out_nid = ALC880_DIGOUT_NID,
15086 .unsol_event = alc_sku_unsol_event,
15087 .setup = alc269vb_laptop_dmic_setup,
15088 .init_hook = alc_inithook,
15089 },
f6a92248
KY
15090};
15091
977ddd6b
KY
15092static int alc269_fill_coef(struct hda_codec *codec)
15093{
15094 int val;
15095
15096 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15097 alc_write_coef_idx(codec, 0xf, 0x960b);
15098 alc_write_coef_idx(codec, 0xe, 0x8817);
15099 }
15100
15101 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15102 alc_write_coef_idx(codec, 0xf, 0x960b);
15103 alc_write_coef_idx(codec, 0xe, 0x8814);
15104 }
15105
15106 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15107 val = alc_read_coef_idx(codec, 0x04);
15108 /* Power up output pin */
15109 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15110 }
15111
15112 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15113 val = alc_read_coef_idx(codec, 0xd);
15114 if ((val & 0x0c00) >> 10 != 0x1) {
15115 /* Capless ramp up clock control */
15116 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15117 }
15118 val = alc_read_coef_idx(codec, 0x17);
15119 if ((val & 0x01c0) >> 6 != 0x4) {
15120 /* Class D power on reset */
15121 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15122 }
15123 }
15124 return 0;
15125}
15126
f6a92248
KY
15127static int patch_alc269(struct hda_codec *codec)
15128{
15129 struct alc_spec *spec;
48c88e82 15130 int board_config, coef;
f6a92248
KY
15131 int err;
15132
15133 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15134 if (spec == NULL)
15135 return -ENOMEM;
15136
15137 codec->spec = spec;
15138
da00c244
KY
15139 alc_auto_parse_customize_define(codec);
15140
c793bec5
KY
15141 if (codec->vendor_id == 0x10ec0269) {
15142 coef = alc_read_coef_idx(codec, 0);
15143 if ((coef & 0x00f0) == 0x0010) {
15144 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15145 spec->cdefine.platform_type == 1) {
15146 alc_codec_rename(codec, "ALC271X");
15147 spec->codec_variant = ALC269_TYPE_ALC271X;
15148 } else if ((coef & 0xf000) == 0x1000) {
15149 spec->codec_variant = ALC269_TYPE_ALC270;
15150 } else if ((coef & 0xf000) == 0x2000) {
15151 alc_codec_rename(codec, "ALC259");
15152 spec->codec_variant = ALC269_TYPE_ALC259;
15153 } else if ((coef & 0xf000) == 0x3000) {
15154 alc_codec_rename(codec, "ALC258");
15155 spec->codec_variant = ALC269_TYPE_ALC258;
15156 } else {
15157 alc_codec_rename(codec, "ALC269VB");
15158 spec->codec_variant = ALC269_TYPE_ALC269VB;
15159 }
15160 } else
15161 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15162 alc269_fill_coef(codec);
15163 }
977ddd6b 15164
f6a92248
KY
15165 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15166 alc269_models,
15167 alc269_cfg_tbl);
15168
15169 if (board_config < 0) {
9a11f1aa
TI
15170 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15171 codec->chip_name);
f6a92248
KY
15172 board_config = ALC269_AUTO;
15173 }
15174
ff818c24
TI
15175 if (board_config == ALC269_AUTO)
15176 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
15177
f6a92248
KY
15178 if (board_config == ALC269_AUTO) {
15179 /* automatic parse from the BIOS config */
15180 err = alc269_parse_auto_config(codec);
15181 if (err < 0) {
15182 alc_free(codec);
15183 return err;
15184 } else if (!err) {
15185 printk(KERN_INFO
15186 "hda_codec: Cannot set up configuration "
15187 "from BIOS. Using base mode...\n");
15188 board_config = ALC269_BASIC;
15189 }
15190 }
15191
dc1eae25 15192 if (has_cdefine_beep(codec)) {
8af2591d
TI
15193 err = snd_hda_attach_beep_device(codec, 0x1);
15194 if (err < 0) {
15195 alc_free(codec);
15196 return err;
15197 }
680cd536
KK
15198 }
15199
f6a92248 15200 if (board_config != ALC269_AUTO)
e9c364c0 15201 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15202
84898e87 15203 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15204 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15205 * fix the sample rate of analog I/O to 44.1kHz
15206 */
15207 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15208 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15209 } else if (spec->dual_adc_switch) {
15210 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15211 /* switch ADC dynamically */
15212 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15213 } else {
15214 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15215 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15216 }
f6a92248
KY
15217 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15218 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15219
6694635d 15220 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15221 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15222 spec->adc_nids = alc269_adc_nids;
15223 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15224 spec->capsrc_nids = alc269_capsrc_nids;
15225 } else {
15226 spec->adc_nids = alc269vb_adc_nids;
15227 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15228 spec->capsrc_nids = alc269vb_capsrc_nids;
15229 }
84898e87
KY
15230 }
15231
f9e336f6 15232 if (!spec->cap_mixer)
b59bdf3b 15233 set_capture_mixer(codec);
dc1eae25 15234 if (has_cdefine_beep(codec))
da00c244 15235 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15236
ff818c24
TI
15237 if (board_config == ALC269_AUTO)
15238 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
15239
100d5eb3
TI
15240 spec->vmaster_nid = 0x02;
15241
f6a92248 15242 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15243#ifdef CONFIG_SND_HDA_POWER_SAVE
15244 codec->patch_ops.suspend = alc269_suspend;
15245#endif
15246#ifdef SND_HDA_NEEDS_RESUME
15247 codec->patch_ops.resume = alc269_resume;
15248#endif
f6a92248
KY
15249 if (board_config == ALC269_AUTO)
15250 spec->init_hook = alc269_auto_init;
bf1b0225
KY
15251
15252 alc_init_jacks(codec);
f6a92248
KY
15253#ifdef CONFIG_SND_HDA_POWER_SAVE
15254 if (!spec->loopback.amplist)
15255 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15256 if (alc269_mic2_for_mute_led(codec))
15257 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15258#endif
15259
15260 return 0;
15261}
15262
df694daa
KY
15263/*
15264 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15265 */
15266
15267/*
15268 * set the path ways for 2 channel output
15269 * need to set the codec line out and mic 1 pin widgets to inputs
15270 */
15271static struct hda_verb alc861_threestack_ch2_init[] = {
15272 /* set pin widget 1Ah (line in) for input */
15273 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15274 /* set pin widget 18h (mic1/2) for input, for mic also enable
15275 * the vref
15276 */
df694daa
KY
15277 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15278
9c7f852e
TI
15279 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15280#if 0
15281 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15282 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15283#endif
df694daa
KY
15284 { } /* end */
15285};
15286/*
15287 * 6ch mode
15288 * need to set the codec line out and mic 1 pin widgets to outputs
15289 */
15290static struct hda_verb alc861_threestack_ch6_init[] = {
15291 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15292 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15293 /* set pin widget 18h (mic1) for output (CLFE)*/
15294 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15295
15296 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15297 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15298
9c7f852e
TI
15299 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15300#if 0
15301 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15302 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15303#endif
df694daa
KY
15304 { } /* end */
15305};
15306
15307static struct hda_channel_mode alc861_threestack_modes[2] = {
15308 { 2, alc861_threestack_ch2_init },
15309 { 6, alc861_threestack_ch6_init },
15310};
22309c3e
TI
15311/* Set mic1 as input and unmute the mixer */
15312static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15313 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15314 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15315 { } /* end */
15316};
15317/* Set mic1 as output and mute mixer */
15318static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15319 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15320 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15321 { } /* end */
15322};
15323
15324static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15325 { 2, alc861_uniwill_m31_ch2_init },
15326 { 4, alc861_uniwill_m31_ch4_init },
15327};
df694daa 15328
7cdbff94
MD
15329/* Set mic1 and line-in as input and unmute the mixer */
15330static struct hda_verb alc861_asus_ch2_init[] = {
15331 /* set pin widget 1Ah (line in) for input */
15332 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15333 /* set pin widget 18h (mic1/2) for input, for mic also enable
15334 * the vref
15335 */
7cdbff94
MD
15336 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15337
15338 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15339#if 0
15340 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15341 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15342#endif
15343 { } /* end */
15344};
15345/* Set mic1 nad line-in as output and mute mixer */
15346static struct hda_verb alc861_asus_ch6_init[] = {
15347 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15348 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15349 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15350 /* set pin widget 18h (mic1) for output (CLFE)*/
15351 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15352 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15353 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15354 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15355
15356 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15357#if 0
15358 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15359 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15360#endif
15361 { } /* end */
15362};
15363
15364static struct hda_channel_mode alc861_asus_modes[2] = {
15365 { 2, alc861_asus_ch2_init },
15366 { 6, alc861_asus_ch6_init },
15367};
15368
df694daa
KY
15369/* patch-ALC861 */
15370
15371static struct snd_kcontrol_new alc861_base_mixer[] = {
15372 /* output mixer control */
15373 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15374 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15375 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15376 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15377 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15378
15379 /*Input mixer control */
15380 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15381 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15382 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15383 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15384 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15385 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15386 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15387 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15388 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15389 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15390
df694daa
KY
15391 { } /* end */
15392};
15393
15394static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15395 /* output mixer control */
15396 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15397 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15398 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15399 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15400 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15401
15402 /* Input mixer control */
15403 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15404 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15405 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15406 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15407 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15408 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15409 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15410 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15411 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15412 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15413
df694daa
KY
15414 {
15415 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15416 .name = "Channel Mode",
15417 .info = alc_ch_mode_info,
15418 .get = alc_ch_mode_get,
15419 .put = alc_ch_mode_put,
15420 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15421 },
15422 { } /* end */
a53d1aec
TD
15423};
15424
d1d985f0 15425static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15426 /* output mixer control */
15427 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15428 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15429 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15430
a53d1aec 15431 { } /* end */
f12ab1e0 15432};
a53d1aec 15433
22309c3e
TI
15434static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15435 /* output mixer control */
15436 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15437 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15438 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15439 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15440 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15441
15442 /* Input mixer control */
15443 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15444 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15445 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15446 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15447 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15448 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15449 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15450 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15451 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15452 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15453
22309c3e
TI
15454 {
15455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15456 .name = "Channel Mode",
15457 .info = alc_ch_mode_info,
15458 .get = alc_ch_mode_get,
15459 .put = alc_ch_mode_put,
15460 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15461 },
15462 { } /* end */
f12ab1e0 15463};
7cdbff94
MD
15464
15465static struct snd_kcontrol_new alc861_asus_mixer[] = {
15466 /* output mixer control */
15467 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15468 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15469 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15470 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15471 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15472
15473 /* Input mixer control */
15474 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15475 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15476 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15477 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15478 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15479 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15480 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15481 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15482 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15483 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15484
7cdbff94
MD
15485 {
15486 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15487 .name = "Channel Mode",
15488 .info = alc_ch_mode_info,
15489 .get = alc_ch_mode_get,
15490 .put = alc_ch_mode_put,
15491 .private_value = ARRAY_SIZE(alc861_asus_modes),
15492 },
15493 { }
56bb0cab
TI
15494};
15495
15496/* additional mixer */
d1d985f0 15497static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15498 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15499 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15500 { }
15501};
7cdbff94 15502
df694daa
KY
15503/*
15504 * generic initialization of ADC, input mixers and output mixers
15505 */
15506static struct hda_verb alc861_base_init_verbs[] = {
15507 /*
15508 * Unmute ADC0 and set the default input to mic-in
15509 */
15510 /* port-A for surround (rear panel) */
15511 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15512 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15513 /* port-B for mic-in (rear panel) with vref */
15514 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15515 /* port-C for line-in (rear panel) */
15516 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15517 /* port-D for Front */
15518 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15519 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15520 /* port-E for HP out (front panel) */
15521 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15522 /* route front PCM to HP */
9dece1d7 15523 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15524 /* port-F for mic-in (front panel) with vref */
15525 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15526 /* port-G for CLFE (rear panel) */
15527 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15528 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15529 /* port-H for side (rear panel) */
15530 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15531 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15532 /* CD-in */
15533 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15534 /* route front mic to ADC1*/
15535 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15536 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15537
df694daa
KY
15538 /* Unmute DAC0~3 & spdif out*/
15539 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15540 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15541 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15542 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15543 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15544
df694daa
KY
15545 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15546 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15547 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15548 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15549 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15550
df694daa
KY
15551 /* Unmute Stereo Mixer 15 */
15552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15553 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15554 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15556
15557 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15558 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15559 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15560 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15561 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15562 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15563 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15564 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15565 /* hp used DAC 3 (Front) */
15566 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15567 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15568
15569 { }
15570};
15571
15572static struct hda_verb alc861_threestack_init_verbs[] = {
15573 /*
15574 * Unmute ADC0 and set the default input to mic-in
15575 */
15576 /* port-A for surround (rear panel) */
15577 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15578 /* port-B for mic-in (rear panel) with vref */
15579 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15580 /* port-C for line-in (rear panel) */
15581 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15582 /* port-D for Front */
15583 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15584 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15585 /* port-E for HP out (front panel) */
15586 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15587 /* route front PCM to HP */
9dece1d7 15588 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15589 /* port-F for mic-in (front panel) with vref */
15590 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15591 /* port-G for CLFE (rear panel) */
15592 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15593 /* port-H for side (rear panel) */
15594 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15595 /* CD-in */
15596 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15597 /* route front mic to ADC1*/
15598 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15599 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15600 /* Unmute DAC0~3 & spdif out*/
15601 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15602 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15603 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15604 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15605 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15606
df694daa
KY
15607 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15608 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15609 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15610 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15611 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15612
df694daa
KY
15613 /* Unmute Stereo Mixer 15 */
15614 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15615 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15616 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15617 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15618
15619 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15620 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15621 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15622 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15623 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15624 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15625 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15626 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15627 /* hp used DAC 3 (Front) */
15628 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15630 { }
15631};
22309c3e
TI
15632
15633static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15634 /*
15635 * Unmute ADC0 and set the default input to mic-in
15636 */
15637 /* port-A for surround (rear panel) */
15638 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15639 /* port-B for mic-in (rear panel) with vref */
15640 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15641 /* port-C for line-in (rear panel) */
15642 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15643 /* port-D for Front */
15644 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15645 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15646 /* port-E for HP out (front panel) */
f12ab1e0
TI
15647 /* this has to be set to VREF80 */
15648 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15649 /* route front PCM to HP */
9dece1d7 15650 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15651 /* port-F for mic-in (front panel) with vref */
15652 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15653 /* port-G for CLFE (rear panel) */
15654 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15655 /* port-H for side (rear panel) */
15656 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15657 /* CD-in */
15658 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15659 /* route front mic to ADC1*/
15660 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15661 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15662 /* Unmute DAC0~3 & spdif out*/
15663 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15664 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15665 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15666 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15667 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15668
22309c3e
TI
15669 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15670 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15671 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15672 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15673 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15674
22309c3e
TI
15675 /* Unmute Stereo Mixer 15 */
15676 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15678 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15680
15681 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15682 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15683 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15684 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15685 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15686 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15687 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15688 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15689 /* hp used DAC 3 (Front) */
15690 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15691 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15692 { }
15693};
15694
7cdbff94
MD
15695static struct hda_verb alc861_asus_init_verbs[] = {
15696 /*
15697 * Unmute ADC0 and set the default input to mic-in
15698 */
f12ab1e0
TI
15699 /* port-A for surround (rear panel)
15700 * according to codec#0 this is the HP jack
15701 */
7cdbff94
MD
15702 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15703 /* route front PCM to HP */
15704 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15705 /* port-B for mic-in (rear panel) with vref */
15706 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15707 /* port-C for line-in (rear panel) */
15708 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15709 /* port-D for Front */
15710 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15711 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15712 /* port-E for HP out (front panel) */
f12ab1e0
TI
15713 /* this has to be set to VREF80 */
15714 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15715 /* route front PCM to HP */
9dece1d7 15716 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15717 /* port-F for mic-in (front panel) with vref */
15718 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15719 /* port-G for CLFE (rear panel) */
15720 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15721 /* port-H for side (rear panel) */
15722 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15723 /* CD-in */
15724 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15725 /* route front mic to ADC1*/
15726 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15727 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15728 /* Unmute DAC0~3 & spdif out*/
15729 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15730 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15731 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15732 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15734 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15735 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15736 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15737 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15738 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15739
7cdbff94
MD
15740 /* Unmute Stereo Mixer 15 */
15741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15743 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15744 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15745
15746 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15747 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15748 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15749 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15750 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15751 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15752 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15753 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15754 /* hp used DAC 3 (Front) */
15755 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15756 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15757 { }
15758};
15759
56bb0cab
TI
15760/* additional init verbs for ASUS laptops */
15761static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15762 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15763 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15764 { }
15765};
7cdbff94 15766
df694daa
KY
15767/*
15768 * generic initialization of ADC, input mixers and output mixers
15769 */
15770static struct hda_verb alc861_auto_init_verbs[] = {
15771 /*
15772 * Unmute ADC0 and set the default input to mic-in
15773 */
f12ab1e0 15774 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15775 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15776
df694daa
KY
15777 /* Unmute DAC0~3 & spdif out*/
15778 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15779 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15780 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15781 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15783
df694daa
KY
15784 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15785 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15786 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15787 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15788 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15789
df694daa
KY
15790 /* Unmute Stereo Mixer 15 */
15791 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15792 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15793 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15794 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15795
1c20930a
TI
15796 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15797 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15798 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15799 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15800 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15801 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15802 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15803 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15804
15805 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15806 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15807 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15808 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15809 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15810 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15811 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15812 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15813
f12ab1e0 15814 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15815
15816 { }
15817};
15818
a53d1aec
TD
15819static struct hda_verb alc861_toshiba_init_verbs[] = {
15820 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15821
a53d1aec
TD
15822 { }
15823};
15824
15825/* toggle speaker-output according to the hp-jack state */
15826static void alc861_toshiba_automute(struct hda_codec *codec)
15827{
864f92be 15828 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15829
47fd830a
TI
15830 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15831 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15832 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15833 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15834}
15835
15836static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15837 unsigned int res)
15838{
a53d1aec
TD
15839 if ((res >> 26) == ALC880_HP_EVENT)
15840 alc861_toshiba_automute(codec);
15841}
15842
def319f9 15843/* pcm configuration: identical with ALC880 */
df694daa
KY
15844#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15845#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15846#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15847#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15848
15849
15850#define ALC861_DIGOUT_NID 0x07
15851
15852static struct hda_channel_mode alc861_8ch_modes[1] = {
15853 { 8, NULL }
15854};
15855
15856static hda_nid_t alc861_dac_nids[4] = {
15857 /* front, surround, clfe, side */
15858 0x03, 0x06, 0x05, 0x04
15859};
15860
9c7f852e
TI
15861static hda_nid_t alc660_dac_nids[3] = {
15862 /* front, clfe, surround */
15863 0x03, 0x05, 0x06
15864};
15865
df694daa
KY
15866static hda_nid_t alc861_adc_nids[1] = {
15867 /* ADC0-2 */
15868 0x08,
15869};
15870
15871static struct hda_input_mux alc861_capture_source = {
15872 .num_items = 5,
15873 .items = {
15874 { "Mic", 0x0 },
15875 { "Front Mic", 0x3 },
15876 { "Line", 0x1 },
15877 { "CD", 0x4 },
15878 { "Mixer", 0x5 },
15879 },
15880};
15881
1c20930a
TI
15882static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15883{
15884 struct alc_spec *spec = codec->spec;
15885 hda_nid_t mix, srcs[5];
15886 int i, j, num;
15887
15888 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15889 return 0;
15890 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15891 if (num < 0)
15892 return 0;
15893 for (i = 0; i < num; i++) {
15894 unsigned int type;
a22d543a 15895 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15896 if (type != AC_WID_AUD_OUT)
15897 continue;
15898 for (j = 0; j < spec->multiout.num_dacs; j++)
15899 if (spec->multiout.dac_nids[j] == srcs[i])
15900 break;
15901 if (j >= spec->multiout.num_dacs)
15902 return srcs[i];
15903 }
15904 return 0;
15905}
15906
df694daa 15907/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15908static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15909 const struct auto_pin_cfg *cfg)
df694daa 15910{
1c20930a 15911 struct alc_spec *spec = codec->spec;
df694daa 15912 int i;
1c20930a 15913 hda_nid_t nid, dac;
df694daa
KY
15914
15915 spec->multiout.dac_nids = spec->private_dac_nids;
15916 for (i = 0; i < cfg->line_outs; i++) {
15917 nid = cfg->line_out_pins[i];
1c20930a
TI
15918 dac = alc861_look_for_dac(codec, nid);
15919 if (!dac)
15920 continue;
15921 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15922 }
df694daa
KY
15923 return 0;
15924}
15925
bcb2f0f5
TI
15926static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15927 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15928{
bcb2f0f5 15929 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15930 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15931}
15932
bcb2f0f5
TI
15933#define alc861_create_out_sw(codec, pfx, nid, chs) \
15934 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15935
df694daa 15936/* add playback controls from the parsed DAC table */
1c20930a 15937static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15938 const struct auto_pin_cfg *cfg)
15939{
1c20930a 15940 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15941 static const char *chname[4] = {
15942 "Front", "Surround", NULL /*CLFE*/, "Side"
15943 };
bcb2f0f5 15944 const char *pfx = alc_get_line_out_pfx(cfg, true);
df694daa 15945 hda_nid_t nid;
1c20930a
TI
15946 int i, err;
15947
df694daa
KY
15948 for (i = 0; i < cfg->line_outs; i++) {
15949 nid = spec->multiout.dac_nids[i];
f12ab1e0 15950 if (!nid)
df694daa 15951 continue;
bcb2f0f5 15952 if (!pfx && i == 2) {
df694daa 15953 /* Center/LFE */
1c20930a 15954 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15955 if (err < 0)
df694daa 15956 return err;
1c20930a 15957 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15958 if (err < 0)
df694daa
KY
15959 return err;
15960 } else {
bcb2f0f5
TI
15961 const char *name = pfx;
15962 if (!name)
15963 name = chname[i];
15964 err = __alc861_create_out_sw(codec, name, nid, i, 3);
f12ab1e0 15965 if (err < 0)
df694daa
KY
15966 return err;
15967 }
15968 }
15969 return 0;
15970}
15971
1c20930a 15972static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15973{
1c20930a 15974 struct alc_spec *spec = codec->spec;
df694daa
KY
15975 int err;
15976 hda_nid_t nid;
15977
f12ab1e0 15978 if (!pin)
df694daa
KY
15979 return 0;
15980
15981 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15982 nid = alc861_look_for_dac(codec, pin);
15983 if (nid) {
15984 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15985 if (err < 0)
15986 return err;
15987 spec->multiout.hp_nid = nid;
15988 }
df694daa
KY
15989 }
15990 return 0;
15991}
15992
15993/* create playback/capture controls for input pins */
05f5f477 15994static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15995 const struct auto_pin_cfg *cfg)
df694daa 15996{
05f5f477 15997 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15998}
15999
f12ab1e0
TI
16000static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16001 hda_nid_t nid,
1c20930a 16002 int pin_type, hda_nid_t dac)
df694daa 16003{
1c20930a
TI
16004 hda_nid_t mix, srcs[5];
16005 int i, num;
16006
564c5bea
JL
16007 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16008 pin_type);
1c20930a 16009 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16010 AMP_OUT_UNMUTE);
1c20930a
TI
16011 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16012 return;
16013 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16014 if (num < 0)
16015 return;
16016 for (i = 0; i < num; i++) {
16017 unsigned int mute;
16018 if (srcs[i] == dac || srcs[i] == 0x15)
16019 mute = AMP_IN_UNMUTE(i);
16020 else
16021 mute = AMP_IN_MUTE(i);
16022 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16023 mute);
16024 }
df694daa
KY
16025}
16026
16027static void alc861_auto_init_multi_out(struct hda_codec *codec)
16028{
16029 struct alc_spec *spec = codec->spec;
16030 int i;
16031
16032 for (i = 0; i < spec->autocfg.line_outs; i++) {
16033 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16034 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16035 if (nid)
baba8ee9 16036 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16037 spec->multiout.dac_nids[i]);
df694daa
KY
16038 }
16039}
16040
16041static void alc861_auto_init_hp_out(struct hda_codec *codec)
16042{
16043 struct alc_spec *spec = codec->spec;
df694daa 16044
15870f05
TI
16045 if (spec->autocfg.hp_outs)
16046 alc861_auto_set_output_and_unmute(codec,
16047 spec->autocfg.hp_pins[0],
16048 PIN_HP,
1c20930a 16049 spec->multiout.hp_nid);
15870f05
TI
16050 if (spec->autocfg.speaker_outs)
16051 alc861_auto_set_output_and_unmute(codec,
16052 spec->autocfg.speaker_pins[0],
16053 PIN_OUT,
1c20930a 16054 spec->multiout.dac_nids[0]);
df694daa
KY
16055}
16056
16057static void alc861_auto_init_analog_input(struct hda_codec *codec)
16058{
16059 struct alc_spec *spec = codec->spec;
66ceeb6b 16060 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16061 int i;
16062
66ceeb6b
TI
16063 for (i = 0; i < cfg->num_inputs; i++) {
16064 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16065 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16066 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16067 }
16068}
16069
16070/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16071/* return 1 if successful, 0 if the proper config is not found,
16072 * or a negative error code
16073 */
df694daa
KY
16074static int alc861_parse_auto_config(struct hda_codec *codec)
16075{
16076 struct alc_spec *spec = codec->spec;
16077 int err;
16078 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16079
f12ab1e0
TI
16080 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16081 alc861_ignore);
16082 if (err < 0)
df694daa 16083 return err;
f12ab1e0 16084 if (!spec->autocfg.line_outs)
df694daa
KY
16085 return 0; /* can't find valid BIOS pin config */
16086
1c20930a 16087 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
16088 if (err < 0)
16089 return err;
1c20930a 16090 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16091 if (err < 0)
16092 return err;
1c20930a 16093 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16094 if (err < 0)
16095 return err;
05f5f477 16096 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16097 if (err < 0)
df694daa
KY
16098 return err;
16099
16100 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16101
757899ac 16102 alc_auto_parse_digital(codec);
df694daa 16103
603c4019 16104 if (spec->kctls.list)
d88897ea 16105 add_mixer(spec, spec->kctls.list);
df694daa 16106
d88897ea 16107 add_verb(spec, alc861_auto_init_verbs);
df694daa 16108
a1e8d2da 16109 spec->num_mux_defs = 1;
61b9b9b1 16110 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16111
16112 spec->adc_nids = alc861_adc_nids;
16113 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16114 set_capture_mixer(codec);
df694daa 16115
6227cdce 16116 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16117
df694daa
KY
16118 return 1;
16119}
16120
ae6b813a
TI
16121/* additional initialization for auto-configuration model */
16122static void alc861_auto_init(struct hda_codec *codec)
df694daa 16123{
f6c7e546 16124 struct alc_spec *spec = codec->spec;
df694daa
KY
16125 alc861_auto_init_multi_out(codec);
16126 alc861_auto_init_hp_out(codec);
16127 alc861_auto_init_analog_input(codec);
757899ac 16128 alc_auto_init_digital(codec);
f6c7e546 16129 if (spec->unsol_event)
7fb0d78f 16130 alc_inithook(codec);
df694daa
KY
16131}
16132
cb53c626
TI
16133#ifdef CONFIG_SND_HDA_POWER_SAVE
16134static struct hda_amp_list alc861_loopbacks[] = {
16135 { 0x15, HDA_INPUT, 0 },
16136 { 0x15, HDA_INPUT, 1 },
16137 { 0x15, HDA_INPUT, 2 },
16138 { 0x15, HDA_INPUT, 3 },
16139 { } /* end */
16140};
16141#endif
16142
df694daa
KY
16143
16144/*
16145 * configuration and preset
16146 */
f5fcc13c
TI
16147static const char *alc861_models[ALC861_MODEL_LAST] = {
16148 [ALC861_3ST] = "3stack",
16149 [ALC660_3ST] = "3stack-660",
16150 [ALC861_3ST_DIG] = "3stack-dig",
16151 [ALC861_6ST_DIG] = "6stack-dig",
16152 [ALC861_UNIWILL_M31] = "uniwill-m31",
16153 [ALC861_TOSHIBA] = "toshiba",
16154 [ALC861_ASUS] = "asus",
16155 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16156 [ALC861_AUTO] = "auto",
16157};
16158
16159static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16160 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16161 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16162 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16163 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16164 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16165 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16166 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16167 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16168 * Any other models that need this preset?
16169 */
16170 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16171 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16172 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16173 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16174 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16175 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16176 /* FIXME: the below seems conflict */
16177 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16178 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16179 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16180 {}
16181};
16182
16183static struct alc_config_preset alc861_presets[] = {
16184 [ALC861_3ST] = {
16185 .mixers = { alc861_3ST_mixer },
16186 .init_verbs = { alc861_threestack_init_verbs },
16187 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16188 .dac_nids = alc861_dac_nids,
16189 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16190 .channel_mode = alc861_threestack_modes,
4e195a7b 16191 .need_dac_fix = 1,
df694daa
KY
16192 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16193 .adc_nids = alc861_adc_nids,
16194 .input_mux = &alc861_capture_source,
16195 },
16196 [ALC861_3ST_DIG] = {
16197 .mixers = { alc861_base_mixer },
16198 .init_verbs = { alc861_threestack_init_verbs },
16199 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16200 .dac_nids = alc861_dac_nids,
16201 .dig_out_nid = ALC861_DIGOUT_NID,
16202 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16203 .channel_mode = alc861_threestack_modes,
4e195a7b 16204 .need_dac_fix = 1,
df694daa
KY
16205 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16206 .adc_nids = alc861_adc_nids,
16207 .input_mux = &alc861_capture_source,
16208 },
16209 [ALC861_6ST_DIG] = {
16210 .mixers = { alc861_base_mixer },
16211 .init_verbs = { alc861_base_init_verbs },
16212 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16213 .dac_nids = alc861_dac_nids,
16214 .dig_out_nid = ALC861_DIGOUT_NID,
16215 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16216 .channel_mode = alc861_8ch_modes,
16217 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16218 .adc_nids = alc861_adc_nids,
16219 .input_mux = &alc861_capture_source,
16220 },
9c7f852e
TI
16221 [ALC660_3ST] = {
16222 .mixers = { alc861_3ST_mixer },
16223 .init_verbs = { alc861_threestack_init_verbs },
16224 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16225 .dac_nids = alc660_dac_nids,
16226 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16227 .channel_mode = alc861_threestack_modes,
4e195a7b 16228 .need_dac_fix = 1,
9c7f852e
TI
16229 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16230 .adc_nids = alc861_adc_nids,
16231 .input_mux = &alc861_capture_source,
16232 },
22309c3e
TI
16233 [ALC861_UNIWILL_M31] = {
16234 .mixers = { alc861_uniwill_m31_mixer },
16235 .init_verbs = { alc861_uniwill_m31_init_verbs },
16236 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16237 .dac_nids = alc861_dac_nids,
16238 .dig_out_nid = ALC861_DIGOUT_NID,
16239 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16240 .channel_mode = alc861_uniwill_m31_modes,
16241 .need_dac_fix = 1,
16242 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16243 .adc_nids = alc861_adc_nids,
16244 .input_mux = &alc861_capture_source,
16245 },
a53d1aec
TD
16246 [ALC861_TOSHIBA] = {
16247 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16248 .init_verbs = { alc861_base_init_verbs,
16249 alc861_toshiba_init_verbs },
a53d1aec
TD
16250 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16251 .dac_nids = alc861_dac_nids,
16252 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16253 .channel_mode = alc883_3ST_2ch_modes,
16254 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16255 .adc_nids = alc861_adc_nids,
16256 .input_mux = &alc861_capture_source,
16257 .unsol_event = alc861_toshiba_unsol_event,
16258 .init_hook = alc861_toshiba_automute,
16259 },
7cdbff94
MD
16260 [ALC861_ASUS] = {
16261 .mixers = { alc861_asus_mixer },
16262 .init_verbs = { alc861_asus_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_asus_modes),
16267 .channel_mode = alc861_asus_modes,
16268 .need_dac_fix = 1,
16269 .hp_nid = 0x06,
16270 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16271 .adc_nids = alc861_adc_nids,
16272 .input_mux = &alc861_capture_source,
16273 },
56bb0cab
TI
16274 [ALC861_ASUS_LAPTOP] = {
16275 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16276 .init_verbs = { alc861_asus_init_verbs,
16277 alc861_asus_laptop_init_verbs },
16278 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16279 .dac_nids = alc861_dac_nids,
16280 .dig_out_nid = ALC861_DIGOUT_NID,
16281 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16282 .channel_mode = alc883_3ST_2ch_modes,
16283 .need_dac_fix = 1,
16284 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16285 .adc_nids = alc861_adc_nids,
16286 .input_mux = &alc861_capture_source,
16287 },
16288};
df694daa 16289
cfc9b06f
TI
16290/* Pin config fixes */
16291enum {
16292 PINFIX_FSC_AMILO_PI1505,
16293};
16294
cfc9b06f
TI
16295static const struct alc_fixup alc861_fixups[] = {
16296 [PINFIX_FSC_AMILO_PI1505] = {
73413b12
TI
16297 .pins = (const struct alc_pincfg[]) {
16298 { 0x0b, 0x0221101f }, /* HP */
16299 { 0x0f, 0x90170310 }, /* speaker */
16300 { }
16301 }
cfc9b06f
TI
16302 },
16303};
16304
16305static struct snd_pci_quirk alc861_fixup_tbl[] = {
16306 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16307 {}
16308};
df694daa
KY
16309
16310static int patch_alc861(struct hda_codec *codec)
16311{
16312 struct alc_spec *spec;
16313 int board_config;
16314 int err;
16315
dc041e0b 16316 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16317 if (spec == NULL)
16318 return -ENOMEM;
16319
f12ab1e0 16320 codec->spec = spec;
df694daa 16321
f5fcc13c
TI
16322 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16323 alc861_models,
16324 alc861_cfg_tbl);
9c7f852e 16325
f5fcc13c 16326 if (board_config < 0) {
9a11f1aa
TI
16327 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16328 codec->chip_name);
df694daa
KY
16329 board_config = ALC861_AUTO;
16330 }
16331
7fa90e87
TI
16332 if (board_config == ALC861_AUTO)
16333 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 16334
df694daa
KY
16335 if (board_config == ALC861_AUTO) {
16336 /* automatic parse from the BIOS config */
16337 err = alc861_parse_auto_config(codec);
16338 if (err < 0) {
16339 alc_free(codec);
16340 return err;
f12ab1e0 16341 } else if (!err) {
9c7f852e
TI
16342 printk(KERN_INFO
16343 "hda_codec: Cannot set up configuration "
16344 "from BIOS. Using base mode...\n");
df694daa
KY
16345 board_config = ALC861_3ST_DIG;
16346 }
16347 }
16348
680cd536
KK
16349 err = snd_hda_attach_beep_device(codec, 0x23);
16350 if (err < 0) {
16351 alc_free(codec);
16352 return err;
16353 }
16354
df694daa 16355 if (board_config != ALC861_AUTO)
e9c364c0 16356 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16357
df694daa
KY
16358 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16359 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16360
df694daa
KY
16361 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16362 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16363
c7a8eb10
TI
16364 if (!spec->cap_mixer)
16365 set_capture_mixer(codec);
45bdd1c1
TI
16366 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16367
2134ea4f
TI
16368 spec->vmaster_nid = 0x03;
16369
7fa90e87
TI
16370 if (board_config == ALC861_AUTO)
16371 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
16372
df694daa 16373 codec->patch_ops = alc_patch_ops;
c97259df 16374 if (board_config == ALC861_AUTO) {
ae6b813a 16375 spec->init_hook = alc861_auto_init;
c97259df
DC
16376#ifdef CONFIG_SND_HDA_POWER_SAVE
16377 spec->power_hook = alc_power_eapd;
16378#endif
16379 }
cb53c626
TI
16380#ifdef CONFIG_SND_HDA_POWER_SAVE
16381 if (!spec->loopback.amplist)
16382 spec->loopback.amplist = alc861_loopbacks;
16383#endif
ea1fb29a 16384
1da177e4
LT
16385 return 0;
16386}
16387
f32610ed
JS
16388/*
16389 * ALC861-VD support
16390 *
16391 * Based on ALC882
16392 *
16393 * In addition, an independent DAC
16394 */
16395#define ALC861VD_DIGOUT_NID 0x06
16396
16397static hda_nid_t alc861vd_dac_nids[4] = {
16398 /* front, surr, clfe, side surr */
16399 0x02, 0x03, 0x04, 0x05
16400};
16401
16402/* dac_nids for ALC660vd are in a different order - according to
16403 * Realtek's driver.
def319f9 16404 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16405 * of ALC660vd codecs, but for now there is only 3stack mixer
16406 * - and it is the same as in 861vd.
16407 * adc_nids in ALC660vd are (is) the same as in 861vd
16408 */
16409static hda_nid_t alc660vd_dac_nids[3] = {
16410 /* front, rear, clfe, rear_surr */
16411 0x02, 0x04, 0x03
16412};
16413
16414static hda_nid_t alc861vd_adc_nids[1] = {
16415 /* ADC0 */
16416 0x09,
16417};
16418
e1406348
TI
16419static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16420
f32610ed
JS
16421/* input MUX */
16422/* FIXME: should be a matrix-type input source selection */
16423static struct hda_input_mux alc861vd_capture_source = {
16424 .num_items = 4,
16425 .items = {
16426 { "Mic", 0x0 },
16427 { "Front Mic", 0x1 },
16428 { "Line", 0x2 },
16429 { "CD", 0x4 },
16430 },
16431};
16432
272a527c 16433static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16434 .num_items = 2,
272a527c 16435 .items = {
8607f7c4 16436 { "Mic", 0x0 },
28c4edb7 16437 { "Internal Mic", 0x1 },
272a527c
KY
16438 },
16439};
16440
d1a991a6
KY
16441static struct hda_input_mux alc861vd_hp_capture_source = {
16442 .num_items = 2,
16443 .items = {
16444 { "Front Mic", 0x0 },
16445 { "ATAPI Mic", 0x1 },
16446 },
16447};
16448
f32610ed
JS
16449/*
16450 * 2ch mode
16451 */
16452static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16453 { 2, NULL }
16454};
16455
16456/*
16457 * 6ch mode
16458 */
16459static struct hda_verb alc861vd_6stack_ch6_init[] = {
16460 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16461 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16462 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16463 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16464 { } /* end */
16465};
16466
16467/*
16468 * 8ch mode
16469 */
16470static struct hda_verb alc861vd_6stack_ch8_init[] = {
16471 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16472 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16473 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16474 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16475 { } /* end */
16476};
16477
16478static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16479 { 6, alc861vd_6stack_ch6_init },
16480 { 8, alc861vd_6stack_ch8_init },
16481};
16482
16483static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16484 {
16485 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16486 .name = "Channel Mode",
16487 .info = alc_ch_mode_info,
16488 .get = alc_ch_mode_get,
16489 .put = alc_ch_mode_put,
16490 },
16491 { } /* end */
16492};
16493
f32610ed
JS
16494/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16495 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16496 */
16497static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16498 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16499 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16500
16501 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16502 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16503
16504 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16505 HDA_OUTPUT),
16506 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16507 HDA_OUTPUT),
16508 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16509 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16510
16511 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16512 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16513
16514 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16515
5f99f86a 16516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16517 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16518 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16519
5f99f86a 16520 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16521 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16522 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16523
16524 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16525 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16526
16527 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16528 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16529
f32610ed
JS
16530 { } /* end */
16531};
16532
16533static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16534 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16535 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16536
16537 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16538
5f99f86a 16539 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16540 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16541 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16542
5f99f86a 16543 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16544 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16545 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16546
16547 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16548 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16549
16550 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16551 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16552
f32610ed
JS
16553 { } /* end */
16554};
16555
bdd148a3
KY
16556static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16557 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16558 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16559 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16560
16561 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16562
5f99f86a 16563 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16564 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16565 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16566
5f99f86a 16567 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16568 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16569 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16570
16571 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16572 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16573
16574 { } /* end */
16575};
16576
b419f346 16577/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16578 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16579 */
16580static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16581 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16582 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16583 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16584 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16585 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16586 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16588 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16589 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16590 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16591 { } /* end */
16592};
16593
d1a991a6
KY
16594/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16595 * Front Mic=0x18, ATAPI Mic = 0x19,
16596 */
16597static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16598 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16599 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16600 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16601 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16602 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16603 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16604 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16605 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16606
d1a991a6
KY
16607 { } /* end */
16608};
16609
f32610ed
JS
16610/*
16611 * generic initialization of ADC, input mixers and output mixers
16612 */
16613static struct hda_verb alc861vd_volume_init_verbs[] = {
16614 /*
16615 * Unmute ADC0 and set the default input to mic-in
16616 */
16617 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16618 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16619
16620 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16621 * the analog-loopback mixer widget
16622 */
16623 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16624 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16625 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16629
16630 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16631 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16632 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16633 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16634 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16635
16636 /*
16637 * Set up output mixers (0x02 - 0x05)
16638 */
16639 /* set vol=0 to output mixers */
16640 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16641 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16642 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16643 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16644
16645 /* set up input amps for analog loopback */
16646 /* Amp Indices: DAC = 0, mixer = 1 */
16647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16649 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16650 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16652 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16653 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16654 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16655
16656 { }
16657};
16658
16659/*
16660 * 3-stack pin configuration:
16661 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16662 */
16663static struct hda_verb alc861vd_3stack_init_verbs[] = {
16664 /*
16665 * Set pin mode and muting
16666 */
16667 /* set front pin widgets 0x14 for output */
16668 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16669 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16670 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16671
16672 /* Mic (rear) pin: input vref at 80% */
16673 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16674 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16675 /* Front Mic pin: input vref at 80% */
16676 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16677 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16678 /* Line In pin: input */
16679 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16680 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16681 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16682 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16683 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16684 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16685 /* CD pin widget for input */
16686 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16687
16688 { }
16689};
16690
16691/*
16692 * 6-stack pin configuration:
16693 */
16694static struct hda_verb alc861vd_6stack_init_verbs[] = {
16695 /*
16696 * Set pin mode and muting
16697 */
16698 /* set front pin widgets 0x14 for output */
16699 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16700 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16701 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16702
16703 /* Rear Pin: output 1 (0x0d) */
16704 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16705 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16706 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16707 /* CLFE Pin: output 2 (0x0e) */
16708 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16709 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16710 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16711 /* Side Pin: output 3 (0x0f) */
16712 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16713 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16714 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16715
16716 /* Mic (rear) pin: input vref at 80% */
16717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16718 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16719 /* Front Mic pin: input vref at 80% */
16720 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16721 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16722 /* Line In pin: input */
16723 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16724 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16725 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16727 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16728 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16729 /* CD pin widget for input */
16730 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16731
16732 { }
16733};
16734
bdd148a3
KY
16735static struct hda_verb alc861vd_eapd_verbs[] = {
16736 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16737 { }
16738};
16739
f9423e7a
KY
16740static struct hda_verb alc660vd_eapd_verbs[] = {
16741 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16742 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16743 { }
16744};
16745
bdd148a3
KY
16746static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16750 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16751 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16752 {}
16753};
16754
4f5d1706 16755static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16756{
a9fd4f3f 16757 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16758 spec->autocfg.hp_pins[0] = 0x1b;
16759 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16760}
16761
16762static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16763{
a9fd4f3f 16764 alc_automute_amp(codec);
eeb43387 16765 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16766}
16767
16768static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16769 unsigned int res)
16770{
16771 switch (res >> 26) {
bdd148a3 16772 case ALC880_MIC_EVENT:
eeb43387 16773 alc88x_simple_mic_automute(codec);
bdd148a3 16774 break;
a9fd4f3f
TI
16775 default:
16776 alc_automute_amp_unsol_event(codec, res);
16777 break;
bdd148a3
KY
16778 }
16779}
16780
272a527c
KY
16781static struct hda_verb alc861vd_dallas_verbs[] = {
16782 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16783 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16784 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16785 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16786
16787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16788 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16789 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16790 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16792 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16793 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16794 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16795
272a527c
KY
16796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16798 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16799 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16800 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16801 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16802 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16803 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16804
16805 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16806 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16807 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16808 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16809 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16810 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16811 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16812 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16813
16814 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16818
16819 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16820 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16821 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16822
16823 { } /* end */
16824};
16825
16826/* toggle speaker-output according to the hp-jack state */
4f5d1706 16827static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16828{
a9fd4f3f 16829 struct alc_spec *spec = codec->spec;
272a527c 16830
a9fd4f3f
TI
16831 spec->autocfg.hp_pins[0] = 0x15;
16832 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16833}
16834
cb53c626
TI
16835#ifdef CONFIG_SND_HDA_POWER_SAVE
16836#define alc861vd_loopbacks alc880_loopbacks
16837#endif
16838
def319f9 16839/* pcm configuration: identical with ALC880 */
f32610ed
JS
16840#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16841#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16842#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16843#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16844
16845/*
16846 * configuration and preset
16847 */
16848static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16849 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16850 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16851 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16852 [ALC861VD_3ST] = "3stack",
16853 [ALC861VD_3ST_DIG] = "3stack-digout",
16854 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16855 [ALC861VD_LENOVO] = "lenovo",
272a527c 16856 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16857 [ALC861VD_HP] = "hp",
f32610ed
JS
16858 [ALC861VD_AUTO] = "auto",
16859};
16860
16861static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16862 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16863 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16864 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16865 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16866 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16867 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16868 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16869 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16870 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16871 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16872 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16873 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16874 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16875 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16876 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16877 {}
16878};
16879
16880static struct alc_config_preset alc861vd_presets[] = {
16881 [ALC660VD_3ST] = {
16882 .mixers = { alc861vd_3st_mixer },
16883 .init_verbs = { alc861vd_volume_init_verbs,
16884 alc861vd_3stack_init_verbs },
16885 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16886 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16887 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16888 .channel_mode = alc861vd_3stack_2ch_modes,
16889 .input_mux = &alc861vd_capture_source,
16890 },
6963f84c
MC
16891 [ALC660VD_3ST_DIG] = {
16892 .mixers = { alc861vd_3st_mixer },
16893 .init_verbs = { alc861vd_volume_init_verbs,
16894 alc861vd_3stack_init_verbs },
16895 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16896 .dac_nids = alc660vd_dac_nids,
16897 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16898 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16899 .channel_mode = alc861vd_3stack_2ch_modes,
16900 .input_mux = &alc861vd_capture_source,
16901 },
f32610ed
JS
16902 [ALC861VD_3ST] = {
16903 .mixers = { alc861vd_3st_mixer },
16904 .init_verbs = { alc861vd_volume_init_verbs,
16905 alc861vd_3stack_init_verbs },
16906 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16907 .dac_nids = alc861vd_dac_nids,
16908 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16909 .channel_mode = alc861vd_3stack_2ch_modes,
16910 .input_mux = &alc861vd_capture_source,
16911 },
16912 [ALC861VD_3ST_DIG] = {
16913 .mixers = { alc861vd_3st_mixer },
16914 .init_verbs = { alc861vd_volume_init_verbs,
16915 alc861vd_3stack_init_verbs },
16916 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16917 .dac_nids = alc861vd_dac_nids,
16918 .dig_out_nid = ALC861VD_DIGOUT_NID,
16919 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16920 .channel_mode = alc861vd_3stack_2ch_modes,
16921 .input_mux = &alc861vd_capture_source,
16922 },
16923 [ALC861VD_6ST_DIG] = {
16924 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16925 .init_verbs = { alc861vd_volume_init_verbs,
16926 alc861vd_6stack_init_verbs },
16927 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16928 .dac_nids = alc861vd_dac_nids,
16929 .dig_out_nid = ALC861VD_DIGOUT_NID,
16930 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16931 .channel_mode = alc861vd_6stack_modes,
16932 .input_mux = &alc861vd_capture_source,
16933 },
bdd148a3
KY
16934 [ALC861VD_LENOVO] = {
16935 .mixers = { alc861vd_lenovo_mixer },
16936 .init_verbs = { alc861vd_volume_init_verbs,
16937 alc861vd_3stack_init_verbs,
16938 alc861vd_eapd_verbs,
16939 alc861vd_lenovo_unsol_verbs },
16940 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16941 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16942 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16943 .channel_mode = alc861vd_3stack_2ch_modes,
16944 .input_mux = &alc861vd_capture_source,
16945 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16946 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16947 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16948 },
272a527c
KY
16949 [ALC861VD_DALLAS] = {
16950 .mixers = { alc861vd_dallas_mixer },
16951 .init_verbs = { alc861vd_dallas_verbs },
16952 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16953 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16954 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16955 .channel_mode = alc861vd_3stack_2ch_modes,
16956 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16957 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16958 .setup = alc861vd_dallas_setup,
16959 .init_hook = alc_automute_amp,
d1a991a6
KY
16960 },
16961 [ALC861VD_HP] = {
16962 .mixers = { alc861vd_hp_mixer },
16963 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16964 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16965 .dac_nids = alc861vd_dac_nids,
d1a991a6 16966 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16967 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16968 .channel_mode = alc861vd_3stack_2ch_modes,
16969 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16970 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16971 .setup = alc861vd_dallas_setup,
16972 .init_hook = alc_automute_amp,
ea1fb29a 16973 },
13c94744
TI
16974 [ALC660VD_ASUS_V1S] = {
16975 .mixers = { alc861vd_lenovo_mixer },
16976 .init_verbs = { alc861vd_volume_init_verbs,
16977 alc861vd_3stack_init_verbs,
16978 alc861vd_eapd_verbs,
16979 alc861vd_lenovo_unsol_verbs },
16980 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16981 .dac_nids = alc660vd_dac_nids,
16982 .dig_out_nid = ALC861VD_DIGOUT_NID,
16983 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16984 .channel_mode = alc861vd_3stack_2ch_modes,
16985 .input_mux = &alc861vd_capture_source,
16986 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16987 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16988 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16989 },
f32610ed
JS
16990};
16991
16992/*
16993 * BIOS auto configuration
16994 */
05f5f477
TI
16995static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16996 const struct auto_pin_cfg *cfg)
16997{
7167594a 16998 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
16999}
17000
17001
f32610ed
JS
17002static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17003 hda_nid_t nid, int pin_type, int dac_idx)
17004{
f6c7e546 17005 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17006}
17007
17008static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17009{
17010 struct alc_spec *spec = codec->spec;
17011 int i;
17012
17013 for (i = 0; i <= HDA_SIDE; i++) {
17014 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17015 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17016 if (nid)
17017 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17018 pin_type, i);
f32610ed
JS
17019 }
17020}
17021
17022
17023static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17024{
17025 struct alc_spec *spec = codec->spec;
17026 hda_nid_t pin;
17027
17028 pin = spec->autocfg.hp_pins[0];
def319f9 17029 if (pin) /* connect to front and use dac 0 */
f32610ed 17030 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17031 pin = spec->autocfg.speaker_pins[0];
17032 if (pin)
17033 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17034}
17035
f32610ed
JS
17036#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17037
17038static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17039{
17040 struct alc_spec *spec = codec->spec;
66ceeb6b 17041 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17042 int i;
17043
66ceeb6b
TI
17044 for (i = 0; i < cfg->num_inputs; i++) {
17045 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17046 if (alc_is_input_pin(codec, nid)) {
30ea098f 17047 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17048 if (nid != ALC861VD_PIN_CD_NID &&
17049 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17050 snd_hda_codec_write(codec, nid, 0,
17051 AC_VERB_SET_AMP_GAIN_MUTE,
17052 AMP_OUT_MUTE);
17053 }
17054 }
17055}
17056
f511b01c
TI
17057#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17058
f32610ed
JS
17059#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17060#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17061
17062/* add playback controls from the parsed DAC table */
17063/* Based on ALC880 version. But ALC861VD has separate,
17064 * different NIDs for mute/unmute switch and volume control */
17065static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17066 const struct auto_pin_cfg *cfg)
17067{
f32610ed 17068 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
bcb2f0f5 17069 const char *pfx = alc_get_line_out_pfx(cfg, true);
f32610ed
JS
17070 hda_nid_t nid_v, nid_s;
17071 int i, err;
17072
17073 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 17074 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17075 continue;
17076 nid_v = alc861vd_idx_to_mixer_vol(
17077 alc880_dac_to_idx(
17078 spec->multiout.dac_nids[i]));
17079 nid_s = alc861vd_idx_to_mixer_switch(
17080 alc880_dac_to_idx(
17081 spec->multiout.dac_nids[i]));
17082
bcb2f0f5 17083 if (!pfx && i == 2) {
f32610ed 17084 /* Center/LFE */
0afe5f89
TI
17085 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17086 "Center",
f12ab1e0
TI
17087 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17088 HDA_OUTPUT));
17089 if (err < 0)
f32610ed 17090 return err;
0afe5f89
TI
17091 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17092 "LFE",
f12ab1e0
TI
17093 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17094 HDA_OUTPUT));
17095 if (err < 0)
f32610ed 17096 return err;
0afe5f89
TI
17097 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17098 "Center",
f12ab1e0
TI
17099 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17100 HDA_INPUT));
17101 if (err < 0)
f32610ed 17102 return err;
0afe5f89
TI
17103 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17104 "LFE",
f12ab1e0
TI
17105 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17106 HDA_INPUT));
17107 if (err < 0)
f32610ed
JS
17108 return err;
17109 } else {
bcb2f0f5
TI
17110 const char *name = pfx;
17111 if (!name)
17112 name = chname[i];
17113 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17114 name, i,
f12ab1e0
TI
17115 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17116 HDA_OUTPUT));
17117 if (err < 0)
f32610ed 17118 return err;
bcb2f0f5
TI
17119 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17120 name, i,
bdd148a3 17121 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17122 HDA_INPUT));
17123 if (err < 0)
f32610ed
JS
17124 return err;
17125 }
17126 }
17127 return 0;
17128}
17129
17130/* add playback controls for speaker and HP outputs */
17131/* Based on ALC880 version. But ALC861VD has separate,
17132 * different NIDs for mute/unmute switch and volume control */
17133static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17134 hda_nid_t pin, const char *pfx)
17135{
17136 hda_nid_t nid_v, nid_s;
17137 int err;
f32610ed 17138
f12ab1e0 17139 if (!pin)
f32610ed
JS
17140 return 0;
17141
17142 if (alc880_is_fixed_pin(pin)) {
17143 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17144 /* specify the DAC as the extra output */
f12ab1e0 17145 if (!spec->multiout.hp_nid)
f32610ed
JS
17146 spec->multiout.hp_nid = nid_v;
17147 else
17148 spec->multiout.extra_out_nid[0] = nid_v;
17149 /* control HP volume/switch on the output mixer amp */
17150 nid_v = alc861vd_idx_to_mixer_vol(
17151 alc880_fixed_pin_idx(pin));
17152 nid_s = alc861vd_idx_to_mixer_switch(
17153 alc880_fixed_pin_idx(pin));
17154
0afe5f89 17155 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17156 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17157 if (err < 0)
f32610ed 17158 return err;
0afe5f89 17159 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17160 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17161 if (err < 0)
f32610ed
JS
17162 return err;
17163 } else if (alc880_is_multi_pin(pin)) {
17164 /* set manual connection */
17165 /* we have only a switch on HP-out PIN */
0afe5f89 17166 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17167 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17168 if (err < 0)
f32610ed
JS
17169 return err;
17170 }
17171 return 0;
17172}
17173
17174/* parse the BIOS configuration and set up the alc_spec
17175 * return 1 if successful, 0 if the proper config is not found,
17176 * or a negative error code
17177 * Based on ALC880 version - had to change it to override
17178 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17179static int alc861vd_parse_auto_config(struct hda_codec *codec)
17180{
17181 struct alc_spec *spec = codec->spec;
17182 int err;
17183 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17184
f12ab1e0
TI
17185 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17186 alc861vd_ignore);
17187 if (err < 0)
f32610ed 17188 return err;
f12ab1e0 17189 if (!spec->autocfg.line_outs)
f32610ed
JS
17190 return 0; /* can't find valid BIOS pin config */
17191
f12ab1e0
TI
17192 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17193 if (err < 0)
17194 return err;
17195 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17196 if (err < 0)
17197 return err;
17198 err = alc861vd_auto_create_extra_out(spec,
17199 spec->autocfg.speaker_pins[0],
17200 "Speaker");
17201 if (err < 0)
17202 return err;
17203 err = alc861vd_auto_create_extra_out(spec,
17204 spec->autocfg.hp_pins[0],
17205 "Headphone");
17206 if (err < 0)
17207 return err;
05f5f477 17208 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17209 if (err < 0)
f32610ed
JS
17210 return err;
17211
17212 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17213
757899ac 17214 alc_auto_parse_digital(codec);
f32610ed 17215
603c4019 17216 if (spec->kctls.list)
d88897ea 17217 add_mixer(spec, spec->kctls.list);
f32610ed 17218
d88897ea 17219 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17220
17221 spec->num_mux_defs = 1;
61b9b9b1 17222 spec->input_mux = &spec->private_imux[0];
f32610ed 17223
776e184e
TI
17224 err = alc_auto_add_mic_boost(codec);
17225 if (err < 0)
17226 return err;
17227
6227cdce 17228 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17229
f32610ed
JS
17230 return 1;
17231}
17232
17233/* additional initialization for auto-configuration model */
17234static void alc861vd_auto_init(struct hda_codec *codec)
17235{
f6c7e546 17236 struct alc_spec *spec = codec->spec;
f32610ed
JS
17237 alc861vd_auto_init_multi_out(codec);
17238 alc861vd_auto_init_hp_out(codec);
17239 alc861vd_auto_init_analog_input(codec);
f511b01c 17240 alc861vd_auto_init_input_src(codec);
757899ac 17241 alc_auto_init_digital(codec);
f6c7e546 17242 if (spec->unsol_event)
7fb0d78f 17243 alc_inithook(codec);
f32610ed
JS
17244}
17245
f8f25ba3
TI
17246enum {
17247 ALC660VD_FIX_ASUS_GPIO1
17248};
17249
17250/* reset GPIO1 */
f8f25ba3
TI
17251static const struct alc_fixup alc861vd_fixups[] = {
17252 [ALC660VD_FIX_ASUS_GPIO1] = {
73413b12
TI
17253 .verbs = (const struct hda_verb[]) {
17254 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17255 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17256 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17257 { }
17258 }
f8f25ba3
TI
17259 },
17260};
17261
17262static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17263 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17264 {}
17265};
17266
f32610ed
JS
17267static int patch_alc861vd(struct hda_codec *codec)
17268{
17269 struct alc_spec *spec;
17270 int err, board_config;
17271
17272 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17273 if (spec == NULL)
17274 return -ENOMEM;
17275
17276 codec->spec = spec;
17277
17278 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17279 alc861vd_models,
17280 alc861vd_cfg_tbl);
17281
17282 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17283 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17284 codec->chip_name);
f32610ed
JS
17285 board_config = ALC861VD_AUTO;
17286 }
17287
7fa90e87
TI
17288 if (board_config == ALC861VD_AUTO)
17289 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 17290
f32610ed
JS
17291 if (board_config == ALC861VD_AUTO) {
17292 /* automatic parse from the BIOS config */
17293 err = alc861vd_parse_auto_config(codec);
17294 if (err < 0) {
17295 alc_free(codec);
17296 return err;
f12ab1e0 17297 } else if (!err) {
f32610ed
JS
17298 printk(KERN_INFO
17299 "hda_codec: Cannot set up configuration "
17300 "from BIOS. Using base mode...\n");
17301 board_config = ALC861VD_3ST;
17302 }
17303 }
17304
680cd536
KK
17305 err = snd_hda_attach_beep_device(codec, 0x23);
17306 if (err < 0) {
17307 alc_free(codec);
17308 return err;
17309 }
17310
f32610ed 17311 if (board_config != ALC861VD_AUTO)
e9c364c0 17312 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17313
2f893286 17314 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17315 /* always turn on EAPD */
d88897ea 17316 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17317 }
17318
f32610ed
JS
17319 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17320 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17321
f32610ed
JS
17322 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17323 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17324
dd704698
TI
17325 if (!spec->adc_nids) {
17326 spec->adc_nids = alc861vd_adc_nids;
17327 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17328 }
17329 if (!spec->capsrc_nids)
17330 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17331
b59bdf3b 17332 set_capture_mixer(codec);
45bdd1c1 17333 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17334
2134ea4f
TI
17335 spec->vmaster_nid = 0x02;
17336
7fa90e87
TI
17337 if (board_config == ALC861VD_AUTO)
17338 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
17339
f32610ed
JS
17340 codec->patch_ops = alc_patch_ops;
17341
17342 if (board_config == ALC861VD_AUTO)
17343 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17344#ifdef CONFIG_SND_HDA_POWER_SAVE
17345 if (!spec->loopback.amplist)
17346 spec->loopback.amplist = alc861vd_loopbacks;
17347#endif
f32610ed
JS
17348
17349 return 0;
17350}
17351
bc9f98a9
KY
17352/*
17353 * ALC662 support
17354 *
17355 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17356 * configuration. Each pin widget can choose any input DACs and a mixer.
17357 * Each ADC is connected from a mixer of all inputs. This makes possible
17358 * 6-channel independent captures.
17359 *
17360 * In addition, an independent DAC for the multi-playback (not used in this
17361 * driver yet).
17362 */
17363#define ALC662_DIGOUT_NID 0x06
17364#define ALC662_DIGIN_NID 0x0a
17365
17366static hda_nid_t alc662_dac_nids[4] = {
17367 /* front, rear, clfe, rear_surr */
17368 0x02, 0x03, 0x04
17369};
17370
622e84cd
KY
17371static hda_nid_t alc272_dac_nids[2] = {
17372 0x02, 0x03
17373};
17374
b59bdf3b 17375static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17376 /* ADC1-2 */
b59bdf3b 17377 0x09, 0x08
bc9f98a9 17378};
e1406348 17379
622e84cd
KY
17380static hda_nid_t alc272_adc_nids[1] = {
17381 /* ADC1-2 */
17382 0x08,
17383};
17384
b59bdf3b 17385static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17386static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17387
e1406348 17388
bc9f98a9
KY
17389/* input MUX */
17390/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17391static struct hda_input_mux alc662_capture_source = {
17392 .num_items = 4,
17393 .items = {
17394 { "Mic", 0x0 },
17395 { "Front Mic", 0x1 },
17396 { "Line", 0x2 },
17397 { "CD", 0x4 },
17398 },
17399};
17400
17401static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17402 .num_items = 2,
17403 .items = {
17404 { "Mic", 0x1 },
17405 { "Line", 0x2 },
17406 },
17407};
291702f0 17408
6dda9f4a
KY
17409static struct hda_input_mux alc663_capture_source = {
17410 .num_items = 3,
17411 .items = {
17412 { "Mic", 0x0 },
17413 { "Front Mic", 0x1 },
17414 { "Line", 0x2 },
17415 },
17416};
17417
4f5d1706 17418#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17419static struct hda_input_mux alc272_nc10_capture_source = {
17420 .num_items = 16,
17421 .items = {
17422 { "Autoselect Mic", 0x0 },
17423 { "Internal Mic", 0x1 },
17424 { "In-0x02", 0x2 },
17425 { "In-0x03", 0x3 },
17426 { "In-0x04", 0x4 },
17427 { "In-0x05", 0x5 },
17428 { "In-0x06", 0x6 },
17429 { "In-0x07", 0x7 },
17430 { "In-0x08", 0x8 },
17431 { "In-0x09", 0x9 },
17432 { "In-0x0a", 0x0a },
17433 { "In-0x0b", 0x0b },
17434 { "In-0x0c", 0x0c },
17435 { "In-0x0d", 0x0d },
17436 { "In-0x0e", 0x0e },
17437 { "In-0x0f", 0x0f },
17438 },
17439};
17440#endif
17441
bc9f98a9
KY
17442/*
17443 * 2ch mode
17444 */
17445static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17446 { 2, NULL }
17447};
17448
17449/*
17450 * 2ch mode
17451 */
17452static struct hda_verb alc662_3ST_ch2_init[] = {
17453 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17454 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17455 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17456 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17457 { } /* end */
17458};
17459
17460/*
17461 * 6ch mode
17462 */
17463static struct hda_verb alc662_3ST_ch6_init[] = {
17464 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17465 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17466 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17467 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17468 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17469 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17470 { } /* end */
17471};
17472
17473static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17474 { 2, alc662_3ST_ch2_init },
17475 { 6, alc662_3ST_ch6_init },
17476};
17477
17478/*
17479 * 2ch mode
17480 */
17481static struct hda_verb alc662_sixstack_ch6_init[] = {
17482 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17483 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17484 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17485 { } /* end */
17486};
17487
17488/*
17489 * 6ch mode
17490 */
17491static struct hda_verb alc662_sixstack_ch8_init[] = {
17492 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17493 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17494 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17495 { } /* end */
17496};
17497
17498static struct hda_channel_mode alc662_5stack_modes[2] = {
17499 { 2, alc662_sixstack_ch6_init },
17500 { 6, alc662_sixstack_ch8_init },
17501};
17502
17503/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17504 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17505 */
17506
17507static struct snd_kcontrol_new alc662_base_mixer[] = {
17508 /* output mixer control */
17509 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17510 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17511 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17512 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17513 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17514 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17515 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17516 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17517 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17518
17519 /*Input mixer control */
17520 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17521 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17522 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17523 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17524 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17525 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17526 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17527 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17528 { } /* end */
17529};
17530
17531static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17532 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17533 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17534 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17535 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17536 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17537 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17538 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17539 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17540 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17541 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17542 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17543 { } /* end */
17544};
17545
17546static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17547 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17548 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17549 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17550 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17551 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17552 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17553 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17554 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17555 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17556 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17557 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17558 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17559 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17560 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17561 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17562 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17563 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17564 { } /* end */
17565};
17566
17567static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17568 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17569 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17570 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17571 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17572 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17573 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17574 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17577 { } /* end */
17578};
17579
291702f0 17580static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17581 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17582 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17583
5f99f86a 17584 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17587
5f99f86a 17588 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17589 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17590 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17591 { } /* end */
17592};
17593
8c427226 17594static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17595 ALC262_HIPPO_MASTER_SWITCH,
17596 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17597 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17598 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17599 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17600 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17601 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17602 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17603 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17604 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17605 { } /* end */
17606};
17607
f1d4e28b
KY
17608static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17609 .ops = &snd_hda_bind_vol,
17610 .values = {
17611 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17612 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17613 0
17614 },
17615};
17616
17617static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17618 .ops = &snd_hda_bind_sw,
17619 .values = {
17620 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17621 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17622 0
17623 },
17624};
17625
6dda9f4a 17626static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17627 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17628 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17631 { } /* end */
17632};
17633
17634static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17635 .ops = &snd_hda_bind_sw,
17636 .values = {
17637 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17638 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17639 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17640 0
17641 },
17642};
17643
17644static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17645 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17646 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17649 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17650 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17651
17652 { } /* end */
17653};
17654
17655static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17656 .ops = &snd_hda_bind_sw,
17657 .values = {
17658 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17659 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17660 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17661 0
17662 },
17663};
17664
17665static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17666 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17667 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17668 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17669 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17670 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17671 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17672 { } /* end */
17673};
17674
17675static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17676 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17677 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17678 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17679 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17680 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17681 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17682 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17683 { } /* end */
17684};
17685
17686static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17687 .ops = &snd_hda_bind_vol,
17688 .values = {
17689 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17690 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17691 0
17692 },
17693};
17694
17695static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17696 .ops = &snd_hda_bind_sw,
17697 .values = {
17698 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17699 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17700 0
17701 },
17702};
17703
17704static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17705 HDA_BIND_VOL("Master Playback Volume",
17706 &alc663_asus_two_bind_master_vol),
17707 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17708 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17709 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17710 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17711 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17712 { } /* end */
17713};
17714
17715static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17716 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17717 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17718 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17719 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17722 { } /* end */
17723};
17724
17725static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17726 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17727 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17728 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17729 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17730 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17731
17732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17733 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17734 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17735 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17736 { } /* end */
17737};
17738
17739static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17740 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17741 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17742 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17743
17744 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17745 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17746 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17747 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17748 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17749 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17750 { } /* end */
17751};
17752
ebb83eeb
KY
17753static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17754 .ops = &snd_hda_bind_sw,
17755 .values = {
17756 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17757 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17758 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17759 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17760 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17761 0
17762 },
17763};
17764
17765static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17766 .ops = &snd_hda_bind_sw,
17767 .values = {
17768 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17769 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17770 0
17771 },
17772};
17773
17774static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17775 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17776 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17777 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17778 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17779 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17780 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17781 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17782 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17784 { } /* end */
17785};
17786
17787static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17788 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17789 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17790 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17791 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17792 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17795 { } /* end */
17796};
17797
17798
bc9f98a9
KY
17799static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17800 {
17801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17802 .name = "Channel Mode",
17803 .info = alc_ch_mode_info,
17804 .get = alc_ch_mode_get,
17805 .put = alc_ch_mode_put,
17806 },
17807 { } /* end */
17808};
17809
17810static struct hda_verb alc662_init_verbs[] = {
17811 /* ADC: mute amp left and right */
17812 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17813 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17814
b60dd394
KY
17815 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17816 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17817 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17818 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17819 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17820 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17821
17822 /* Front Pin: output 0 (0x0c) */
17823 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17824 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17825
17826 /* Rear Pin: output 1 (0x0d) */
17827 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17829
17830 /* CLFE Pin: output 2 (0x0e) */
17831 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17832 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17833
17834 /* Mic (rear) pin: input vref at 80% */
17835 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17836 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17837 /* Front Mic pin: input vref at 80% */
17838 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17839 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17840 /* Line In pin: input */
17841 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17842 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17843 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17844 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17845 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17846 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17847 /* CD pin widget for input */
17848 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17849
17850 /* FIXME: use matrix-type input source selection */
17851 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17852 /* Input mixer */
17853 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17854 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17855
17856 /* always trun on EAPD */
17857 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17858 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17859
bc9f98a9
KY
17860 { }
17861};
17862
cec27c89
KY
17863static struct hda_verb alc663_init_verbs[] = {
17864 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17865 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17866 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17867 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17868 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17869 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17870 { }
17871};
17872
17873static struct hda_verb alc272_init_verbs[] = {
17874 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17875 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17876 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17877 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17878 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17879 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17880 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17881 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17882 { }
17883};
17884
bc9f98a9
KY
17885static struct hda_verb alc662_sue_init_verbs[] = {
17886 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17887 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17888 {}
17889};
17890
17891static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17892 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17893 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17894 {}
bc9f98a9
KY
17895};
17896
8c427226
KY
17897/* Set Unsolicited Event*/
17898static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17899 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17900 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17901 {}
17902};
17903
6dda9f4a 17904static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17905 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17906 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17907 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17908 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17909 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17912 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17913 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17914 {}
17915};
17916
17917static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17918 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17919 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17920 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17921 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17923 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17924 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17925 {}
17926};
17927
17928static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17929 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17930 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17931 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17932 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17933 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17934 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17935 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17936 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17937 {}
17938};
6dda9f4a 17939
f1d4e28b
KY
17940static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17941 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17942 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17943 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17944 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17945 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17946 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17947 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17948 {}
17949};
6dda9f4a 17950
f1d4e28b
KY
17951static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17952 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17953 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17954 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17955 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17956 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17958 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17959 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17960 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17961 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17962 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17963 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17964 {}
17965};
17966
17967static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17968 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17969 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17970 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17971 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17972 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17973 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17974 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17975 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17976 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17977 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17978 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17979 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17980 {}
17981};
17982
17983static struct hda_verb alc663_g71v_init_verbs[] = {
17984 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17985 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17986 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17987
17988 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17989 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17990 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17991
17992 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17993 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17994 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17995 {}
17996};
17997
17998static struct hda_verb alc663_g50v_init_verbs[] = {
17999 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18000 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18001 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18002
18003 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18004 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18005 {}
18006};
18007
f1d4e28b
KY
18008static struct hda_verb alc662_ecs_init_verbs[] = {
18009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18010 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18011 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18012 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18013 {}
18014};
18015
622e84cd
KY
18016static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18017 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18018 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18019 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18020 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18021 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18022 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18023 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18024 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18026 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18027 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18028 {}
18029};
18030
18031static struct hda_verb alc272_dell_init_verbs[] = {
18032 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18033 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18034 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18035 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18036 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18037 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18038 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18039 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18040 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18041 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18042 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18043 {}
18044};
18045
ebb83eeb
KY
18046static struct hda_verb alc663_mode7_init_verbs[] = {
18047 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18049 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18050 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18051 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18052 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18053 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18054 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18055 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18056 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18059 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18060 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18061 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18062 {}
18063};
18064
18065static struct hda_verb alc663_mode8_init_verbs[] = {
18066 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18067 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18068 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18069 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18070 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18071 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18072 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18074 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18075 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18076 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18077 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18078 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18079 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18080 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18081 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18082 {}
18083};
18084
f1d4e28b
KY
18085static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18086 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18087 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18088 { } /* end */
18089};
18090
622e84cd
KY
18091static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18092 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18093 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18094 { } /* end */
18095};
18096
bc9f98a9
KY
18097static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18098{
18099 unsigned int present;
f12ab1e0 18100 unsigned char bits;
bc9f98a9 18101
864f92be 18102 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 18103 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18104
47fd830a
TI
18105 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18106 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18107}
18108
18109static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18110{
18111 unsigned int present;
f12ab1e0 18112 unsigned char bits;
bc9f98a9 18113
864f92be 18114 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 18115 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18116
47fd830a
TI
18117 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18118 HDA_AMP_MUTE, bits);
18119 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18120 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18121}
18122
18123static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18124 unsigned int res)
18125{
18126 if ((res >> 26) == ALC880_HP_EVENT)
18127 alc662_lenovo_101e_all_automute(codec);
18128 if ((res >> 26) == ALC880_FRONT_EVENT)
18129 alc662_lenovo_101e_ispeaker_automute(codec);
18130}
18131
291702f0
KY
18132/* unsolicited event for HP jack sensing */
18133static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18134 unsigned int res)
18135{
291702f0 18136 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18137 alc_mic_automute(codec);
42171c17
TI
18138 else
18139 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18140}
18141
4f5d1706
TI
18142static void alc662_eeepc_setup(struct hda_codec *codec)
18143{
18144 struct alc_spec *spec = codec->spec;
18145
18146 alc262_hippo1_setup(codec);
18147 spec->ext_mic.pin = 0x18;
18148 spec->ext_mic.mux_idx = 0;
18149 spec->int_mic.pin = 0x19;
18150 spec->int_mic.mux_idx = 1;
18151 spec->auto_mic = 1;
18152}
18153
291702f0
KY
18154static void alc662_eeepc_inithook(struct hda_codec *codec)
18155{
4f5d1706
TI
18156 alc262_hippo_automute(codec);
18157 alc_mic_automute(codec);
291702f0
KY
18158}
18159
4f5d1706 18160static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18161{
42171c17
TI
18162 struct alc_spec *spec = codec->spec;
18163
18164 spec->autocfg.hp_pins[0] = 0x14;
18165 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18166}
18167
4f5d1706
TI
18168#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18169
6dda9f4a
KY
18170static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18171{
18172 unsigned int present;
18173 unsigned char bits;
18174
864f92be 18175 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18176 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18177 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18178 HDA_AMP_MUTE, bits);
f1d4e28b 18179 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18180 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18181}
18182
18183static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18184{
18185 unsigned int present;
18186 unsigned char bits;
18187
864f92be 18188 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18189 bits = present ? HDA_AMP_MUTE : 0;
18190 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18191 HDA_AMP_MUTE, bits);
f1d4e28b 18192 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18193 HDA_AMP_MUTE, bits);
f1d4e28b 18194 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18195 HDA_AMP_MUTE, bits);
f1d4e28b 18196 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18197 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18198}
18199
18200static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18201{
18202 unsigned int present;
18203 unsigned char bits;
18204
864f92be 18205 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18206 bits = present ? HDA_AMP_MUTE : 0;
18207 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18208 HDA_AMP_MUTE, bits);
f1d4e28b 18209 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18210 HDA_AMP_MUTE, bits);
f1d4e28b 18211 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18212 HDA_AMP_MUTE, bits);
f1d4e28b 18213 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18214 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18215}
18216
18217static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18218{
18219 unsigned int present;
18220 unsigned char bits;
18221
864f92be 18222 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18223 bits = present ? 0 : PIN_OUT;
18224 snd_hda_codec_write(codec, 0x14, 0,
18225 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18226}
18227
18228static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18229{
18230 unsigned int present1, present2;
18231
864f92be
WF
18232 present1 = snd_hda_jack_detect(codec, 0x21);
18233 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18234
18235 if (present1 || present2) {
18236 snd_hda_codec_write_cache(codec, 0x14, 0,
18237 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18238 } else {
18239 snd_hda_codec_write_cache(codec, 0x14, 0,
18240 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18241 }
18242}
18243
18244static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18245{
18246 unsigned int present1, present2;
18247
864f92be
WF
18248 present1 = snd_hda_jack_detect(codec, 0x1b);
18249 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18250
18251 if (present1 || present2) {
18252 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18253 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18254 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18255 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18256 } else {
18257 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18258 HDA_AMP_MUTE, 0);
f1d4e28b 18259 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18260 HDA_AMP_MUTE, 0);
f1d4e28b 18261 }
6dda9f4a
KY
18262}
18263
ebb83eeb
KY
18264static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18265{
18266 unsigned int present1, present2;
18267
18268 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18269 AC_VERB_GET_PIN_SENSE, 0)
18270 & AC_PINSENSE_PRESENCE;
18271 present2 = snd_hda_codec_read(codec, 0x21, 0,
18272 AC_VERB_GET_PIN_SENSE, 0)
18273 & AC_PINSENSE_PRESENCE;
18274
18275 if (present1 || present2) {
18276 snd_hda_codec_write_cache(codec, 0x14, 0,
18277 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18278 snd_hda_codec_write_cache(codec, 0x17, 0,
18279 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18280 } else {
18281 snd_hda_codec_write_cache(codec, 0x14, 0,
18282 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18283 snd_hda_codec_write_cache(codec, 0x17, 0,
18284 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18285 }
18286}
18287
18288static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18289{
18290 unsigned int present1, present2;
18291
18292 present1 = snd_hda_codec_read(codec, 0x21, 0,
18293 AC_VERB_GET_PIN_SENSE, 0)
18294 & AC_PINSENSE_PRESENCE;
18295 present2 = snd_hda_codec_read(codec, 0x15, 0,
18296 AC_VERB_GET_PIN_SENSE, 0)
18297 & AC_PINSENSE_PRESENCE;
18298
18299 if (present1 || present2) {
18300 snd_hda_codec_write_cache(codec, 0x14, 0,
18301 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18302 snd_hda_codec_write_cache(codec, 0x17, 0,
18303 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18304 } else {
18305 snd_hda_codec_write_cache(codec, 0x14, 0,
18306 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18307 snd_hda_codec_write_cache(codec, 0x17, 0,
18308 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18309 }
18310}
18311
6dda9f4a
KY
18312static void alc663_m51va_unsol_event(struct hda_codec *codec,
18313 unsigned int res)
18314{
18315 switch (res >> 26) {
18316 case ALC880_HP_EVENT:
18317 alc663_m51va_speaker_automute(codec);
18318 break;
18319 case ALC880_MIC_EVENT:
4f5d1706 18320 alc_mic_automute(codec);
6dda9f4a
KY
18321 break;
18322 }
18323}
18324
4f5d1706
TI
18325static void alc663_m51va_setup(struct hda_codec *codec)
18326{
18327 struct alc_spec *spec = codec->spec;
18328 spec->ext_mic.pin = 0x18;
18329 spec->ext_mic.mux_idx = 0;
18330 spec->int_mic.pin = 0x12;
ebb83eeb 18331 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18332 spec->auto_mic = 1;
18333}
18334
6dda9f4a
KY
18335static void alc663_m51va_inithook(struct hda_codec *codec)
18336{
18337 alc663_m51va_speaker_automute(codec);
4f5d1706 18338 alc_mic_automute(codec);
6dda9f4a
KY
18339}
18340
f1d4e28b 18341/* ***************** Mode1 ******************************/
4f5d1706 18342#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18343
18344static void alc663_mode1_setup(struct hda_codec *codec)
18345{
18346 struct alc_spec *spec = codec->spec;
18347 spec->ext_mic.pin = 0x18;
18348 spec->ext_mic.mux_idx = 0;
18349 spec->int_mic.pin = 0x19;
18350 spec->int_mic.mux_idx = 1;
18351 spec->auto_mic = 1;
18352}
18353
4f5d1706 18354#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18355
f1d4e28b
KY
18356/* ***************** Mode2 ******************************/
18357static void alc662_mode2_unsol_event(struct hda_codec *codec,
18358 unsigned int res)
18359{
18360 switch (res >> 26) {
18361 case ALC880_HP_EVENT:
18362 alc662_f5z_speaker_automute(codec);
18363 break;
18364 case ALC880_MIC_EVENT:
4f5d1706 18365 alc_mic_automute(codec);
f1d4e28b
KY
18366 break;
18367 }
18368}
18369
ebb83eeb 18370#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18371
f1d4e28b
KY
18372static void alc662_mode2_inithook(struct hda_codec *codec)
18373{
18374 alc662_f5z_speaker_automute(codec);
4f5d1706 18375 alc_mic_automute(codec);
f1d4e28b
KY
18376}
18377/* ***************** Mode3 ******************************/
18378static void alc663_mode3_unsol_event(struct hda_codec *codec,
18379 unsigned int res)
18380{
18381 switch (res >> 26) {
18382 case ALC880_HP_EVENT:
18383 alc663_two_hp_m1_speaker_automute(codec);
18384 break;
18385 case ALC880_MIC_EVENT:
4f5d1706 18386 alc_mic_automute(codec);
f1d4e28b
KY
18387 break;
18388 }
18389}
18390
ebb83eeb 18391#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18392
f1d4e28b
KY
18393static void alc663_mode3_inithook(struct hda_codec *codec)
18394{
18395 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18396 alc_mic_automute(codec);
f1d4e28b
KY
18397}
18398/* ***************** Mode4 ******************************/
18399static void alc663_mode4_unsol_event(struct hda_codec *codec,
18400 unsigned int res)
18401{
18402 switch (res >> 26) {
18403 case ALC880_HP_EVENT:
18404 alc663_21jd_two_speaker_automute(codec);
18405 break;
18406 case ALC880_MIC_EVENT:
4f5d1706 18407 alc_mic_automute(codec);
f1d4e28b
KY
18408 break;
18409 }
18410}
18411
ebb83eeb 18412#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18413
f1d4e28b
KY
18414static void alc663_mode4_inithook(struct hda_codec *codec)
18415{
18416 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18417 alc_mic_automute(codec);
f1d4e28b
KY
18418}
18419/* ***************** Mode5 ******************************/
18420static void alc663_mode5_unsol_event(struct hda_codec *codec,
18421 unsigned int res)
18422{
18423 switch (res >> 26) {
18424 case ALC880_HP_EVENT:
18425 alc663_15jd_two_speaker_automute(codec);
18426 break;
18427 case ALC880_MIC_EVENT:
4f5d1706 18428 alc_mic_automute(codec);
f1d4e28b
KY
18429 break;
18430 }
18431}
18432
ebb83eeb 18433#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18434
f1d4e28b
KY
18435static void alc663_mode5_inithook(struct hda_codec *codec)
18436{
18437 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18438 alc_mic_automute(codec);
f1d4e28b
KY
18439}
18440/* ***************** Mode6 ******************************/
18441static void alc663_mode6_unsol_event(struct hda_codec *codec,
18442 unsigned int res)
18443{
18444 switch (res >> 26) {
18445 case ALC880_HP_EVENT:
18446 alc663_two_hp_m2_speaker_automute(codec);
18447 break;
18448 case ALC880_MIC_EVENT:
4f5d1706 18449 alc_mic_automute(codec);
f1d4e28b
KY
18450 break;
18451 }
18452}
18453
ebb83eeb 18454#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18455
f1d4e28b
KY
18456static void alc663_mode6_inithook(struct hda_codec *codec)
18457{
18458 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18459 alc_mic_automute(codec);
f1d4e28b
KY
18460}
18461
ebb83eeb
KY
18462/* ***************** Mode7 ******************************/
18463static void alc663_mode7_unsol_event(struct hda_codec *codec,
18464 unsigned int res)
18465{
18466 switch (res >> 26) {
18467 case ALC880_HP_EVENT:
18468 alc663_two_hp_m7_speaker_automute(codec);
18469 break;
18470 case ALC880_MIC_EVENT:
18471 alc_mic_automute(codec);
18472 break;
18473 }
18474}
18475
18476#define alc663_mode7_setup alc663_mode1_setup
18477
18478static void alc663_mode7_inithook(struct hda_codec *codec)
18479{
18480 alc663_two_hp_m7_speaker_automute(codec);
18481 alc_mic_automute(codec);
18482}
18483
18484/* ***************** Mode8 ******************************/
18485static void alc663_mode8_unsol_event(struct hda_codec *codec,
18486 unsigned int res)
18487{
18488 switch (res >> 26) {
18489 case ALC880_HP_EVENT:
18490 alc663_two_hp_m8_speaker_automute(codec);
18491 break;
18492 case ALC880_MIC_EVENT:
18493 alc_mic_automute(codec);
18494 break;
18495 }
18496}
18497
18498#define alc663_mode8_setup alc663_m51va_setup
18499
18500static void alc663_mode8_inithook(struct hda_codec *codec)
18501{
18502 alc663_two_hp_m8_speaker_automute(codec);
18503 alc_mic_automute(codec);
18504}
18505
6dda9f4a
KY
18506static void alc663_g71v_hp_automute(struct hda_codec *codec)
18507{
18508 unsigned int present;
18509 unsigned char bits;
18510
864f92be 18511 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18512 bits = present ? HDA_AMP_MUTE : 0;
18513 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18514 HDA_AMP_MUTE, bits);
18515 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18516 HDA_AMP_MUTE, bits);
18517}
18518
18519static void alc663_g71v_front_automute(struct hda_codec *codec)
18520{
18521 unsigned int present;
18522 unsigned char bits;
18523
864f92be 18524 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18525 bits = present ? HDA_AMP_MUTE : 0;
18526 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18527 HDA_AMP_MUTE, bits);
18528}
18529
18530static void alc663_g71v_unsol_event(struct hda_codec *codec,
18531 unsigned int res)
18532{
18533 switch (res >> 26) {
18534 case ALC880_HP_EVENT:
18535 alc663_g71v_hp_automute(codec);
18536 break;
18537 case ALC880_FRONT_EVENT:
18538 alc663_g71v_front_automute(codec);
18539 break;
18540 case ALC880_MIC_EVENT:
4f5d1706 18541 alc_mic_automute(codec);
6dda9f4a
KY
18542 break;
18543 }
18544}
18545
4f5d1706
TI
18546#define alc663_g71v_setup alc663_m51va_setup
18547
6dda9f4a
KY
18548static void alc663_g71v_inithook(struct hda_codec *codec)
18549{
18550 alc663_g71v_front_automute(codec);
18551 alc663_g71v_hp_automute(codec);
4f5d1706 18552 alc_mic_automute(codec);
6dda9f4a
KY
18553}
18554
18555static void alc663_g50v_unsol_event(struct hda_codec *codec,
18556 unsigned int res)
18557{
18558 switch (res >> 26) {
18559 case ALC880_HP_EVENT:
18560 alc663_m51va_speaker_automute(codec);
18561 break;
18562 case ALC880_MIC_EVENT:
4f5d1706 18563 alc_mic_automute(codec);
6dda9f4a
KY
18564 break;
18565 }
18566}
18567
4f5d1706
TI
18568#define alc663_g50v_setup alc663_m51va_setup
18569
6dda9f4a
KY
18570static void alc663_g50v_inithook(struct hda_codec *codec)
18571{
18572 alc663_m51va_speaker_automute(codec);
4f5d1706 18573 alc_mic_automute(codec);
6dda9f4a
KY
18574}
18575
f1d4e28b
KY
18576static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18577 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18578 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18579
5f99f86a 18580 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18581 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18582 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18583
5f99f86a 18584 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18585 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18586 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18587 { } /* end */
18588};
18589
9541ba1d
CP
18590static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18591 /* Master Playback automatically created from Speaker and Headphone */
18592 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18593 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18594 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18595 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18596
8607f7c4
DH
18597 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18598 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18599 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18600
28c4edb7
DH
18601 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18602 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18603 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18604 { } /* end */
18605};
18606
cb53c626
TI
18607#ifdef CONFIG_SND_HDA_POWER_SAVE
18608#define alc662_loopbacks alc880_loopbacks
18609#endif
18610
bc9f98a9 18611
def319f9 18612/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18613#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18614#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18615#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18616#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18617
18618/*
18619 * configuration and preset
18620 */
18621static const char *alc662_models[ALC662_MODEL_LAST] = {
18622 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18623 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18624 [ALC662_3ST_6ch] = "3stack-6ch",
18625 [ALC662_5ST_DIG] = "6stack-dig",
18626 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18627 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18628 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18629 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18630 [ALC663_ASUS_M51VA] = "m51va",
18631 [ALC663_ASUS_G71V] = "g71v",
18632 [ALC663_ASUS_H13] = "h13",
18633 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18634 [ALC663_ASUS_MODE1] = "asus-mode1",
18635 [ALC662_ASUS_MODE2] = "asus-mode2",
18636 [ALC663_ASUS_MODE3] = "asus-mode3",
18637 [ALC663_ASUS_MODE4] = "asus-mode4",
18638 [ALC663_ASUS_MODE5] = "asus-mode5",
18639 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18640 [ALC663_ASUS_MODE7] = "asus-mode7",
18641 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18642 [ALC272_DELL] = "dell",
18643 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18644 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18645 [ALC662_AUTO] = "auto",
18646};
18647
18648static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18649 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18650 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18651 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18652 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18653 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18654 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18655 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18656 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18657 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18658 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18659 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18660 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18661 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18662 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18663 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18664 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18665 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18666 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18667 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18668 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18669 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18670 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18671 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18672 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18673 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18674 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18675 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18676 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18677 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18678 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18679 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18680 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18681 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18682 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18683 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18684 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18685 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18686 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18687 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18688 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18689 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18690 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18691 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18692 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18693 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18694 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18695 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18696 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18697 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18698 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18699 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18700 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18701 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18702 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18703 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18704 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18705 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18706 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18707 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18708 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18709 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18710 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18711 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18712 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18713 ALC662_3ST_6ch_DIG),
4dee8baa 18714 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18715 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18716 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18717 ALC662_3ST_6ch_DIG),
6227cdce 18718 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18719 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18720 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18721 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18722 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18723 ALC662_3ST_6ch_DIG),
dea0a509
TI
18724 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18725 ALC663_ASUS_H13),
bc9f98a9
KY
18726 {}
18727};
18728
18729static struct alc_config_preset alc662_presets[] = {
18730 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18731 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18732 .init_verbs = { alc662_init_verbs },
18733 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18734 .dac_nids = alc662_dac_nids,
18735 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18736 .dig_in_nid = ALC662_DIGIN_NID,
18737 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18738 .channel_mode = alc662_3ST_2ch_modes,
18739 .input_mux = &alc662_capture_source,
18740 },
18741 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18742 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18743 .init_verbs = { alc662_init_verbs },
18744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18745 .dac_nids = alc662_dac_nids,
18746 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18747 .dig_in_nid = ALC662_DIGIN_NID,
18748 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18749 .channel_mode = alc662_3ST_6ch_modes,
18750 .need_dac_fix = 1,
18751 .input_mux = &alc662_capture_source,
f12ab1e0 18752 },
bc9f98a9 18753 [ALC662_3ST_6ch] = {
f9e336f6 18754 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18755 .init_verbs = { alc662_init_verbs },
18756 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18757 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18758 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18759 .channel_mode = alc662_3ST_6ch_modes,
18760 .need_dac_fix = 1,
18761 .input_mux = &alc662_capture_source,
f12ab1e0 18762 },
bc9f98a9 18763 [ALC662_5ST_DIG] = {
f9e336f6 18764 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18765 .init_verbs = { alc662_init_verbs },
18766 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18767 .dac_nids = alc662_dac_nids,
18768 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18769 .dig_in_nid = ALC662_DIGIN_NID,
18770 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18771 .channel_mode = alc662_5stack_modes,
18772 .input_mux = &alc662_capture_source,
18773 },
18774 [ALC662_LENOVO_101E] = {
f9e336f6 18775 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18776 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18777 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18778 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18779 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18780 .channel_mode = alc662_3ST_2ch_modes,
18781 .input_mux = &alc662_lenovo_101e_capture_source,
18782 .unsol_event = alc662_lenovo_101e_unsol_event,
18783 .init_hook = alc662_lenovo_101e_all_automute,
18784 },
291702f0 18785 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18786 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18787 .init_verbs = { alc662_init_verbs,
18788 alc662_eeepc_sue_init_verbs },
18789 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18790 .dac_nids = alc662_dac_nids,
291702f0
KY
18791 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18792 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18793 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18794 .setup = alc662_eeepc_setup,
291702f0
KY
18795 .init_hook = alc662_eeepc_inithook,
18796 },
8c427226 18797 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18798 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18799 alc662_chmode_mixer },
18800 .init_verbs = { alc662_init_verbs,
18801 alc662_eeepc_ep20_sue_init_verbs },
18802 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18803 .dac_nids = alc662_dac_nids,
8c427226
KY
18804 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18805 .channel_mode = alc662_3ST_6ch_modes,
18806 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18807 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18808 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18809 .init_hook = alc662_eeepc_ep20_inithook,
18810 },
f1d4e28b 18811 [ALC662_ECS] = {
f9e336f6 18812 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18813 .init_verbs = { alc662_init_verbs,
18814 alc662_ecs_init_verbs },
18815 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18816 .dac_nids = alc662_dac_nids,
18817 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18818 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18819 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18820 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18821 .init_hook = alc662_eeepc_inithook,
18822 },
6dda9f4a 18823 [ALC663_ASUS_M51VA] = {
f9e336f6 18824 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18825 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18826 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18827 .dac_nids = alc662_dac_nids,
18828 .dig_out_nid = ALC662_DIGOUT_NID,
18829 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18830 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18831 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18832 .setup = alc663_m51va_setup,
6dda9f4a
KY
18833 .init_hook = alc663_m51va_inithook,
18834 },
18835 [ALC663_ASUS_G71V] = {
f9e336f6 18836 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18837 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18838 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18839 .dac_nids = alc662_dac_nids,
18840 .dig_out_nid = ALC662_DIGOUT_NID,
18841 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18842 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18843 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18844 .setup = alc663_g71v_setup,
6dda9f4a
KY
18845 .init_hook = alc663_g71v_inithook,
18846 },
18847 [ALC663_ASUS_H13] = {
f9e336f6 18848 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18849 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18850 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18851 .dac_nids = alc662_dac_nids,
18852 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18853 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18854 .unsol_event = alc663_m51va_unsol_event,
18855 .init_hook = alc663_m51va_inithook,
18856 },
18857 [ALC663_ASUS_G50V] = {
f9e336f6 18858 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18859 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18860 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18861 .dac_nids = alc662_dac_nids,
18862 .dig_out_nid = ALC662_DIGOUT_NID,
18863 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18864 .channel_mode = alc662_3ST_6ch_modes,
18865 .input_mux = &alc663_capture_source,
18866 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18867 .setup = alc663_g50v_setup,
6dda9f4a
KY
18868 .init_hook = alc663_g50v_inithook,
18869 },
f1d4e28b 18870 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18871 .mixers = { alc663_m51va_mixer },
18872 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18873 .init_verbs = { alc662_init_verbs,
18874 alc663_21jd_amic_init_verbs },
18875 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18876 .hp_nid = 0x03,
18877 .dac_nids = alc662_dac_nids,
18878 .dig_out_nid = ALC662_DIGOUT_NID,
18879 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18880 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18881 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18882 .setup = alc663_mode1_setup,
f1d4e28b
KY
18883 .init_hook = alc663_mode1_inithook,
18884 },
18885 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18886 .mixers = { alc662_1bjd_mixer },
18887 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18888 .init_verbs = { alc662_init_verbs,
18889 alc662_1bjd_amic_init_verbs },
18890 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18891 .dac_nids = alc662_dac_nids,
18892 .dig_out_nid = ALC662_DIGOUT_NID,
18893 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18894 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18895 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18896 .setup = alc662_mode2_setup,
f1d4e28b
KY
18897 .init_hook = alc662_mode2_inithook,
18898 },
18899 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18900 .mixers = { alc663_two_hp_m1_mixer },
18901 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18902 .init_verbs = { alc662_init_verbs,
18903 alc663_two_hp_amic_m1_init_verbs },
18904 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18905 .hp_nid = 0x03,
18906 .dac_nids = alc662_dac_nids,
18907 .dig_out_nid = ALC662_DIGOUT_NID,
18908 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18909 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18910 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18911 .setup = alc663_mode3_setup,
f1d4e28b
KY
18912 .init_hook = alc663_mode3_inithook,
18913 },
18914 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18915 .mixers = { alc663_asus_21jd_clfe_mixer },
18916 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18917 .init_verbs = { alc662_init_verbs,
18918 alc663_21jd_amic_init_verbs},
18919 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18920 .hp_nid = 0x03,
18921 .dac_nids = alc662_dac_nids,
18922 .dig_out_nid = ALC662_DIGOUT_NID,
18923 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18924 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18925 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18926 .setup = alc663_mode4_setup,
f1d4e28b
KY
18927 .init_hook = alc663_mode4_inithook,
18928 },
18929 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18930 .mixers = { alc663_asus_15jd_clfe_mixer },
18931 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18932 .init_verbs = { alc662_init_verbs,
18933 alc663_15jd_amic_init_verbs },
18934 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18935 .hp_nid = 0x03,
18936 .dac_nids = alc662_dac_nids,
18937 .dig_out_nid = ALC662_DIGOUT_NID,
18938 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18939 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18940 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18941 .setup = alc663_mode5_setup,
f1d4e28b
KY
18942 .init_hook = alc663_mode5_inithook,
18943 },
18944 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18945 .mixers = { alc663_two_hp_m2_mixer },
18946 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18947 .init_verbs = { alc662_init_verbs,
18948 alc663_two_hp_amic_m2_init_verbs },
18949 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18950 .hp_nid = 0x03,
18951 .dac_nids = alc662_dac_nids,
18952 .dig_out_nid = ALC662_DIGOUT_NID,
18953 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18954 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18955 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18956 .setup = alc663_mode6_setup,
f1d4e28b
KY
18957 .init_hook = alc663_mode6_inithook,
18958 },
ebb83eeb
KY
18959 [ALC663_ASUS_MODE7] = {
18960 .mixers = { alc663_mode7_mixer },
18961 .cap_mixer = alc662_auto_capture_mixer,
18962 .init_verbs = { alc662_init_verbs,
18963 alc663_mode7_init_verbs },
18964 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18965 .hp_nid = 0x03,
18966 .dac_nids = alc662_dac_nids,
18967 .dig_out_nid = ALC662_DIGOUT_NID,
18968 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18969 .channel_mode = alc662_3ST_2ch_modes,
18970 .unsol_event = alc663_mode7_unsol_event,
18971 .setup = alc663_mode7_setup,
18972 .init_hook = alc663_mode7_inithook,
18973 },
18974 [ALC663_ASUS_MODE8] = {
18975 .mixers = { alc663_mode8_mixer },
18976 .cap_mixer = alc662_auto_capture_mixer,
18977 .init_verbs = { alc662_init_verbs,
18978 alc663_mode8_init_verbs },
18979 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18980 .hp_nid = 0x03,
18981 .dac_nids = alc662_dac_nids,
18982 .dig_out_nid = ALC662_DIGOUT_NID,
18983 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18984 .channel_mode = alc662_3ST_2ch_modes,
18985 .unsol_event = alc663_mode8_unsol_event,
18986 .setup = alc663_mode8_setup,
18987 .init_hook = alc663_mode8_inithook,
18988 },
622e84cd
KY
18989 [ALC272_DELL] = {
18990 .mixers = { alc663_m51va_mixer },
18991 .cap_mixer = alc272_auto_capture_mixer,
18992 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18993 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18994 .dac_nids = alc662_dac_nids,
18995 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18996 .adc_nids = alc272_adc_nids,
18997 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18998 .capsrc_nids = alc272_capsrc_nids,
18999 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19000 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19001 .setup = alc663_m51va_setup,
622e84cd
KY
19002 .init_hook = alc663_m51va_inithook,
19003 },
19004 [ALC272_DELL_ZM1] = {
19005 .mixers = { alc663_m51va_mixer },
19006 .cap_mixer = alc662_auto_capture_mixer,
19007 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19008 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19009 .dac_nids = alc662_dac_nids,
19010 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19011 .adc_nids = alc662_adc_nids,
b59bdf3b 19012 .num_adc_nids = 1,
622e84cd
KY
19013 .capsrc_nids = alc662_capsrc_nids,
19014 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19015 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19016 .setup = alc663_m51va_setup,
622e84cd
KY
19017 .init_hook = alc663_m51va_inithook,
19018 },
9541ba1d
CP
19019 [ALC272_SAMSUNG_NC10] = {
19020 .mixers = { alc272_nc10_mixer },
19021 .init_verbs = { alc662_init_verbs,
19022 alc663_21jd_amic_init_verbs },
19023 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19024 .dac_nids = alc272_dac_nids,
19025 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19026 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 19027 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 19028 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19029 .setup = alc663_mode4_setup,
9541ba1d
CP
19030 .init_hook = alc663_mode4_inithook,
19031 },
bc9f98a9
KY
19032};
19033
19034
19035/*
19036 * BIOS auto configuration
19037 */
19038
7085ec12
TI
19039/* convert from MIX nid to DAC */
19040static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19041{
19042 if (nid == 0x0f)
19043 return 0x02;
19044 else if (nid >= 0x0c && nid <= 0x0e)
19045 return nid - 0x0c + 0x02;
cc1c452e
DH
19046 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19047 return 0x25;
7085ec12
TI
19048 else
19049 return 0;
19050}
19051
19052/* get MIX nid connected to the given pin targeted to DAC */
19053static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19054 hda_nid_t dac)
19055{
cc1c452e 19056 hda_nid_t mix[5];
7085ec12
TI
19057 int i, num;
19058
19059 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19060 for (i = 0; i < num; i++) {
19061 if (alc662_mix_to_dac(mix[i]) == dac)
19062 return mix[i];
19063 }
19064 return 0;
19065}
19066
19067/* look for an empty DAC slot */
19068static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19069{
19070 struct alc_spec *spec = codec->spec;
19071 hda_nid_t srcs[5];
19072 int i, j, num;
19073
19074 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19075 if (num < 0)
19076 return 0;
19077 for (i = 0; i < num; i++) {
19078 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19079 if (!nid)
19080 continue;
19081 for (j = 0; j < spec->multiout.num_dacs; j++)
19082 if (spec->multiout.dac_nids[j] == nid)
19083 break;
19084 if (j >= spec->multiout.num_dacs)
19085 return nid;
19086 }
19087 return 0;
19088}
19089
19090/* fill in the dac_nids table from the parsed pin configuration */
19091static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19092 const struct auto_pin_cfg *cfg)
19093{
19094 struct alc_spec *spec = codec->spec;
19095 int i;
19096 hda_nid_t dac;
19097
19098 spec->multiout.dac_nids = spec->private_dac_nids;
19099 for (i = 0; i < cfg->line_outs; i++) {
19100 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19101 if (!dac)
19102 continue;
19103 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19104 }
19105 return 0;
19106}
19107
bcb2f0f5
TI
19108static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19109 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19110{
bcb2f0f5 19111 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
19112 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19113}
19114
bcb2f0f5
TI
19115static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19116 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19117{
bcb2f0f5 19118 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19119 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19120}
19121
bcb2f0f5
TI
19122#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19123 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19124#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19125 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19126#define alc662_add_stereo_vol(spec, pfx, nid) \
19127 alc662_add_vol_ctl(spec, pfx, nid, 3)
19128#define alc662_add_stereo_sw(spec, pfx, nid) \
19129 alc662_add_sw_ctl(spec, pfx, nid, 3)
19130
bc9f98a9 19131/* add playback controls from the parsed DAC table */
7085ec12 19132static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19133 const struct auto_pin_cfg *cfg)
19134{
7085ec12 19135 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19136 static const char *chname[4] = {
19137 "Front", "Surround", NULL /*CLFE*/, "Side"
19138 };
bcb2f0f5 19139 const char *pfx = alc_get_line_out_pfx(cfg, true);
7085ec12 19140 hda_nid_t nid, mix;
bc9f98a9
KY
19141 int i, err;
19142
19143 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19144 nid = spec->multiout.dac_nids[i];
19145 if (!nid)
19146 continue;
19147 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19148 if (!mix)
bc9f98a9 19149 continue;
bcb2f0f5 19150 if (!pfx && i == 2) {
bc9f98a9 19151 /* Center/LFE */
7085ec12 19152 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19153 if (err < 0)
19154 return err;
7085ec12 19155 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19156 if (err < 0)
19157 return err;
7085ec12 19158 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19159 if (err < 0)
19160 return err;
7085ec12 19161 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19162 if (err < 0)
19163 return err;
19164 } else {
bcb2f0f5
TI
19165 const char *name = pfx;
19166 if (!name)
19167 name = chname[i];
19168 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
bc9f98a9
KY
19169 if (err < 0)
19170 return err;
bcb2f0f5 19171 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
bc9f98a9
KY
19172 if (err < 0)
19173 return err;
19174 }
19175 }
19176 return 0;
19177}
19178
19179/* add playback controls for speaker and HP outputs */
7085ec12
TI
19180/* return DAC nid if any new DAC is assigned */
19181static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19182 const char *pfx)
19183{
7085ec12
TI
19184 struct alc_spec *spec = codec->spec;
19185 hda_nid_t nid, mix;
bc9f98a9 19186 int err;
bc9f98a9
KY
19187
19188 if (!pin)
19189 return 0;
7085ec12
TI
19190 nid = alc662_look_for_dac(codec, pin);
19191 if (!nid) {
7085ec12
TI
19192 /* the corresponding DAC is already occupied */
19193 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19194 return 0; /* no way */
19195 /* create a switch only */
0afe5f89 19196 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19197 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19198 }
19199
7085ec12
TI
19200 mix = alc662_dac_to_mix(codec, pin, nid);
19201 if (!mix)
19202 return 0;
19203 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19204 if (err < 0)
19205 return err;
19206 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19207 if (err < 0)
19208 return err;
19209 return nid;
bc9f98a9
KY
19210}
19211
19212/* create playback/capture controls for input pins */
05f5f477 19213#define alc662_auto_create_input_ctls \
4b7348a1 19214 alc882_auto_create_input_ctls
bc9f98a9
KY
19215
19216static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19217 hda_nid_t nid, int pin_type,
7085ec12 19218 hda_nid_t dac)
bc9f98a9 19219{
7085ec12 19220 int i, num;
ce503f38 19221 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19222
f6c7e546 19223 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19224 /* need the manual connection? */
7085ec12
TI
19225 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19226 if (num <= 1)
19227 return;
19228 for (i = 0; i < num; i++) {
19229 if (alc662_mix_to_dac(srcs[i]) != dac)
19230 continue;
19231 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19232 return;
bc9f98a9
KY
19233 }
19234}
19235
19236static void alc662_auto_init_multi_out(struct hda_codec *codec)
19237{
19238 struct alc_spec *spec = codec->spec;
7085ec12 19239 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19240 int i;
19241
19242 for (i = 0; i <= HDA_SIDE; i++) {
19243 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19244 if (nid)
baba8ee9 19245 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19246 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19247 }
19248}
19249
19250static void alc662_auto_init_hp_out(struct hda_codec *codec)
19251{
19252 struct alc_spec *spec = codec->spec;
19253 hda_nid_t pin;
19254
19255 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19256 if (pin)
19257 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19258 spec->multiout.hp_nid);
f6c7e546
TI
19259 pin = spec->autocfg.speaker_pins[0];
19260 if (pin)
7085ec12
TI
19261 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19262 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19263}
19264
bc9f98a9
KY
19265#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19266
19267static void alc662_auto_init_analog_input(struct hda_codec *codec)
19268{
19269 struct alc_spec *spec = codec->spec;
66ceeb6b 19270 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19271 int i;
19272
66ceeb6b
TI
19273 for (i = 0; i < cfg->num_inputs; i++) {
19274 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19275 if (alc_is_input_pin(codec, nid)) {
30ea098f 19276 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19277 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19278 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19279 snd_hda_codec_write(codec, nid, 0,
19280 AC_VERB_SET_AMP_GAIN_MUTE,
19281 AMP_OUT_MUTE);
19282 }
19283 }
19284}
19285
f511b01c
TI
19286#define alc662_auto_init_input_src alc882_auto_init_input_src
19287
bc9f98a9
KY
19288static int alc662_parse_auto_config(struct hda_codec *codec)
19289{
19290 struct alc_spec *spec = codec->spec;
19291 int err;
19292 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19293
19294 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19295 alc662_ignore);
19296 if (err < 0)
19297 return err;
19298 if (!spec->autocfg.line_outs)
19299 return 0; /* can't find valid BIOS pin config */
19300
7085ec12 19301 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19302 if (err < 0)
19303 return err;
7085ec12 19304 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19305 if (err < 0)
19306 return err;
7085ec12 19307 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19308 spec->autocfg.speaker_pins[0],
19309 "Speaker");
19310 if (err < 0)
19311 return err;
7085ec12
TI
19312 if (err)
19313 spec->multiout.extra_out_nid[0] = err;
19314 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19315 "Headphone");
19316 if (err < 0)
19317 return err;
7085ec12
TI
19318 if (err)
19319 spec->multiout.hp_nid = err;
05f5f477 19320 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19321 if (err < 0)
bc9f98a9
KY
19322 return err;
19323
19324 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19325
757899ac 19326 alc_auto_parse_digital(codec);
bc9f98a9 19327
603c4019 19328 if (spec->kctls.list)
d88897ea 19329 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19330
19331 spec->num_mux_defs = 1;
61b9b9b1 19332 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19333
cec27c89
KY
19334 add_verb(spec, alc662_init_verbs);
19335 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19336 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19337 add_verb(spec, alc663_init_verbs);
19338
19339 if (codec->vendor_id == 0x10ec0272)
19340 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19341
19342 err = alc_auto_add_mic_boost(codec);
19343 if (err < 0)
19344 return err;
19345
6227cdce
KY
19346 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19347 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19348 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19349 else
19350 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19351
8c87286f 19352 return 1;
bc9f98a9
KY
19353}
19354
19355/* additional initialization for auto-configuration model */
19356static void alc662_auto_init(struct hda_codec *codec)
19357{
f6c7e546 19358 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19359 alc662_auto_init_multi_out(codec);
19360 alc662_auto_init_hp_out(codec);
19361 alc662_auto_init_analog_input(codec);
f511b01c 19362 alc662_auto_init_input_src(codec);
757899ac 19363 alc_auto_init_digital(codec);
f6c7e546 19364 if (spec->unsol_event)
7fb0d78f 19365 alc_inithook(codec);
bc9f98a9
KY
19366}
19367
6be7948f
TB
19368static void alc272_fixup_mario(struct hda_codec *codec,
19369 const struct alc_fixup *fix, int pre_init) {
19370 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19371 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19372 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19373 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19374 (0 << AC_AMPCAP_MUTE_SHIFT)))
19375 printk(KERN_WARNING
19376 "hda_codec: failed to override amp caps for NID 0x2\n");
19377}
19378
6cb3b707 19379enum {
2df03514 19380 ALC662_FIXUP_ASPIRE,
6cb3b707 19381 ALC662_FIXUP_IDEAPAD,
6be7948f 19382 ALC272_FIXUP_MARIO,
6cb3b707
DH
19383};
19384
19385static const struct alc_fixup alc662_fixups[] = {
2df03514
DC
19386 [ALC662_FIXUP_ASPIRE] = {
19387 .pins = (const struct alc_pincfg[]) {
19388 { 0x15, 0x99130112 }, /* subwoofer */
19389 { }
19390 }
19391 },
6cb3b707
DH
19392 [ALC662_FIXUP_IDEAPAD] = {
19393 .pins = (const struct alc_pincfg[]) {
19394 { 0x17, 0x99130112 }, /* subwoofer */
19395 { }
19396 }
19397 },
6be7948f
TB
19398 [ALC272_FIXUP_MARIO] = {
19399 .func = alc272_fixup_mario,
19400 }
6cb3b707
DH
19401};
19402
19403static struct snd_pci_quirk alc662_fixup_tbl[] = {
2df03514 19404 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19405 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19406 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707
DH
19407 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19408 {}
19409};
19410
6be7948f
TB
19411static const struct alc_model_fixup alc662_fixup_models[] = {
19412 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19413 {}
19414};
6cb3b707
DH
19415
19416
bc9f98a9
KY
19417static int patch_alc662(struct hda_codec *codec)
19418{
19419 struct alc_spec *spec;
19420 int err, board_config;
693194f3 19421 int coef;
bc9f98a9
KY
19422
19423 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19424 if (!spec)
19425 return -ENOMEM;
19426
19427 codec->spec = spec;
19428
da00c244
KY
19429 alc_auto_parse_customize_define(codec);
19430
2c3bf9ab
TI
19431 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19432
693194f3
KY
19433 coef = alc_read_coef_idx(codec, 0);
19434 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19435 alc_codec_rename(codec, "ALC661");
693194f3
KY
19436 else if (coef & (1 << 14) &&
19437 codec->bus->pci->subsystem_vendor == 0x1025 &&
19438 spec->cdefine.platform_type == 1)
c027ddcd 19439 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19440 else if (coef == 0x4011)
19441 alc_codec_rename(codec, "ALC656");
274693f3 19442
bc9f98a9
KY
19443 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19444 alc662_models,
19445 alc662_cfg_tbl);
19446 if (board_config < 0) {
9a11f1aa
TI
19447 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19448 codec->chip_name);
bc9f98a9
KY
19449 board_config = ALC662_AUTO;
19450 }
19451
19452 if (board_config == ALC662_AUTO) {
6cb3b707 19453 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1);
bc9f98a9
KY
19454 /* automatic parse from the BIOS config */
19455 err = alc662_parse_auto_config(codec);
19456 if (err < 0) {
19457 alc_free(codec);
19458 return err;
8c87286f 19459 } else if (!err) {
bc9f98a9
KY
19460 printk(KERN_INFO
19461 "hda_codec: Cannot set up configuration "
19462 "from BIOS. Using base mode...\n");
19463 board_config = ALC662_3ST_2ch_DIG;
19464 }
19465 }
19466
dc1eae25 19467 if (has_cdefine_beep(codec)) {
8af2591d
TI
19468 err = snd_hda_attach_beep_device(codec, 0x1);
19469 if (err < 0) {
19470 alc_free(codec);
19471 return err;
19472 }
680cd536
KK
19473 }
19474
bc9f98a9 19475 if (board_config != ALC662_AUTO)
e9c364c0 19476 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19477
bc9f98a9
KY
19478 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19479 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19480
bc9f98a9
KY
19481 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19482 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19483
dd704698
TI
19484 if (!spec->adc_nids) {
19485 spec->adc_nids = alc662_adc_nids;
19486 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19487 }
19488 if (!spec->capsrc_nids)
19489 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19490
f9e336f6 19491 if (!spec->cap_mixer)
b59bdf3b 19492 set_capture_mixer(codec);
cec27c89 19493
dc1eae25 19494 if (has_cdefine_beep(codec)) {
da00c244
KY
19495 switch (codec->vendor_id) {
19496 case 0x10ec0662:
19497 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19498 break;
19499 case 0x10ec0272:
19500 case 0x10ec0663:
19501 case 0x10ec0665:
19502 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19503 break;
19504 case 0x10ec0273:
19505 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19506 break;
19507 }
cec27c89 19508 }
2134ea4f
TI
19509 spec->vmaster_nid = 0x02;
19510
bc9f98a9 19511 codec->patch_ops = alc_patch_ops;
6cb3b707 19512 if (board_config == ALC662_AUTO) {
bc9f98a9 19513 spec->init_hook = alc662_auto_init;
6be7948f
TB
19514 alc_pick_fixup_model(codec, alc662_fixup_models,
19515 alc662_fixup_tbl, alc662_fixups, 0);
6cb3b707
DH
19516 }
19517
bf1b0225
KY
19518 alc_init_jacks(codec);
19519
cb53c626
TI
19520#ifdef CONFIG_SND_HDA_POWER_SAVE
19521 if (!spec->loopback.amplist)
19522 spec->loopback.amplist = alc662_loopbacks;
19523#endif
bc9f98a9
KY
19524
19525 return 0;
19526}
19527
274693f3
KY
19528static int patch_alc888(struct hda_codec *codec)
19529{
19530 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19531 kfree(codec->chip_name);
01e0f137
KY
19532 if (codec->vendor_id == 0x10ec0887)
19533 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19534 else
19535 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19536 if (!codec->chip_name) {
19537 alc_free(codec);
274693f3 19538 return -ENOMEM;
ac2c92e0
TI
19539 }
19540 return patch_alc662(codec);
274693f3 19541 }
ac2c92e0 19542 return patch_alc882(codec);
274693f3
KY
19543}
19544
d1eb57f4
KY
19545/*
19546 * ALC680 support
19547 */
c69aefab 19548#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19549#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19550#define alc680_modes alc260_modes
19551
19552static hda_nid_t alc680_dac_nids[3] = {
19553 /* Lout1, Lout2, hp */
19554 0x02, 0x03, 0x04
19555};
19556
19557static hda_nid_t alc680_adc_nids[3] = {
19558 /* ADC0-2 */
19559 /* DMIC, MIC, Line-in*/
19560 0x07, 0x08, 0x09
19561};
19562
c69aefab
KY
19563/*
19564 * Analog capture ADC cgange
19565 */
66ceeb6b
TI
19566static void alc680_rec_autoswitch(struct hda_codec *codec)
19567{
19568 struct alc_spec *spec = codec->spec;
19569 struct auto_pin_cfg *cfg = &spec->autocfg;
19570 int pin_found = 0;
19571 int type_found = AUTO_PIN_LAST;
19572 hda_nid_t nid;
19573 int i;
19574
19575 for (i = 0; i < cfg->num_inputs; i++) {
19576 nid = cfg->inputs[i].pin;
19577 if (!(snd_hda_query_pin_caps(codec, nid) &
19578 AC_PINCAP_PRES_DETECT))
19579 continue;
19580 if (snd_hda_jack_detect(codec, nid)) {
19581 if (cfg->inputs[i].type < type_found) {
19582 type_found = cfg->inputs[i].type;
19583 pin_found = nid;
19584 }
19585 }
19586 }
19587
19588 nid = 0x07;
19589 if (pin_found)
19590 snd_hda_get_connections(codec, pin_found, &nid, 1);
19591
19592 if (nid != spec->cur_adc)
19593 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19594 spec->cur_adc = nid;
19595 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19596 spec->cur_adc_format);
19597}
19598
c69aefab
KY
19599static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19600 struct hda_codec *codec,
19601 unsigned int stream_tag,
19602 unsigned int format,
19603 struct snd_pcm_substream *substream)
19604{
19605 struct alc_spec *spec = codec->spec;
c69aefab 19606
66ceeb6b 19607 spec->cur_adc = 0x07;
c69aefab
KY
19608 spec->cur_adc_stream_tag = stream_tag;
19609 spec->cur_adc_format = format;
19610
66ceeb6b 19611 alc680_rec_autoswitch(codec);
c69aefab
KY
19612 return 0;
19613}
19614
19615static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19616 struct hda_codec *codec,
19617 struct snd_pcm_substream *substream)
19618{
19619 snd_hda_codec_cleanup_stream(codec, 0x07);
19620 snd_hda_codec_cleanup_stream(codec, 0x08);
19621 snd_hda_codec_cleanup_stream(codec, 0x09);
19622 return 0;
19623}
19624
19625static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19626 .substreams = 1, /* can be overridden */
19627 .channels_min = 2,
19628 .channels_max = 2,
19629 /* NID is set in alc_build_pcms */
19630 .ops = {
19631 .prepare = alc680_capture_pcm_prepare,
19632 .cleanup = alc680_capture_pcm_cleanup
19633 },
19634};
19635
d1eb57f4
KY
19636static struct snd_kcontrol_new alc680_base_mixer[] = {
19637 /* output mixer control */
19638 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19639 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19640 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19642 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19643 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19644 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19645 { }
19646};
19647
c69aefab
KY
19648static struct hda_bind_ctls alc680_bind_cap_vol = {
19649 .ops = &snd_hda_bind_vol,
19650 .values = {
19651 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19652 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19653 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19654 0
19655 },
19656};
19657
19658static struct hda_bind_ctls alc680_bind_cap_switch = {
19659 .ops = &snd_hda_bind_sw,
19660 .values = {
19661 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19662 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19663 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19664 0
19665 },
19666};
19667
19668static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19669 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19670 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19671 { } /* end */
19672};
19673
19674/*
19675 * generic initialization of ADC, input mixers and output mixers
19676 */
19677static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19678 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19679 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19680 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19681
c69aefab
KY
19682 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19683 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19684 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19685 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19686 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19687 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19688
19689 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19691 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19693 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19694
19695 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19696 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19697 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19698
d1eb57f4
KY
19699 { }
19700};
19701
c69aefab
KY
19702/* toggle speaker-output according to the hp-jack state */
19703static void alc680_base_setup(struct hda_codec *codec)
19704{
19705 struct alc_spec *spec = codec->spec;
19706
19707 spec->autocfg.hp_pins[0] = 0x16;
19708 spec->autocfg.speaker_pins[0] = 0x14;
19709 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19710 spec->autocfg.num_inputs = 2;
19711 spec->autocfg.inputs[0].pin = 0x18;
19712 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19713 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19714 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19715}
19716
19717static void alc680_unsol_event(struct hda_codec *codec,
19718 unsigned int res)
19719{
19720 if ((res >> 26) == ALC880_HP_EVENT)
19721 alc_automute_amp(codec);
19722 if ((res >> 26) == ALC880_MIC_EVENT)
19723 alc680_rec_autoswitch(codec);
19724}
19725
19726static void alc680_inithook(struct hda_codec *codec)
19727{
19728 alc_automute_amp(codec);
19729 alc680_rec_autoswitch(codec);
19730}
19731
d1eb57f4
KY
19732/* create input playback/capture controls for the given pin */
19733static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19734 const char *ctlname, int idx)
19735{
19736 hda_nid_t dac;
19737 int err;
19738
19739 switch (nid) {
19740 case 0x14:
19741 dac = 0x02;
19742 break;
19743 case 0x15:
19744 dac = 0x03;
19745 break;
19746 case 0x16:
19747 dac = 0x04;
19748 break;
19749 default:
19750 return 0;
19751 }
19752 if (spec->multiout.dac_nids[0] != dac &&
19753 spec->multiout.dac_nids[1] != dac) {
19754 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19755 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19756 HDA_OUTPUT));
19757 if (err < 0)
19758 return err;
19759
19760 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19761 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19762
19763 if (err < 0)
19764 return err;
19765 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19766 }
19767
19768 return 0;
19769}
19770
19771/* add playback controls from the parsed DAC table */
19772static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19773 const struct auto_pin_cfg *cfg)
19774{
19775 hda_nid_t nid;
19776 int err;
19777
19778 spec->multiout.dac_nids = spec->private_dac_nids;
19779
19780 nid = cfg->line_out_pins[0];
19781 if (nid) {
19782 const char *name;
19783 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19784 name = "Speaker";
19785 else
19786 name = "Front";
19787 err = alc680_new_analog_output(spec, nid, name, 0);
19788 if (err < 0)
19789 return err;
19790 }
19791
19792 nid = cfg->speaker_pins[0];
19793 if (nid) {
19794 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19795 if (err < 0)
19796 return err;
19797 }
19798 nid = cfg->hp_pins[0];
19799 if (nid) {
19800 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19801 if (err < 0)
19802 return err;
19803 }
19804
19805 return 0;
19806}
19807
19808static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19809 hda_nid_t nid, int pin_type)
19810{
19811 alc_set_pin_output(codec, nid, pin_type);
19812}
19813
19814static void alc680_auto_init_multi_out(struct hda_codec *codec)
19815{
19816 struct alc_spec *spec = codec->spec;
19817 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19818 if (nid) {
19819 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19820 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19821 }
19822}
19823
19824static void alc680_auto_init_hp_out(struct hda_codec *codec)
19825{
19826 struct alc_spec *spec = codec->spec;
19827 hda_nid_t pin;
19828
19829 pin = spec->autocfg.hp_pins[0];
19830 if (pin)
19831 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19832 pin = spec->autocfg.speaker_pins[0];
19833 if (pin)
19834 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19835}
19836
19837/* pcm configuration: identical with ALC880 */
19838#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19839#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19840#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19841#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19842#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19843
19844/*
19845 * BIOS auto configuration
19846 */
19847static int alc680_parse_auto_config(struct hda_codec *codec)
19848{
19849 struct alc_spec *spec = codec->spec;
19850 int err;
19851 static hda_nid_t alc680_ignore[] = { 0 };
19852
19853 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19854 alc680_ignore);
19855 if (err < 0)
19856 return err;
c69aefab 19857
d1eb57f4
KY
19858 if (!spec->autocfg.line_outs) {
19859 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19860 spec->multiout.max_channels = 2;
19861 spec->no_analog = 1;
19862 goto dig_only;
19863 }
19864 return 0; /* can't find valid BIOS pin config */
19865 }
19866 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19867 if (err < 0)
19868 return err;
19869
19870 spec->multiout.max_channels = 2;
19871
19872 dig_only:
19873 /* digital only support output */
757899ac 19874 alc_auto_parse_digital(codec);
d1eb57f4
KY
19875 if (spec->kctls.list)
19876 add_mixer(spec, spec->kctls.list);
19877
19878 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19879
19880 err = alc_auto_add_mic_boost(codec);
19881 if (err < 0)
19882 return err;
19883
19884 return 1;
19885}
19886
19887#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19888
19889/* init callback for auto-configuration model -- overriding the default init */
19890static void alc680_auto_init(struct hda_codec *codec)
19891{
19892 struct alc_spec *spec = codec->spec;
19893 alc680_auto_init_multi_out(codec);
19894 alc680_auto_init_hp_out(codec);
19895 alc680_auto_init_analog_input(codec);
757899ac 19896 alc_auto_init_digital(codec);
d1eb57f4
KY
19897 if (spec->unsol_event)
19898 alc_inithook(codec);
19899}
19900
19901/*
19902 * configuration and preset
19903 */
19904static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19905 [ALC680_BASE] = "base",
19906 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19907};
19908
19909static struct snd_pci_quirk alc680_cfg_tbl[] = {
19910 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19911 {}
19912};
19913
19914static struct alc_config_preset alc680_presets[] = {
19915 [ALC680_BASE] = {
19916 .mixers = { alc680_base_mixer },
c69aefab 19917 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19918 .init_verbs = { alc680_init_verbs },
19919 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19920 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19921 .dig_out_nid = ALC680_DIGOUT_NID,
19922 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19923 .channel_mode = alc680_modes,
c69aefab
KY
19924 .unsol_event = alc680_unsol_event,
19925 .setup = alc680_base_setup,
19926 .init_hook = alc680_inithook,
19927
d1eb57f4
KY
19928 },
19929};
19930
19931static int patch_alc680(struct hda_codec *codec)
19932{
19933 struct alc_spec *spec;
19934 int board_config;
19935 int err;
19936
19937 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19938 if (spec == NULL)
19939 return -ENOMEM;
19940
19941 codec->spec = spec;
19942
19943 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19944 alc680_models,
19945 alc680_cfg_tbl);
19946
19947 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19948 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19949 codec->chip_name);
19950 board_config = ALC680_AUTO;
19951 }
19952
19953 if (board_config == ALC680_AUTO) {
19954 /* automatic parse from the BIOS config */
19955 err = alc680_parse_auto_config(codec);
19956 if (err < 0) {
19957 alc_free(codec);
19958 return err;
19959 } else if (!err) {
19960 printk(KERN_INFO
19961 "hda_codec: Cannot set up configuration "
19962 "from BIOS. Using base mode...\n");
19963 board_config = ALC680_BASE;
19964 }
19965 }
19966
19967 if (board_config != ALC680_AUTO)
19968 setup_preset(codec, &alc680_presets[board_config]);
19969
19970 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19971 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19972 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19973 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19974
19975 if (!spec->adc_nids) {
19976 spec->adc_nids = alc680_adc_nids;
19977 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19978 }
19979
19980 if (!spec->cap_mixer)
19981 set_capture_mixer(codec);
19982
19983 spec->vmaster_nid = 0x02;
19984
19985 codec->patch_ops = alc_patch_ops;
19986 if (board_config == ALC680_AUTO)
19987 spec->init_hook = alc680_auto_init;
19988
19989 return 0;
19990}
19991
1da177e4
LT
19992/*
19993 * patch entries
19994 */
1289e9e8 19995static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19996 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19997 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19998 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19999 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20000 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20001 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20002 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20003 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20004 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20005 .patch = patch_alc861 },
f32610ed
JS
20006 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20007 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20008 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20009 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20010 .patch = patch_alc882 },
bc9f98a9
KY
20011 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20012 .patch = patch_alc662 },
6dda9f4a 20013 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20014 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20015 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20016 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20017 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20018 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20019 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20020 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20021 .patch = patch_alc882 },
cb308f97 20022 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20023 .patch = patch_alc882 },
df694daa 20024 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20025 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20026 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20027 .patch = patch_alc882 },
274693f3 20028 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20029 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20030 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20031 {} /* terminator */
20032};
1289e9e8
TI
20033
20034MODULE_ALIAS("snd-hda-codec-id:10ec*");
20035
20036MODULE_LICENSE("GPL");
20037MODULE_DESCRIPTION("Realtek HD-audio codec");
20038
20039static struct hda_codec_preset_list realtek_list = {
20040 .preset = snd_hda_preset_realtek,
20041 .owner = THIS_MODULE,
20042};
20043
20044static int __init patch_realtek_init(void)
20045{
20046 return snd_hda_add_codec_preset(&realtek_list);
20047}
20048
20049static void __exit patch_realtek_exit(void)
20050{
20051 snd_hda_delete_codec_preset(&realtek_list);
20052}
20053
20054module_init(patch_realtek_init)
20055module_exit(patch_realtek_exit)