]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda: Disable 4/6 channels on some NVIDIA GPUs.
[mirror_ubuntu-bionic-kernel.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
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},
2029 { }
2030};
2031
d2fd4b09
TV
2032/*
2033 * ALC888 Acer Aspire 6530G model
2034 */
2035
2036static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2037/* Route to built-in subwoofer as well as speakers */
2038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2039 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2040 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2041 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2042/* Bias voltage on for external mic port */
2043 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2044/* Front Mic: set to PIN_IN (empty by default) */
2045 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2046/* Unselect Front Mic by default in input mixer 3 */
2047 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2048/* Enable unsolicited event for HP jack */
2049 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2050/* Enable speaker output */
2051 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2052 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2053 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2054/* Enable headphone output */
2055 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2056 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2057 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2058 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2059 { }
2060};
2061
d9477207
DK
2062/*
2063 *ALC888 Acer Aspire 7730G model
2064 */
2065
2066static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2067/* Bias voltage on for external mic port */
2068 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2069/* Front Mic: set to PIN_IN (empty by default) */
2070 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2071/* Unselect Front Mic by default in input mixer 3 */
2072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2073/* Enable unsolicited event for HP jack */
2074 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2075/* Enable speaker output */
2076 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2077 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2078 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2079/* Enable headphone output */
2080 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2081 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2082 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2083 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2084/*Enable internal subwoofer */
2085 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2086 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2087 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2088 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2089 { }
2090};
2091
3b315d70 2092/*
018df418 2093 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2094 */
2095
018df418 2096static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2097/* Front Mic: set to PIN_IN (empty by default) */
2098 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2099/* Unselect Front Mic by default in input mixer 3 */
2100 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2101/* Enable unsolicited event for HP jack */
2102 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2103/* Connect Internal Front to Front */
2104 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2105 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2106 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2107/* Connect Internal Rear to Rear */
2108 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2109 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2110 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2111/* Connect Internal CLFE to CLFE */
2112 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2113 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2114 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2115/* Connect HP out to Front */
018df418 2116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2117 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2118 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2119/* Enable all DACs */
2120/* DAC DISABLE/MUTE 1? */
2121/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2122 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2123 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2124/* DAC DISABLE/MUTE 2? */
2125/* some bit here disables the other DACs. Init=0x4900 */
2126 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2127 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2128/* DMIC fix
2129 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2130 * which makes the stereo useless. However, either the mic or the ALC889
2131 * makes the signal become a difference/sum signal instead of standard
2132 * stereo, which is annoying. So instead we flip this bit which makes the
2133 * codec replicate the sum signal to both channels, turning it into a
2134 * normal mono mic.
2135 */
2136/* DMIC_CONTROL? Init value = 0x0001 */
2137 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2138 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2139 { }
2140};
2141
ef8ef5fb 2142static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2143 /* Front mic only available on one ADC */
2144 {
2145 .num_items = 4,
2146 .items = {
2147 { "Mic", 0x0 },
2148 { "Line", 0x2 },
2149 { "CD", 0x4 },
2150 { "Front Mic", 0xb },
2151 },
2152 },
2153 {
2154 .num_items = 3,
2155 .items = {
2156 { "Mic", 0x0 },
2157 { "Line", 0x2 },
2158 { "CD", 0x4 },
2159 },
2160 }
2161};
2162
d2fd4b09
TV
2163static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2164 /* Interal mic only available on one ADC */
2165 {
684a8842 2166 .num_items = 5,
d2fd4b09 2167 .items = {
8607f7c4 2168 { "Mic", 0x0 },
684a8842 2169 { "Line In", 0x2 },
d2fd4b09 2170 { "CD", 0x4 },
684a8842 2171 { "Input Mix", 0xa },
28c4edb7 2172 { "Internal Mic", 0xb },
d2fd4b09
TV
2173 },
2174 },
2175 {
684a8842 2176 .num_items = 4,
d2fd4b09 2177 .items = {
8607f7c4 2178 { "Mic", 0x0 },
684a8842 2179 { "Line In", 0x2 },
d2fd4b09 2180 { "CD", 0x4 },
684a8842 2181 { "Input Mix", 0xa },
d2fd4b09
TV
2182 },
2183 }
2184};
2185
018df418
HM
2186static struct hda_input_mux alc889_capture_sources[3] = {
2187 /* Digital mic only available on first "ADC" */
2188 {
2189 .num_items = 5,
2190 .items = {
2191 { "Mic", 0x0 },
2192 { "Line", 0x2 },
2193 { "CD", 0x4 },
2194 { "Front Mic", 0xb },
2195 { "Input Mix", 0xa },
2196 },
2197 },
2198 {
2199 .num_items = 4,
2200 .items = {
2201 { "Mic", 0x0 },
2202 { "Line", 0x2 },
2203 { "CD", 0x4 },
2204 { "Input Mix", 0xa },
2205 },
2206 },
2207 {
2208 .num_items = 4,
2209 .items = {
2210 { "Mic", 0x0 },
2211 { "Line", 0x2 },
2212 { "CD", 0x4 },
2213 { "Input Mix", 0xa },
2214 },
2215 }
2216};
2217
ef8ef5fb 2218static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2219 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2220 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2221 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2222 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2223 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2224 HDA_OUTPUT),
2225 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2226 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2227 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2228 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2229 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2230 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2231 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2232 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2233 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2234 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2235 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2236 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2237 { } /* end */
2238};
2239
556eea9a
HM
2240static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2241 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2242 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2243 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2244 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2245 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2246 HDA_OUTPUT),
2247 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2248 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2249 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2250 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2251 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2252 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2253 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2254 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2255 { } /* end */
2256};
2257
2258
4f5d1706 2259static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2260{
a9fd4f3f 2261 struct alc_spec *spec = codec->spec;
5b2d1eca 2262
a9fd4f3f
TI
2263 spec->autocfg.hp_pins[0] = 0x15;
2264 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2265 spec->autocfg.speaker_pins[1] = 0x16;
2266 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2267}
2268
4f5d1706 2269static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2270{
2271 struct alc_spec *spec = codec->spec;
2272
2273 spec->autocfg.hp_pins[0] = 0x15;
2274 spec->autocfg.speaker_pins[0] = 0x14;
2275 spec->autocfg.speaker_pins[1] = 0x16;
2276 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2277}
2278
d9477207
DK
2279static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2280{
2281 struct alc_spec *spec = codec->spec;
2282
2283 spec->autocfg.hp_pins[0] = 0x15;
2284 spec->autocfg.speaker_pins[0] = 0x14;
2285 spec->autocfg.speaker_pins[1] = 0x16;
2286 spec->autocfg.speaker_pins[2] = 0x17;
2287}
2288
4f5d1706 2289static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2290{
2291 struct alc_spec *spec = codec->spec;
2292
2293 spec->autocfg.hp_pins[0] = 0x15;
2294 spec->autocfg.speaker_pins[0] = 0x14;
2295 spec->autocfg.speaker_pins[1] = 0x16;
2296 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2297}
2298
1da177e4 2299/*
e9edcee0
TI
2300 * ALC880 3-stack model
2301 *
2302 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2303 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2304 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2305 */
2306
e9edcee0
TI
2307static hda_nid_t alc880_dac_nids[4] = {
2308 /* front, rear, clfe, rear_surr */
2309 0x02, 0x05, 0x04, 0x03
2310};
2311
2312static hda_nid_t alc880_adc_nids[3] = {
2313 /* ADC0-2 */
2314 0x07, 0x08, 0x09,
2315};
2316
2317/* The datasheet says the node 0x07 is connected from inputs,
2318 * but it shows zero connection in the real implementation on some devices.
df694daa 2319 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2320 */
e9edcee0
TI
2321static hda_nid_t alc880_adc_nids_alt[2] = {
2322 /* ADC1-2 */
2323 0x08, 0x09,
2324};
2325
2326#define ALC880_DIGOUT_NID 0x06
2327#define ALC880_DIGIN_NID 0x0a
2328
2329static struct hda_input_mux alc880_capture_source = {
2330 .num_items = 4,
2331 .items = {
2332 { "Mic", 0x0 },
2333 { "Front Mic", 0x3 },
2334 { "Line", 0x2 },
2335 { "CD", 0x4 },
2336 },
2337};
2338
2339/* channel source setting (2/6 channel selection for 3-stack) */
2340/* 2ch mode */
2341static struct hda_verb alc880_threestack_ch2_init[] = {
2342 /* set line-in to input, mute it */
2343 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2344 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2345 /* set mic-in to input vref 80%, mute it */
2346 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2347 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2348 { } /* end */
2349};
2350
2351/* 6ch mode */
2352static struct hda_verb alc880_threestack_ch6_init[] = {
2353 /* set line-in to output, unmute it */
2354 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2355 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2356 /* set mic-in to output, unmute it */
2357 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2358 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2359 { } /* end */
2360};
2361
d2a6d7dc 2362static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2363 { 2, alc880_threestack_ch2_init },
2364 { 6, alc880_threestack_ch6_init },
2365};
2366
c8b6bf9b 2367static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2368 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2369 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2370 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2371 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2372 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2373 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2374 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2375 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2376 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2377 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2378 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2379 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2380 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2381 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2382 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2383 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2385 {
2386 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2387 .name = "Channel Mode",
df694daa
KY
2388 .info = alc_ch_mode_info,
2389 .get = alc_ch_mode_get,
2390 .put = alc_ch_mode_put,
e9edcee0
TI
2391 },
2392 { } /* end */
2393};
2394
2395/* capture mixer elements */
f9e336f6
TI
2396static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2397 struct snd_ctl_elem_info *uinfo)
2398{
2399 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2400 struct alc_spec *spec = codec->spec;
2401 int err;
1da177e4 2402
5a9e02e9 2403 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2404 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2405 HDA_INPUT);
2406 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2407 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2408 return err;
2409}
2410
2411static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2412 unsigned int size, unsigned int __user *tlv)
2413{
2414 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2415 struct alc_spec *spec = codec->spec;
2416 int err;
1da177e4 2417
5a9e02e9 2418 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2419 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2420 HDA_INPUT);
2421 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2422 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2423 return err;
2424}
2425
2426typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2427 struct snd_ctl_elem_value *ucontrol);
2428
2429static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2430 struct snd_ctl_elem_value *ucontrol,
2431 getput_call_t func)
2432{
2433 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2434 struct alc_spec *spec = codec->spec;
2435 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2436 int err;
2437
5a9e02e9 2438 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2439 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2440 3, 0, HDA_INPUT);
2441 err = func(kcontrol, ucontrol);
5a9e02e9 2442 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2443 return err;
2444}
2445
2446static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2447 struct snd_ctl_elem_value *ucontrol)
2448{
2449 return alc_cap_getput_caller(kcontrol, ucontrol,
2450 snd_hda_mixer_amp_volume_get);
2451}
2452
2453static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2454 struct snd_ctl_elem_value *ucontrol)
2455{
2456 return alc_cap_getput_caller(kcontrol, ucontrol,
2457 snd_hda_mixer_amp_volume_put);
2458}
2459
2460/* capture mixer elements */
2461#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2462
2463static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2464 struct snd_ctl_elem_value *ucontrol)
2465{
2466 return alc_cap_getput_caller(kcontrol, ucontrol,
2467 snd_hda_mixer_amp_switch_get);
2468}
2469
2470static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2471 struct snd_ctl_elem_value *ucontrol)
2472{
2473 return alc_cap_getput_caller(kcontrol, ucontrol,
2474 snd_hda_mixer_amp_switch_put);
2475}
2476
a23b688f 2477#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2478 { \
2479 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2480 .name = "Capture Switch", \
2481 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2482 .count = num, \
2483 .info = alc_cap_sw_info, \
2484 .get = alc_cap_sw_get, \
2485 .put = alc_cap_sw_put, \
2486 }, \
2487 { \
2488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2489 .name = "Capture Volume", \
2490 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2491 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2492 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2493 .count = num, \
2494 .info = alc_cap_vol_info, \
2495 .get = alc_cap_vol_get, \
2496 .put = alc_cap_vol_put, \
2497 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2498 }
2499
2500#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2501 { \
2502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2503 /* .name = "Capture Source", */ \
2504 .name = "Input Source", \
2505 .count = num, \
2506 .info = alc_mux_enum_info, \
2507 .get = alc_mux_enum_get, \
2508 .put = alc_mux_enum_put, \
a23b688f
TI
2509 }
2510
2511#define DEFINE_CAPMIX(num) \
2512static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2513 _DEFINE_CAPMIX(num), \
2514 _DEFINE_CAPSRC(num), \
2515 { } /* end */ \
2516}
2517
2518#define DEFINE_CAPMIX_NOSRC(num) \
2519static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2520 _DEFINE_CAPMIX(num), \
2521 { } /* end */ \
f9e336f6
TI
2522}
2523
2524/* up to three ADCs */
2525DEFINE_CAPMIX(1);
2526DEFINE_CAPMIX(2);
2527DEFINE_CAPMIX(3);
a23b688f
TI
2528DEFINE_CAPMIX_NOSRC(1);
2529DEFINE_CAPMIX_NOSRC(2);
2530DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2531
2532/*
2533 * ALC880 5-stack model
2534 *
9c7f852e
TI
2535 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2536 * Side = 0x02 (0xd)
e9edcee0
TI
2537 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2538 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2539 */
2540
2541/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2542static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2543 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2544 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2545 { } /* end */
2546};
2547
e9edcee0
TI
2548/* channel source setting (6/8 channel selection for 5-stack) */
2549/* 6ch mode */
2550static struct hda_verb alc880_fivestack_ch6_init[] = {
2551 /* set line-in to input, mute it */
2552 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2553 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2554 { } /* end */
2555};
2556
e9edcee0
TI
2557/* 8ch mode */
2558static struct hda_verb alc880_fivestack_ch8_init[] = {
2559 /* set line-in to output, unmute it */
2560 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2561 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2562 { } /* end */
2563};
2564
d2a6d7dc 2565static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2566 { 6, alc880_fivestack_ch6_init },
2567 { 8, alc880_fivestack_ch8_init },
2568};
2569
2570
2571/*
2572 * ALC880 6-stack model
2573 *
9c7f852e
TI
2574 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2575 * Side = 0x05 (0x0f)
e9edcee0
TI
2576 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2577 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2578 */
2579
2580static hda_nid_t alc880_6st_dac_nids[4] = {
2581 /* front, rear, clfe, rear_surr */
2582 0x02, 0x03, 0x04, 0x05
f12ab1e0 2583};
e9edcee0
TI
2584
2585static struct hda_input_mux alc880_6stack_capture_source = {
2586 .num_items = 4,
2587 .items = {
2588 { "Mic", 0x0 },
2589 { "Front Mic", 0x1 },
2590 { "Line", 0x2 },
2591 { "CD", 0x4 },
2592 },
2593};
2594
2595/* fixed 8-channels */
d2a6d7dc 2596static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2597 { 8, NULL },
2598};
2599
c8b6bf9b 2600static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2601 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2602 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2603 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2604 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2605 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2606 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2607 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2608 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2609 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2610 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2611 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2612 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2613 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2614 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2615 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2616 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2617 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2618 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2619 {
2620 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2621 .name = "Channel Mode",
df694daa
KY
2622 .info = alc_ch_mode_info,
2623 .get = alc_ch_mode_get,
2624 .put = alc_ch_mode_put,
16ded525
TI
2625 },
2626 { } /* end */
2627};
2628
e9edcee0
TI
2629
2630/*
2631 * ALC880 W810 model
2632 *
2633 * W810 has rear IO for:
2634 * Front (DAC 02)
2635 * Surround (DAC 03)
2636 * Center/LFE (DAC 04)
2637 * Digital out (06)
2638 *
2639 * The system also has a pair of internal speakers, and a headphone jack.
2640 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2641 *
e9edcee0
TI
2642 * There is a variable resistor to control the speaker or headphone
2643 * volume. This is a hardware-only device without a software API.
2644 *
2645 * Plugging headphones in will disable the internal speakers. This is
2646 * implemented in hardware, not via the driver using jack sense. In
2647 * a similar fashion, plugging into the rear socket marked "front" will
2648 * disable both the speakers and headphones.
2649 *
2650 * For input, there's a microphone jack, and an "audio in" jack.
2651 * These may not do anything useful with this driver yet, because I
2652 * haven't setup any initialization verbs for these yet...
2653 */
2654
2655static hda_nid_t alc880_w810_dac_nids[3] = {
2656 /* front, rear/surround, clfe */
2657 0x02, 0x03, 0x04
16ded525
TI
2658};
2659
e9edcee0 2660/* fixed 6 channels */
d2a6d7dc 2661static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2662 { 6, NULL }
2663};
2664
2665/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2666static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2667 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2668 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2669 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2670 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2671 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2672 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2673 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2674 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2675 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2676 { } /* end */
2677};
2678
2679
2680/*
2681 * Z710V model
2682 *
2683 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2684 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2685 * Line = 0x1a
e9edcee0
TI
2686 */
2687
2688static hda_nid_t alc880_z71v_dac_nids[1] = {
2689 0x02
2690};
2691#define ALC880_Z71V_HP_DAC 0x03
2692
2693/* fixed 2 channels */
d2a6d7dc 2694static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2695 { 2, NULL }
2696};
2697
c8b6bf9b 2698static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2699 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2700 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2701 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2702 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2703 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2704 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2705 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2706 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2707 { } /* end */
2708};
2709
e9edcee0 2710
e9edcee0
TI
2711/*
2712 * ALC880 F1734 model
2713 *
2714 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2715 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2716 */
2717
2718static hda_nid_t alc880_f1734_dac_nids[1] = {
2719 0x03
2720};
2721#define ALC880_F1734_HP_DAC 0x02
2722
c8b6bf9b 2723static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2724 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2725 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2726 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2727 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2728 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2729 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2731 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2732 { } /* end */
2733};
2734
937b4160
TI
2735static struct hda_input_mux alc880_f1734_capture_source = {
2736 .num_items = 2,
2737 .items = {
2738 { "Mic", 0x1 },
2739 { "CD", 0x4 },
2740 },
2741};
2742
e9edcee0 2743
e9edcee0
TI
2744/*
2745 * ALC880 ASUS model
2746 *
2747 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2748 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2749 * Mic = 0x18, Line = 0x1a
2750 */
2751
2752#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2753#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2754
c8b6bf9b 2755static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2756 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2757 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2758 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2759 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2760 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2761 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2762 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2763 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2764 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2765 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2766 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2767 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2768 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2769 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2770 {
2771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2772 .name = "Channel Mode",
df694daa
KY
2773 .info = alc_ch_mode_info,
2774 .get = alc_ch_mode_get,
2775 .put = alc_ch_mode_put,
16ded525
TI
2776 },
2777 { } /* end */
2778};
e9edcee0 2779
e9edcee0
TI
2780/*
2781 * ALC880 ASUS W1V model
2782 *
2783 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2784 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2785 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2786 */
2787
2788/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2789static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2790 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2791 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2792 { } /* end */
2793};
2794
df694daa
KY
2795/* TCL S700 */
2796static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2797 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2798 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2799 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2800 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2801 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2802 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2803 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2804 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2805 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2806 { } /* end */
2807};
2808
ccc656ce
KY
2809/* Uniwill */
2810static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2811 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2812 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2813 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2814 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2815 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2816 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2817 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2818 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2819 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2820 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2821 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2822 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2824 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2825 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2826 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2827 {
2828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2829 .name = "Channel Mode",
2830 .info = alc_ch_mode_info,
2831 .get = alc_ch_mode_get,
2832 .put = alc_ch_mode_put,
2833 },
2834 { } /* end */
2835};
2836
2cf9f0fc
TD
2837static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2838 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2839 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2840 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2841 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2842 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2843 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
2844 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2845 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
2846 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2847 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
2848 { } /* end */
2849};
2850
ccc656ce 2851static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2852 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2853 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2854 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2855 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2858 { } /* end */
2859};
2860
2134ea4f
TI
2861/*
2862 * virtual master controls
2863 */
2864
2865/*
2866 * slave controls for virtual master
2867 */
2868static const char *alc_slave_vols[] = {
2869 "Front Playback Volume",
2870 "Surround Playback Volume",
2871 "Center Playback Volume",
2872 "LFE Playback Volume",
2873 "Side Playback Volume",
2874 "Headphone Playback Volume",
2875 "Speaker Playback Volume",
2876 "Mono Playback Volume",
2134ea4f 2877 "Line-Out Playback Volume",
26f5df26 2878 "PCM Playback Volume",
2134ea4f
TI
2879 NULL,
2880};
2881
2882static const char *alc_slave_sws[] = {
2883 "Front Playback Switch",
2884 "Surround Playback Switch",
2885 "Center Playback Switch",
2886 "LFE Playback Switch",
2887 "Side Playback Switch",
2888 "Headphone Playback Switch",
2889 "Speaker Playback Switch",
2890 "Mono Playback Switch",
edb54a55 2891 "IEC958 Playback Switch",
23033b2b
TI
2892 "Line-Out Playback Switch",
2893 "PCM Playback Switch",
2134ea4f
TI
2894 NULL,
2895};
2896
1da177e4 2897/*
e9edcee0 2898 * build control elements
1da177e4 2899 */
603c4019 2900
5b0cb1d8
JK
2901#define NID_MAPPING (-1)
2902
2903#define SUBDEV_SPEAKER_ (0 << 6)
2904#define SUBDEV_HP_ (1 << 6)
2905#define SUBDEV_LINE_ (2 << 6)
2906#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2907#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2908#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2909
603c4019
TI
2910static void alc_free_kctls(struct hda_codec *codec);
2911
67d634c0 2912#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2913/* additional beep mixers; the actual parameters are overwritten at build */
2914static struct snd_kcontrol_new alc_beep_mixer[] = {
2915 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2916 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2917 { } /* end */
2918};
67d634c0 2919#endif
45bdd1c1 2920
1da177e4
LT
2921static int alc_build_controls(struct hda_codec *codec)
2922{
2923 struct alc_spec *spec = codec->spec;
2f44f847 2924 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2925 struct snd_kcontrol_new *knew;
2926 int i, j, err;
2927 unsigned int u;
2928 hda_nid_t nid;
1da177e4
LT
2929
2930 for (i = 0; i < spec->num_mixers; i++) {
2931 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2932 if (err < 0)
2933 return err;
2934 }
f9e336f6
TI
2935 if (spec->cap_mixer) {
2936 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2937 if (err < 0)
2938 return err;
2939 }
1da177e4 2940 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2941 err = snd_hda_create_spdif_out_ctls(codec,
2942 spec->multiout.dig_out_nid);
1da177e4
LT
2943 if (err < 0)
2944 return err;
e64f14f4
TI
2945 if (!spec->no_analog) {
2946 err = snd_hda_create_spdif_share_sw(codec,
2947 &spec->multiout);
2948 if (err < 0)
2949 return err;
2950 spec->multiout.share_spdif = 1;
2951 }
1da177e4
LT
2952 }
2953 if (spec->dig_in_nid) {
2954 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2955 if (err < 0)
2956 return err;
2957 }
2134ea4f 2958
67d634c0 2959#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2960 /* create beep controls if needed */
2961 if (spec->beep_amp) {
2962 struct snd_kcontrol_new *knew;
2963 for (knew = alc_beep_mixer; knew->name; knew++) {
2964 struct snd_kcontrol *kctl;
2965 kctl = snd_ctl_new1(knew, codec);
2966 if (!kctl)
2967 return -ENOMEM;
2968 kctl->private_value = spec->beep_amp;
5e26dfd0 2969 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2970 if (err < 0)
2971 return err;
2972 }
2973 }
67d634c0 2974#endif
45bdd1c1 2975
2134ea4f 2976 /* if we have no master control, let's create it */
e64f14f4
TI
2977 if (!spec->no_analog &&
2978 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2979 unsigned int vmaster_tlv[4];
2134ea4f 2980 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2981 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2982 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2983 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2984 if (err < 0)
2985 return err;
2986 }
e64f14f4
TI
2987 if (!spec->no_analog &&
2988 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2989 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2990 NULL, alc_slave_sws);
2991 if (err < 0)
2992 return err;
2993 }
2994
5b0cb1d8 2995 /* assign Capture Source enums to NID */
fbe618f2
TI
2996 if (spec->capsrc_nids || spec->adc_nids) {
2997 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2998 if (!kctl)
2999 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3000 for (i = 0; kctl && i < kctl->count; i++) {
3001 hda_nid_t *nids = spec->capsrc_nids;
3002 if (!nids)
3003 nids = spec->adc_nids;
3004 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3005 if (err < 0)
3006 return err;
3007 }
5b0cb1d8
JK
3008 }
3009 if (spec->cap_mixer) {
3010 const char *kname = kctl ? kctl->id.name : NULL;
3011 for (knew = spec->cap_mixer; knew->name; knew++) {
3012 if (kname && strcmp(knew->name, kname) == 0)
3013 continue;
3014 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3015 for (i = 0; kctl && i < kctl->count; i++) {
3016 err = snd_hda_add_nid(codec, kctl, i,
3017 spec->adc_nids[i]);
3018 if (err < 0)
3019 return err;
3020 }
3021 }
3022 }
3023
3024 /* other nid->control mapping */
3025 for (i = 0; i < spec->num_mixers; i++) {
3026 for (knew = spec->mixers[i]; knew->name; knew++) {
3027 if (knew->iface != NID_MAPPING)
3028 continue;
3029 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3030 if (kctl == NULL)
3031 continue;
3032 u = knew->subdevice;
3033 for (j = 0; j < 4; j++, u >>= 8) {
3034 nid = u & 0x3f;
3035 if (nid == 0)
3036 continue;
3037 switch (u & 0xc0) {
3038 case SUBDEV_SPEAKER_:
3039 nid = spec->autocfg.speaker_pins[nid];
3040 break;
3041 case SUBDEV_LINE_:
3042 nid = spec->autocfg.line_out_pins[nid];
3043 break;
3044 case SUBDEV_HP_:
3045 nid = spec->autocfg.hp_pins[nid];
3046 break;
3047 default:
3048 continue;
3049 }
3050 err = snd_hda_add_nid(codec, kctl, 0, nid);
3051 if (err < 0)
3052 return err;
3053 }
3054 u = knew->private_value;
3055 for (j = 0; j < 4; j++, u >>= 8) {
3056 nid = u & 0xff;
3057 if (nid == 0)
3058 continue;
3059 err = snd_hda_add_nid(codec, kctl, 0, nid);
3060 if (err < 0)
3061 return err;
3062 }
3063 }
3064 }
bae84e70
TI
3065
3066 alc_free_kctls(codec); /* no longer needed */
3067
1da177e4
LT
3068 return 0;
3069}
3070
e9edcee0 3071
1da177e4
LT
3072/*
3073 * initialize the codec volumes, etc
3074 */
3075
e9edcee0
TI
3076/*
3077 * generic initialization of ADC, input mixers and output mixers
3078 */
3079static struct hda_verb alc880_volume_init_verbs[] = {
3080 /*
3081 * Unmute ADC0-2 and set the default input to mic-in
3082 */
71fe7b82 3083 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3084 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3085 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3086 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3087 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3088 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3089
e9edcee0
TI
3090 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3091 * mixer widget
9c7f852e
TI
3092 * Note: PASD motherboards uses the Line In 2 as the input for front
3093 * panel mic (mic 2)
1da177e4 3094 */
e9edcee0 3095 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3103
e9edcee0
TI
3104 /*
3105 * Set up output mixers (0x0c - 0x0f)
1da177e4 3106 */
e9edcee0
TI
3107 /* set vol=0 to output mixers */
3108 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3109 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3111 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3112 /* set up input amps for analog loopback */
3113 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3116 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3117 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3118 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3119 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3120 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3121 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3122
3123 { }
3124};
3125
e9edcee0
TI
3126/*
3127 * 3-stack pin configuration:
3128 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3129 */
3130static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3131 /*
3132 * preset connection lists of input pins
3133 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3134 */
3135 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3136 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3137 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3138
3139 /*
3140 * Set pin mode and muting
3141 */
3142 /* set front pin widgets 0x14 for output */
05acb863 3143 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3144 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3145 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3146 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3147 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3148 /* Mic2 (as headphone out) for HP output */
3149 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3150 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3151 /* Line In pin widget for input */
05acb863 3152 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3153 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3154 /* Line2 (as front mic) pin widget for input and vref at 80% */
3155 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3156 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3157 /* CD pin widget for input */
05acb863 3158 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3159
e9edcee0
TI
3160 { }
3161};
1da177e4 3162
e9edcee0
TI
3163/*
3164 * 5-stack pin configuration:
3165 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3166 * line-in/side = 0x1a, f-mic = 0x1b
3167 */
3168static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3169 /*
3170 * preset connection lists of input pins
3171 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3172 */
e9edcee0
TI
3173 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3174 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3175
e9edcee0
TI
3176 /*
3177 * Set pin mode and muting
1da177e4 3178 */
e9edcee0
TI
3179 /* set pin widgets 0x14-0x17 for output */
3180 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3181 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3182 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3183 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3184 /* unmute pins for output (no gain on this amp) */
3185 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3187 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3188 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3189
3190 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3191 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3192 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3193 /* Mic2 (as headphone out) for HP output */
3194 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3195 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3196 /* Line In pin widget for input */
3197 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3198 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3199 /* Line2 (as front mic) pin widget for input and vref at 80% */
3200 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3201 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3202 /* CD pin widget for input */
3203 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3204
3205 { }
3206};
3207
e9edcee0
TI
3208/*
3209 * W810 pin configuration:
3210 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3211 */
3212static struct hda_verb alc880_pin_w810_init_verbs[] = {
3213 /* hphone/speaker input selector: front DAC */
3214 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3215
05acb863 3216 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3217 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3218 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3219 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3220 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3221 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3222
e9edcee0 3223 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3224 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3225
1da177e4
LT
3226 { }
3227};
3228
e9edcee0
TI
3229/*
3230 * Z71V pin configuration:
3231 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3232 */
3233static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3237 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3238
16ded525 3239 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3240 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3241 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3242 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3243
3244 { }
3245};
3246
e9edcee0
TI
3247/*
3248 * 6-stack pin configuration:
9c7f852e
TI
3249 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3250 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3251 */
3252static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3253 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3254
16ded525 3255 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3256 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3259 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3260 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3261 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3262 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3263
16ded525 3264 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3265 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3266 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3267 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3268 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3269 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3270 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3271 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3273
e9edcee0
TI
3274 { }
3275};
3276
ccc656ce
KY
3277/*
3278 * Uniwill pin configuration:
3279 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3280 * line = 0x1a
3281 */
3282static struct hda_verb alc880_uniwill_init_verbs[] = {
3283 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3284
3285 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3286 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3287 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3288 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3289 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3290 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3291 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3292 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3293 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3295 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3296 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3297 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3298 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3299
3300 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3301 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3302 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3303 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3305 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3306 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3307 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3308 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3309
3310 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3311 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3312
3313 { }
3314};
3315
3316/*
3317* Uniwill P53
ea1fb29a 3318* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3319 */
3320static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3321 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3322
3323 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3324 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3327 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3328 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3329 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3331 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3332 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3335
3336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3338 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3339 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3340 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3341 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3342
3343 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3344 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3345
3346 { }
3347};
3348
2cf9f0fc
TD
3349static struct hda_verb alc880_beep_init_verbs[] = {
3350 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3351 { }
3352};
3353
458a4fab 3354/* auto-toggle front mic */
eeb43387 3355static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3356{
3357 unsigned int present;
3358 unsigned char bits;
ccc656ce 3359
864f92be 3360 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3361 bits = present ? HDA_AMP_MUTE : 0;
3362 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3363}
3364
4f5d1706 3365static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3366{
a9fd4f3f
TI
3367 struct alc_spec *spec = codec->spec;
3368
3369 spec->autocfg.hp_pins[0] = 0x14;
3370 spec->autocfg.speaker_pins[0] = 0x15;
3371 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3372}
3373
3374static void alc880_uniwill_init_hook(struct hda_codec *codec)
3375{
a9fd4f3f 3376 alc_automute_amp(codec);
eeb43387 3377 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3378}
3379
3380static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3381 unsigned int res)
3382{
3383 /* Looks like the unsol event is incompatible with the standard
3384 * definition. 4bit tag is placed at 28 bit!
3385 */
458a4fab 3386 switch (res >> 28) {
458a4fab 3387 case ALC880_MIC_EVENT:
eeb43387 3388 alc88x_simple_mic_automute(codec);
458a4fab 3389 break;
a9fd4f3f
TI
3390 default:
3391 alc_automute_amp_unsol_event(codec, res);
3392 break;
458a4fab 3393 }
ccc656ce
KY
3394}
3395
4f5d1706 3396static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3397{
a9fd4f3f 3398 struct alc_spec *spec = codec->spec;
ccc656ce 3399
a9fd4f3f
TI
3400 spec->autocfg.hp_pins[0] = 0x14;
3401 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3402}
3403
3404static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3405{
3406 unsigned int present;
ea1fb29a 3407
ccc656ce 3408 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3409 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3410 present &= HDA_AMP_VOLMASK;
3411 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3412 HDA_AMP_VOLMASK, present);
3413 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3414 HDA_AMP_VOLMASK, present);
ccc656ce 3415}
47fd830a 3416
ccc656ce
KY
3417static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3418 unsigned int res)
3419{
3420 /* Looks like the unsol event is incompatible with the standard
3421 * definition. 4bit tag is placed at 28 bit!
3422 */
f12ab1e0 3423 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3424 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3425 else
3426 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3427}
3428
e9edcee0
TI
3429/*
3430 * F1734 pin configuration:
3431 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3432 */
3433static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3434 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3435 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3436 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3437 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3438 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3439
e9edcee0 3440 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3441 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3443 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3444
e9edcee0
TI
3445 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3446 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3447 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3448 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3449 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3450 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3451 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3452 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3453 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3454
937b4160
TI
3455 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3456 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3457
dfc0ff62
TI
3458 { }
3459};
3460
e9edcee0
TI
3461/*
3462 * ASUS pin configuration:
3463 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3464 */
3465static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3466 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3467 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3468 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3469 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3470
3471 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3472 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3473 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3474 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3475 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3476 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3477 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3478 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3479
3480 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3482 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3483 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3484 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3485 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3486 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3487 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3488 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3489
e9edcee0
TI
3490 { }
3491};
16ded525 3492
e9edcee0 3493/* Enable GPIO mask and set output */
bc9f98a9
KY
3494#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3495#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3496#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3497
3498/* Clevo m520g init */
3499static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3500 /* headphone output */
3501 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3502 /* line-out */
3503 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3504 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3505 /* Line-in */
3506 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3507 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3508 /* CD */
3509 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3510 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3511 /* Mic1 (rear panel) */
3512 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3514 /* Mic2 (front panel) */
3515 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3516 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3517 /* headphone */
3518 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3519 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3520 /* change to EAPD mode */
3521 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3522 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3523
3524 { }
16ded525
TI
3525};
3526
df694daa 3527static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3528 /* change to EAPD mode */
3529 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3530 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3531
df694daa
KY
3532 /* Headphone output */
3533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3534 /* Front output*/
3535 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3536 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3537
3538 /* Line In pin widget for input */
3539 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3540 /* CD pin widget for input */
3541 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3542 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3544
3545 /* change to EAPD mode */
3546 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3547 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3548
3549 { }
3550};
16ded525 3551
e9edcee0 3552/*
ae6b813a
TI
3553 * LG m1 express dual
3554 *
3555 * Pin assignment:
3556 * Rear Line-In/Out (blue): 0x14
3557 * Build-in Mic-In: 0x15
3558 * Speaker-out: 0x17
3559 * HP-Out (green): 0x1b
3560 * Mic-In/Out (red): 0x19
3561 * SPDIF-Out: 0x1e
3562 */
3563
3564/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3565static hda_nid_t alc880_lg_dac_nids[3] = {
3566 0x05, 0x02, 0x03
3567};
3568
3569/* seems analog CD is not working */
3570static struct hda_input_mux alc880_lg_capture_source = {
3571 .num_items = 3,
3572 .items = {
3573 { "Mic", 0x1 },
3574 { "Line", 0x5 },
3575 { "Internal Mic", 0x6 },
3576 },
3577};
3578
3579/* 2,4,6 channel modes */
3580static struct hda_verb alc880_lg_ch2_init[] = {
3581 /* set line-in and mic-in to input */
3582 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3583 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3584 { }
3585};
3586
3587static struct hda_verb alc880_lg_ch4_init[] = {
3588 /* set line-in to out and mic-in to input */
3589 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3590 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3591 { }
3592};
3593
3594static struct hda_verb alc880_lg_ch6_init[] = {
3595 /* set line-in and mic-in to output */
3596 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3597 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3598 { }
3599};
3600
3601static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3602 { 2, alc880_lg_ch2_init },
3603 { 4, alc880_lg_ch4_init },
3604 { 6, alc880_lg_ch6_init },
3605};
3606
3607static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3608 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3609 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3610 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3611 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3612 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3613 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3614 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3615 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3618 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3619 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3620 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3621 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3622 {
3623 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3624 .name = "Channel Mode",
3625 .info = alc_ch_mode_info,
3626 .get = alc_ch_mode_get,
3627 .put = alc_ch_mode_put,
3628 },
3629 { } /* end */
3630};
3631
3632static struct hda_verb alc880_lg_init_verbs[] = {
3633 /* set capture source to mic-in */
3634 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3635 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3636 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3637 /* mute all amp mixer inputs */
3638 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3639 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3640 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3641 /* line-in to input */
3642 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3643 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3644 /* built-in mic */
3645 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3646 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3647 /* speaker-out */
3648 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3649 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3650 /* mic-in to input */
3651 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3652 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3653 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3654 /* HP-out */
3655 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3656 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3657 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3658 /* jack sense */
a9fd4f3f 3659 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3660 { }
3661};
3662
3663/* toggle speaker-output according to the hp-jack state */
4f5d1706 3664static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3665{
a9fd4f3f 3666 struct alc_spec *spec = codec->spec;
ae6b813a 3667
a9fd4f3f
TI
3668 spec->autocfg.hp_pins[0] = 0x1b;
3669 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3670}
3671
d681518a
TI
3672/*
3673 * LG LW20
3674 *
3675 * Pin assignment:
3676 * Speaker-out: 0x14
3677 * Mic-In: 0x18
e4f41da9
CM
3678 * Built-in Mic-In: 0x19
3679 * Line-In: 0x1b
3680 * HP-Out: 0x1a
d681518a
TI
3681 * SPDIF-Out: 0x1e
3682 */
3683
d681518a 3684static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3685 .num_items = 3,
d681518a
TI
3686 .items = {
3687 { "Mic", 0x0 },
3688 { "Internal Mic", 0x1 },
e4f41da9 3689 { "Line In", 0x2 },
d681518a
TI
3690 },
3691};
3692
0a8c5da3
CM
3693#define alc880_lg_lw_modes alc880_threestack_modes
3694
d681518a 3695static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3696 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3697 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3698 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3699 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3700 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3701 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3702 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3703 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3705 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3708 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3709 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3710 {
3711 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3712 .name = "Channel Mode",
3713 .info = alc_ch_mode_info,
3714 .get = alc_ch_mode_get,
3715 .put = alc_ch_mode_put,
3716 },
d681518a
TI
3717 { } /* end */
3718};
3719
3720static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3721 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3722 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3723 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3724
d681518a
TI
3725 /* set capture source to mic-in */
3726 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3727 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3728 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3729 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3730 /* speaker-out */
3731 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3732 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3733 /* HP-out */
d681518a
TI
3734 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3735 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3736 /* mic-in to input */
3737 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3738 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3739 /* built-in mic */
3740 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3741 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3742 /* jack sense */
a9fd4f3f 3743 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3744 { }
3745};
3746
3747/* toggle speaker-output according to the hp-jack state */
4f5d1706 3748static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3749{
a9fd4f3f 3750 struct alc_spec *spec = codec->spec;
d681518a 3751
a9fd4f3f
TI
3752 spec->autocfg.hp_pins[0] = 0x1b;
3753 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3754}
3755
df99cd33
TI
3756static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3757 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3758 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3759 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3760 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3761 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3762 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3763 { } /* end */
3764};
3765
3766static struct hda_input_mux alc880_medion_rim_capture_source = {
3767 .num_items = 2,
3768 .items = {
3769 { "Mic", 0x0 },
3770 { "Internal Mic", 0x1 },
3771 },
3772};
3773
3774static struct hda_verb alc880_medion_rim_init_verbs[] = {
3775 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3776
3777 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3778 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3779
3780 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3781 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3782 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3783 /* Mic2 (as headphone out) for HP output */
3784 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3785 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3786 /* Internal Speaker */
3787 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3788 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3789
3790 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3791 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3792
3793 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3794 { }
3795};
3796
3797/* toggle speaker-output according to the hp-jack state */
3798static void alc880_medion_rim_automute(struct hda_codec *codec)
3799{
a9fd4f3f
TI
3800 struct alc_spec *spec = codec->spec;
3801 alc_automute_amp(codec);
3802 /* toggle EAPD */
3803 if (spec->jack_present)
df99cd33
TI
3804 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3805 else
3806 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3807}
3808
3809static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3810 unsigned int res)
3811{
3812 /* Looks like the unsol event is incompatible with the standard
3813 * definition. 4bit tag is placed at 28 bit!
3814 */
3815 if ((res >> 28) == ALC880_HP_EVENT)
3816 alc880_medion_rim_automute(codec);
3817}
3818
4f5d1706 3819static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3820{
3821 struct alc_spec *spec = codec->spec;
3822
3823 spec->autocfg.hp_pins[0] = 0x14;
3824 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3825}
3826
cb53c626
TI
3827#ifdef CONFIG_SND_HDA_POWER_SAVE
3828static struct hda_amp_list alc880_loopbacks[] = {
3829 { 0x0b, HDA_INPUT, 0 },
3830 { 0x0b, HDA_INPUT, 1 },
3831 { 0x0b, HDA_INPUT, 2 },
3832 { 0x0b, HDA_INPUT, 3 },
3833 { 0x0b, HDA_INPUT, 4 },
3834 { } /* end */
3835};
3836
3837static struct hda_amp_list alc880_lg_loopbacks[] = {
3838 { 0x0b, HDA_INPUT, 1 },
3839 { 0x0b, HDA_INPUT, 6 },
3840 { 0x0b, HDA_INPUT, 7 },
3841 { } /* end */
3842};
3843#endif
3844
ae6b813a
TI
3845/*
3846 * Common callbacks
e9edcee0
TI
3847 */
3848
1da177e4
LT
3849static int alc_init(struct hda_codec *codec)
3850{
3851 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3852 unsigned int i;
3853
2c3bf9ab 3854 alc_fix_pll(codec);
4a79ba34 3855 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3856
e9edcee0
TI
3857 for (i = 0; i < spec->num_init_verbs; i++)
3858 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3859
3860 if (spec->init_hook)
3861 spec->init_hook(codec);
3862
9e5341b9 3863 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
3864 return 0;
3865}
3866
ae6b813a
TI
3867static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3868{
3869 struct alc_spec *spec = codec->spec;
3870
3871 if (spec->unsol_event)
3872 spec->unsol_event(codec, res);
3873}
3874
cb53c626
TI
3875#ifdef CONFIG_SND_HDA_POWER_SAVE
3876static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3877{
3878 struct alc_spec *spec = codec->spec;
3879 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3880}
3881#endif
3882
1da177e4
LT
3883/*
3884 * Analog playback callbacks
3885 */
3886static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3887 struct hda_codec *codec,
c8b6bf9b 3888 struct snd_pcm_substream *substream)
1da177e4
LT
3889{
3890 struct alc_spec *spec = codec->spec;
9a08160b
TI
3891 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3892 hinfo);
1da177e4
LT
3893}
3894
3895static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3896 struct hda_codec *codec,
3897 unsigned int stream_tag,
3898 unsigned int format,
c8b6bf9b 3899 struct snd_pcm_substream *substream)
1da177e4
LT
3900{
3901 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3902 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3903 stream_tag, format, substream);
1da177e4
LT
3904}
3905
3906static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3907 struct hda_codec *codec,
c8b6bf9b 3908 struct snd_pcm_substream *substream)
1da177e4
LT
3909{
3910 struct alc_spec *spec = codec->spec;
3911 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3912}
3913
3914/*
3915 * Digital out
3916 */
3917static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3918 struct hda_codec *codec,
c8b6bf9b 3919 struct snd_pcm_substream *substream)
1da177e4
LT
3920{
3921 struct alc_spec *spec = codec->spec;
3922 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3923}
3924
6b97eb45
TI
3925static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3926 struct hda_codec *codec,
3927 unsigned int stream_tag,
3928 unsigned int format,
3929 struct snd_pcm_substream *substream)
3930{
3931 struct alc_spec *spec = codec->spec;
3932 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3933 stream_tag, format, substream);
3934}
3935
9b5f12e5
TI
3936static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3937 struct hda_codec *codec,
3938 struct snd_pcm_substream *substream)
3939{
3940 struct alc_spec *spec = codec->spec;
3941 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3942}
3943
1da177e4
LT
3944static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3945 struct hda_codec *codec,
c8b6bf9b 3946 struct snd_pcm_substream *substream)
1da177e4
LT
3947{
3948 struct alc_spec *spec = codec->spec;
3949 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3950}
3951
3952/*
3953 * Analog capture
3954 */
6330079f 3955static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3956 struct hda_codec *codec,
3957 unsigned int stream_tag,
3958 unsigned int format,
c8b6bf9b 3959 struct snd_pcm_substream *substream)
1da177e4
LT
3960{
3961 struct alc_spec *spec = codec->spec;
3962
6330079f 3963 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3964 stream_tag, 0, format);
3965 return 0;
3966}
3967
6330079f 3968static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3969 struct hda_codec *codec,
c8b6bf9b 3970 struct snd_pcm_substream *substream)
1da177e4
LT
3971{
3972 struct alc_spec *spec = codec->spec;
3973
888afa15
TI
3974 snd_hda_codec_cleanup_stream(codec,
3975 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3976 return 0;
3977}
3978
840b64c0
TI
3979/* analog capture with dynamic dual-adc changes */
3980static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3981 struct hda_codec *codec,
3982 unsigned int stream_tag,
3983 unsigned int format,
3984 struct snd_pcm_substream *substream)
3985{
3986 struct alc_spec *spec = codec->spec;
3987 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3988 spec->cur_adc_stream_tag = stream_tag;
3989 spec->cur_adc_format = format;
3990 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3991 return 0;
3992}
3993
3994static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3995 struct hda_codec *codec,
3996 struct snd_pcm_substream *substream)
3997{
3998 struct alc_spec *spec = codec->spec;
3999 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4000 spec->cur_adc = 0;
4001 return 0;
4002}
4003
4004static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4005 .substreams = 1,
4006 .channels_min = 2,
4007 .channels_max = 2,
4008 .nid = 0, /* fill later */
4009 .ops = {
4010 .prepare = dualmic_capture_pcm_prepare,
4011 .cleanup = dualmic_capture_pcm_cleanup
4012 },
4013};
1da177e4
LT
4014
4015/*
4016 */
4017static struct hda_pcm_stream alc880_pcm_analog_playback = {
4018 .substreams = 1,
4019 .channels_min = 2,
4020 .channels_max = 8,
e9edcee0 4021 /* NID is set in alc_build_pcms */
1da177e4
LT
4022 .ops = {
4023 .open = alc880_playback_pcm_open,
4024 .prepare = alc880_playback_pcm_prepare,
4025 .cleanup = alc880_playback_pcm_cleanup
4026 },
4027};
4028
4029static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4030 .substreams = 1,
4031 .channels_min = 2,
4032 .channels_max = 2,
4033 /* NID is set in alc_build_pcms */
4034};
4035
4036static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4037 .substreams = 1,
4038 .channels_min = 2,
4039 .channels_max = 2,
4040 /* NID is set in alc_build_pcms */
4041};
4042
4043static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4044 .substreams = 2, /* can be overridden */
1da177e4
LT
4045 .channels_min = 2,
4046 .channels_max = 2,
e9edcee0 4047 /* NID is set in alc_build_pcms */
1da177e4 4048 .ops = {
6330079f
TI
4049 .prepare = alc880_alt_capture_pcm_prepare,
4050 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4051 },
4052};
4053
4054static struct hda_pcm_stream alc880_pcm_digital_playback = {
4055 .substreams = 1,
4056 .channels_min = 2,
4057 .channels_max = 2,
4058 /* NID is set in alc_build_pcms */
4059 .ops = {
4060 .open = alc880_dig_playback_pcm_open,
6b97eb45 4061 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4062 .prepare = alc880_dig_playback_pcm_prepare,
4063 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4064 },
4065};
4066
4067static struct hda_pcm_stream alc880_pcm_digital_capture = {
4068 .substreams = 1,
4069 .channels_min = 2,
4070 .channels_max = 2,
4071 /* NID is set in alc_build_pcms */
4072};
4073
4c5186ed 4074/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 4075static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4076 .substreams = 0,
4077 .channels_min = 0,
4078 .channels_max = 0,
4079};
4080
1da177e4
LT
4081static int alc_build_pcms(struct hda_codec *codec)
4082{
4083 struct alc_spec *spec = codec->spec;
4084 struct hda_pcm *info = spec->pcm_rec;
4085 int i;
4086
4087 codec->num_pcms = 1;
4088 codec->pcm_info = info;
4089
e64f14f4
TI
4090 if (spec->no_analog)
4091 goto skip_analog;
4092
812a2cca
TI
4093 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4094 "%s Analog", codec->chip_name);
1da177e4 4095 info->name = spec->stream_name_analog;
274693f3 4096
4a471b7d 4097 if (spec->stream_analog_playback) {
da3cec35
TI
4098 if (snd_BUG_ON(!spec->multiout.dac_nids))
4099 return -EINVAL;
4a471b7d
TI
4100 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4101 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4102 }
4103 if (spec->stream_analog_capture) {
da3cec35
TI
4104 if (snd_BUG_ON(!spec->adc_nids))
4105 return -EINVAL;
4a471b7d
TI
4106 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4107 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4108 }
4109
4110 if (spec->channel_mode) {
4111 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4112 for (i = 0; i < spec->num_channel_mode; i++) {
4113 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4114 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4115 }
1da177e4
LT
4116 }
4117 }
4118
e64f14f4 4119 skip_analog:
e08a007d 4120 /* SPDIF for stream index #1 */
1da177e4 4121 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4122 snprintf(spec->stream_name_digital,
4123 sizeof(spec->stream_name_digital),
4124 "%s Digital", codec->chip_name);
e08a007d 4125 codec->num_pcms = 2;
b25c9da1 4126 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4127 info = spec->pcm_rec + 1;
1da177e4 4128 info->name = spec->stream_name_digital;
8c441982
TI
4129 if (spec->dig_out_type)
4130 info->pcm_type = spec->dig_out_type;
4131 else
4132 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4133 if (spec->multiout.dig_out_nid &&
4134 spec->stream_digital_playback) {
1da177e4
LT
4135 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4136 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4137 }
4a471b7d
TI
4138 if (spec->dig_in_nid &&
4139 spec->stream_digital_capture) {
1da177e4
LT
4140 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4141 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4142 }
963f803f
TI
4143 /* FIXME: do we need this for all Realtek codec models? */
4144 codec->spdif_status_reset = 1;
1da177e4
LT
4145 }
4146
e64f14f4
TI
4147 if (spec->no_analog)
4148 return 0;
4149
e08a007d
TI
4150 /* If the use of more than one ADC is requested for the current
4151 * model, configure a second analog capture-only PCM.
4152 */
4153 /* Additional Analaog capture for index #2 */
6330079f
TI
4154 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4155 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4156 codec->num_pcms = 3;
c06134d7 4157 info = spec->pcm_rec + 2;
e08a007d 4158 info->name = spec->stream_name_analog;
6330079f
TI
4159 if (spec->alt_dac_nid) {
4160 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4161 *spec->stream_analog_alt_playback;
4162 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4163 spec->alt_dac_nid;
4164 } else {
4165 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4166 alc_pcm_null_stream;
4167 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4168 }
4169 if (spec->num_adc_nids > 1) {
4170 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4171 *spec->stream_analog_alt_capture;
4172 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4173 spec->adc_nids[1];
4174 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4175 spec->num_adc_nids - 1;
4176 } else {
4177 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4178 alc_pcm_null_stream;
4179 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4180 }
4181 }
4182
1da177e4
LT
4183 return 0;
4184}
4185
a4e09aa3
TI
4186static inline void alc_shutup(struct hda_codec *codec)
4187{
4188 snd_hda_shutup_pins(codec);
4189}
4190
603c4019
TI
4191static void alc_free_kctls(struct hda_codec *codec)
4192{
4193 struct alc_spec *spec = codec->spec;
4194
4195 if (spec->kctls.list) {
4196 struct snd_kcontrol_new *kctl = spec->kctls.list;
4197 int i;
4198 for (i = 0; i < spec->kctls.used; i++)
4199 kfree(kctl[i].name);
4200 }
4201 snd_array_free(&spec->kctls);
4202}
4203
1da177e4
LT
4204static void alc_free(struct hda_codec *codec)
4205{
e9edcee0 4206 struct alc_spec *spec = codec->spec;
e9edcee0 4207
f12ab1e0 4208 if (!spec)
e9edcee0
TI
4209 return;
4210
a4e09aa3 4211 alc_shutup(codec);
603c4019 4212 alc_free_kctls(codec);
e9edcee0 4213 kfree(spec);
680cd536 4214 snd_hda_detach_beep_device(codec);
1da177e4
LT
4215}
4216
f5de24b0 4217#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4218static void alc_power_eapd(struct hda_codec *codec)
4219{
4220 /* We currently only handle front, HP */
4221 switch (codec->vendor_id) {
4222 case 0x10ec0260:
9e4c8496
TI
4223 set_eapd(codec, 0x0f, 0);
4224 set_eapd(codec, 0x10, 0);
c97259df
DC
4225 break;
4226 case 0x10ec0262:
4227 case 0x10ec0267:
4228 case 0x10ec0268:
4229 case 0x10ec0269:
9e4c8496 4230 case 0x10ec0270:
c97259df
DC
4231 case 0x10ec0272:
4232 case 0x10ec0660:
4233 case 0x10ec0662:
4234 case 0x10ec0663:
4235 case 0x10ec0862:
4236 case 0x10ec0889:
9e4c8496
TI
4237 set_eapd(codec, 0x14, 0);
4238 set_eapd(codec, 0x15, 0);
c97259df
DC
4239 break;
4240 }
4241}
4242
f5de24b0
HM
4243static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4244{
4245 struct alc_spec *spec = codec->spec;
a4e09aa3 4246 alc_shutup(codec);
f5de24b0 4247 if (spec && spec->power_hook)
c97259df 4248 spec->power_hook(codec);
f5de24b0
HM
4249 return 0;
4250}
4251#endif
4252
e044c39a 4253#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4254static int alc_resume(struct hda_codec *codec)
4255{
e044c39a
TI
4256 codec->patch_ops.init(codec);
4257 snd_hda_codec_resume_amp(codec);
4258 snd_hda_codec_resume_cache(codec);
9e5341b9 4259 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4260 return 0;
4261}
e044c39a
TI
4262#endif
4263
1da177e4
LT
4264/*
4265 */
4266static struct hda_codec_ops alc_patch_ops = {
4267 .build_controls = alc_build_controls,
4268 .build_pcms = alc_build_pcms,
4269 .init = alc_init,
4270 .free = alc_free,
ae6b813a 4271 .unsol_event = alc_unsol_event,
e044c39a
TI
4272#ifdef SND_HDA_NEEDS_RESUME
4273 .resume = alc_resume,
4274#endif
cb53c626 4275#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4276 .suspend = alc_suspend,
cb53c626
TI
4277 .check_power_status = alc_check_power_status,
4278#endif
c97259df 4279 .reboot_notify = alc_shutup,
1da177e4
LT
4280};
4281
c027ddcd
KY
4282/* replace the codec chip_name with the given string */
4283static int alc_codec_rename(struct hda_codec *codec, const char *name)
4284{
4285 kfree(codec->chip_name);
4286 codec->chip_name = kstrdup(name, GFP_KERNEL);
4287 if (!codec->chip_name) {
4288 alc_free(codec);
4289 return -ENOMEM;
4290 }
4291 return 0;
4292}
4293
2fa522be
TI
4294/*
4295 * Test configuration for debugging
4296 *
4297 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4298 * enum controls.
4299 */
4300#ifdef CONFIG_SND_DEBUG
4301static hda_nid_t alc880_test_dac_nids[4] = {
4302 0x02, 0x03, 0x04, 0x05
4303};
4304
4305static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4306 .num_items = 7,
2fa522be
TI
4307 .items = {
4308 { "In-1", 0x0 },
4309 { "In-2", 0x1 },
4310 { "In-3", 0x2 },
4311 { "In-4", 0x3 },
4312 { "CD", 0x4 },
ae6b813a
TI
4313 { "Front", 0x5 },
4314 { "Surround", 0x6 },
2fa522be
TI
4315 },
4316};
4317
d2a6d7dc 4318static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4319 { 2, NULL },
fd2c326d 4320 { 4, NULL },
2fa522be 4321 { 6, NULL },
fd2c326d 4322 { 8, NULL },
2fa522be
TI
4323};
4324
9c7f852e
TI
4325static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4326 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4327{
4328 static char *texts[] = {
4329 "N/A", "Line Out", "HP Out",
4330 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4331 };
4332 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4333 uinfo->count = 1;
4334 uinfo->value.enumerated.items = 8;
4335 if (uinfo->value.enumerated.item >= 8)
4336 uinfo->value.enumerated.item = 7;
4337 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4338 return 0;
4339}
4340
9c7f852e
TI
4341static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4342 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4343{
4344 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4345 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4346 unsigned int pin_ctl, item = 0;
4347
4348 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4349 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4350 if (pin_ctl & AC_PINCTL_OUT_EN) {
4351 if (pin_ctl & AC_PINCTL_HP_EN)
4352 item = 2;
4353 else
4354 item = 1;
4355 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4356 switch (pin_ctl & AC_PINCTL_VREFEN) {
4357 case AC_PINCTL_VREF_HIZ: item = 3; break;
4358 case AC_PINCTL_VREF_50: item = 4; break;
4359 case AC_PINCTL_VREF_GRD: item = 5; break;
4360 case AC_PINCTL_VREF_80: item = 6; break;
4361 case AC_PINCTL_VREF_100: item = 7; break;
4362 }
4363 }
4364 ucontrol->value.enumerated.item[0] = item;
4365 return 0;
4366}
4367
9c7f852e
TI
4368static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4369 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4370{
4371 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4372 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4373 static unsigned int ctls[] = {
4374 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4375 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4376 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4377 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4378 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4379 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4380 };
4381 unsigned int old_ctl, new_ctl;
4382
4383 old_ctl = snd_hda_codec_read(codec, nid, 0,
4384 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4385 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4386 if (old_ctl != new_ctl) {
82beb8fd
TI
4387 int val;
4388 snd_hda_codec_write_cache(codec, nid, 0,
4389 AC_VERB_SET_PIN_WIDGET_CONTROL,
4390 new_ctl);
47fd830a
TI
4391 val = ucontrol->value.enumerated.item[0] >= 3 ?
4392 HDA_AMP_MUTE : 0;
4393 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4394 HDA_AMP_MUTE, val);
2fa522be
TI
4395 return 1;
4396 }
4397 return 0;
4398}
4399
9c7f852e
TI
4400static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4401 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4402{
4403 static char *texts[] = {
4404 "Front", "Surround", "CLFE", "Side"
4405 };
4406 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4407 uinfo->count = 1;
4408 uinfo->value.enumerated.items = 4;
4409 if (uinfo->value.enumerated.item >= 4)
4410 uinfo->value.enumerated.item = 3;
4411 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4412 return 0;
4413}
4414
9c7f852e
TI
4415static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4416 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4417{
4418 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4419 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4420 unsigned int sel;
4421
4422 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4423 ucontrol->value.enumerated.item[0] = sel & 3;
4424 return 0;
4425}
4426
9c7f852e
TI
4427static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4428 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4429{
4430 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4431 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4432 unsigned int sel;
4433
4434 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4435 if (ucontrol->value.enumerated.item[0] != sel) {
4436 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4437 snd_hda_codec_write_cache(codec, nid, 0,
4438 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4439 return 1;
4440 }
4441 return 0;
4442}
4443
4444#define PIN_CTL_TEST(xname,nid) { \
4445 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4446 .name = xname, \
5b0cb1d8 4447 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4448 .info = alc_test_pin_ctl_info, \
4449 .get = alc_test_pin_ctl_get, \
4450 .put = alc_test_pin_ctl_put, \
4451 .private_value = nid \
4452 }
4453
4454#define PIN_SRC_TEST(xname,nid) { \
4455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4456 .name = xname, \
5b0cb1d8 4457 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4458 .info = alc_test_pin_src_info, \
4459 .get = alc_test_pin_src_get, \
4460 .put = alc_test_pin_src_put, \
4461 .private_value = nid \
4462 }
4463
c8b6bf9b 4464static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4465 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4466 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4467 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4468 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4469 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4470 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4471 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4472 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4473 PIN_CTL_TEST("Front Pin Mode", 0x14),
4474 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4475 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4476 PIN_CTL_TEST("Side Pin Mode", 0x17),
4477 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4478 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4479 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4480 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4481 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4482 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4483 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4484 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4485 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4486 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4487 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4488 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4489 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4490 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4491 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4492 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4493 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4494 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4495 {
4496 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4497 .name = "Channel Mode",
df694daa
KY
4498 .info = alc_ch_mode_info,
4499 .get = alc_ch_mode_get,
4500 .put = alc_ch_mode_put,
2fa522be
TI
4501 },
4502 { } /* end */
4503};
4504
4505static struct hda_verb alc880_test_init_verbs[] = {
4506 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4507 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4509 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4510 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4511 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4512 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4513 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4515 /* Vol output for 0x0c-0x0f */
05acb863
TI
4516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4518 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4519 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4520 /* Set output pins 0x14-0x17 */
05acb863
TI
4521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4522 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4523 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4524 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4525 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4528 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4529 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4530 /* Set input pins 0x18-0x1c */
16ded525
TI
4531 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4532 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4533 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4534 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4535 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4536 /* Mute input pins 0x18-0x1b */
05acb863
TI
4537 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4538 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4539 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4540 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4541 /* ADC set up */
05acb863 4542 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4543 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4544 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4545 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4546 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4547 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4548 /* Analog input/passthru */
4549 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4550 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4551 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4552 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4553 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4554 { }
4555};
4556#endif
4557
1da177e4
LT
4558/*
4559 */
4560
f5fcc13c
TI
4561static const char *alc880_models[ALC880_MODEL_LAST] = {
4562 [ALC880_3ST] = "3stack",
4563 [ALC880_TCL_S700] = "tcl",
4564 [ALC880_3ST_DIG] = "3stack-digout",
4565 [ALC880_CLEVO] = "clevo",
4566 [ALC880_5ST] = "5stack",
4567 [ALC880_5ST_DIG] = "5stack-digout",
4568 [ALC880_W810] = "w810",
4569 [ALC880_Z71V] = "z71v",
4570 [ALC880_6ST] = "6stack",
4571 [ALC880_6ST_DIG] = "6stack-digout",
4572 [ALC880_ASUS] = "asus",
4573 [ALC880_ASUS_W1V] = "asus-w1v",
4574 [ALC880_ASUS_DIG] = "asus-dig",
4575 [ALC880_ASUS_DIG2] = "asus-dig2",
4576 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4577 [ALC880_UNIWILL_P53] = "uniwill-p53",
4578 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4579 [ALC880_F1734] = "F1734",
4580 [ALC880_LG] = "lg",
4581 [ALC880_LG_LW] = "lg-lw",
df99cd33 4582 [ALC880_MEDION_RIM] = "medion",
2fa522be 4583#ifdef CONFIG_SND_DEBUG
f5fcc13c 4584 [ALC880_TEST] = "test",
2fa522be 4585#endif
f5fcc13c
TI
4586 [ALC880_AUTO] = "auto",
4587};
4588
4589static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4590 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4591 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4592 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4593 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4594 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4595 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4596 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4597 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4598 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4599 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4600 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4601 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4602 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4603 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4604 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4605 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4606 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4607 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4608 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4609 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4610 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4611 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4612 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4613 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4614 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4615 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4616 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4617 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4618 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4619 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4620 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4621 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4622 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4623 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4624 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4625 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4626 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4627 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4628 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4629 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4630 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4631 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4632 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4633 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4634 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4635 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4636 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4637 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4638 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4639 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4640 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4641 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4642 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4643 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4644 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4645 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4646 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4647 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4648 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4649 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4650 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4651 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4652 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4653 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4654 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4655 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4656 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4657 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4658 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4659 /* default Intel */
4660 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4661 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4662 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4663 {}
4664};
4665
16ded525 4666/*
df694daa 4667 * ALC880 codec presets
16ded525 4668 */
16ded525
TI
4669static struct alc_config_preset alc880_presets[] = {
4670 [ALC880_3ST] = {
e9edcee0 4671 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4672 .init_verbs = { alc880_volume_init_verbs,
4673 alc880_pin_3stack_init_verbs },
16ded525 4674 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4675 .dac_nids = alc880_dac_nids,
16ded525
TI
4676 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4677 .channel_mode = alc880_threestack_modes,
4e195a7b 4678 .need_dac_fix = 1,
16ded525
TI
4679 .input_mux = &alc880_capture_source,
4680 },
4681 [ALC880_3ST_DIG] = {
e9edcee0 4682 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4683 .init_verbs = { alc880_volume_init_verbs,
4684 alc880_pin_3stack_init_verbs },
16ded525 4685 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4686 .dac_nids = alc880_dac_nids,
4687 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4688 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4689 .channel_mode = alc880_threestack_modes,
4e195a7b 4690 .need_dac_fix = 1,
16ded525
TI
4691 .input_mux = &alc880_capture_source,
4692 },
df694daa
KY
4693 [ALC880_TCL_S700] = {
4694 .mixers = { alc880_tcl_s700_mixer },
4695 .init_verbs = { alc880_volume_init_verbs,
4696 alc880_pin_tcl_S700_init_verbs,
4697 alc880_gpio2_init_verbs },
4698 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4699 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4700 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4701 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4702 .hp_nid = 0x03,
4703 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4704 .channel_mode = alc880_2_jack_modes,
4705 .input_mux = &alc880_capture_source,
4706 },
16ded525 4707 [ALC880_5ST] = {
f12ab1e0
TI
4708 .mixers = { alc880_three_stack_mixer,
4709 alc880_five_stack_mixer},
4710 .init_verbs = { alc880_volume_init_verbs,
4711 alc880_pin_5stack_init_verbs },
16ded525
TI
4712 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4713 .dac_nids = alc880_dac_nids,
16ded525
TI
4714 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4715 .channel_mode = alc880_fivestack_modes,
4716 .input_mux = &alc880_capture_source,
4717 },
4718 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4719 .mixers = { alc880_three_stack_mixer,
4720 alc880_five_stack_mixer },
4721 .init_verbs = { alc880_volume_init_verbs,
4722 alc880_pin_5stack_init_verbs },
16ded525
TI
4723 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4724 .dac_nids = alc880_dac_nids,
4725 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4726 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4727 .channel_mode = alc880_fivestack_modes,
4728 .input_mux = &alc880_capture_source,
4729 },
b6482d48
TI
4730 [ALC880_6ST] = {
4731 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4732 .init_verbs = { alc880_volume_init_verbs,
4733 alc880_pin_6stack_init_verbs },
b6482d48
TI
4734 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4735 .dac_nids = alc880_6st_dac_nids,
4736 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4737 .channel_mode = alc880_sixstack_modes,
4738 .input_mux = &alc880_6stack_capture_source,
4739 },
16ded525 4740 [ALC880_6ST_DIG] = {
e9edcee0 4741 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4742 .init_verbs = { alc880_volume_init_verbs,
4743 alc880_pin_6stack_init_verbs },
16ded525
TI
4744 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4745 .dac_nids = alc880_6st_dac_nids,
4746 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4747 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4748 .channel_mode = alc880_sixstack_modes,
4749 .input_mux = &alc880_6stack_capture_source,
4750 },
4751 [ALC880_W810] = {
e9edcee0 4752 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4753 .init_verbs = { alc880_volume_init_verbs,
4754 alc880_pin_w810_init_verbs,
b0af0de5 4755 alc880_gpio2_init_verbs },
16ded525
TI
4756 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4757 .dac_nids = alc880_w810_dac_nids,
4758 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4759 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4760 .channel_mode = alc880_w810_modes,
4761 .input_mux = &alc880_capture_source,
4762 },
4763 [ALC880_Z71V] = {
e9edcee0 4764 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4765 .init_verbs = { alc880_volume_init_verbs,
4766 alc880_pin_z71v_init_verbs },
16ded525
TI
4767 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4768 .dac_nids = alc880_z71v_dac_nids,
4769 .dig_out_nid = ALC880_DIGOUT_NID,
4770 .hp_nid = 0x03,
e9edcee0
TI
4771 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4772 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4773 .input_mux = &alc880_capture_source,
4774 },
4775 [ALC880_F1734] = {
e9edcee0 4776 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4777 .init_verbs = { alc880_volume_init_verbs,
4778 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4779 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4780 .dac_nids = alc880_f1734_dac_nids,
4781 .hp_nid = 0x02,
4782 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4783 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4784 .input_mux = &alc880_f1734_capture_source,
4785 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4786 .setup = alc880_uniwill_p53_setup,
4787 .init_hook = alc_automute_amp,
16ded525
TI
4788 },
4789 [ALC880_ASUS] = {
e9edcee0 4790 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4791 .init_verbs = { alc880_volume_init_verbs,
4792 alc880_pin_asus_init_verbs,
e9edcee0
TI
4793 alc880_gpio1_init_verbs },
4794 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4795 .dac_nids = alc880_asus_dac_nids,
4796 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4797 .channel_mode = alc880_asus_modes,
4e195a7b 4798 .need_dac_fix = 1,
16ded525
TI
4799 .input_mux = &alc880_capture_source,
4800 },
4801 [ALC880_ASUS_DIG] = {
e9edcee0 4802 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4803 .init_verbs = { alc880_volume_init_verbs,
4804 alc880_pin_asus_init_verbs,
e9edcee0
TI
4805 alc880_gpio1_init_verbs },
4806 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4807 .dac_nids = alc880_asus_dac_nids,
16ded525 4808 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4809 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4810 .channel_mode = alc880_asus_modes,
4e195a7b 4811 .need_dac_fix = 1,
16ded525
TI
4812 .input_mux = &alc880_capture_source,
4813 },
df694daa
KY
4814 [ALC880_ASUS_DIG2] = {
4815 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4816 .init_verbs = { alc880_volume_init_verbs,
4817 alc880_pin_asus_init_verbs,
df694daa
KY
4818 alc880_gpio2_init_verbs }, /* use GPIO2 */
4819 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4820 .dac_nids = alc880_asus_dac_nids,
4821 .dig_out_nid = ALC880_DIGOUT_NID,
4822 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4823 .channel_mode = alc880_asus_modes,
4e195a7b 4824 .need_dac_fix = 1,
df694daa
KY
4825 .input_mux = &alc880_capture_source,
4826 },
16ded525 4827 [ALC880_ASUS_W1V] = {
e9edcee0 4828 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4829 .init_verbs = { alc880_volume_init_verbs,
4830 alc880_pin_asus_init_verbs,
e9edcee0
TI
4831 alc880_gpio1_init_verbs },
4832 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4833 .dac_nids = alc880_asus_dac_nids,
16ded525 4834 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4835 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4836 .channel_mode = alc880_asus_modes,
4e195a7b 4837 .need_dac_fix = 1,
16ded525
TI
4838 .input_mux = &alc880_capture_source,
4839 },
4840 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4841 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4842 .init_verbs = { alc880_volume_init_verbs,
4843 alc880_pin_asus_init_verbs },
e9edcee0
TI
4844 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4845 .dac_nids = alc880_asus_dac_nids,
16ded525 4846 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4847 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4848 .channel_mode = alc880_asus_modes,
4e195a7b 4849 .need_dac_fix = 1,
16ded525
TI
4850 .input_mux = &alc880_capture_source,
4851 },
ccc656ce
KY
4852 [ALC880_UNIWILL] = {
4853 .mixers = { alc880_uniwill_mixer },
4854 .init_verbs = { alc880_volume_init_verbs,
4855 alc880_uniwill_init_verbs },
4856 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4857 .dac_nids = alc880_asus_dac_nids,
4858 .dig_out_nid = ALC880_DIGOUT_NID,
4859 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4860 .channel_mode = alc880_threestack_modes,
4861 .need_dac_fix = 1,
4862 .input_mux = &alc880_capture_source,
4863 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4864 .setup = alc880_uniwill_setup,
a9fd4f3f 4865 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4866 },
4867 [ALC880_UNIWILL_P53] = {
4868 .mixers = { alc880_uniwill_p53_mixer },
4869 .init_verbs = { alc880_volume_init_verbs,
4870 alc880_uniwill_p53_init_verbs },
4871 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4872 .dac_nids = alc880_asus_dac_nids,
4873 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4874 .channel_mode = alc880_threestack_modes,
4875 .input_mux = &alc880_capture_source,
4876 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4877 .setup = alc880_uniwill_p53_setup,
4878 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4879 },
4880 [ALC880_FUJITSU] = {
45bdd1c1 4881 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4882 .init_verbs = { alc880_volume_init_verbs,
4883 alc880_uniwill_p53_init_verbs,
4884 alc880_beep_init_verbs },
4885 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4886 .dac_nids = alc880_dac_nids,
d53d7d9e 4887 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4888 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4889 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4890 .input_mux = &alc880_capture_source,
4891 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4892 .setup = alc880_uniwill_p53_setup,
4893 .init_hook = alc_automute_amp,
ccc656ce 4894 },
df694daa
KY
4895 [ALC880_CLEVO] = {
4896 .mixers = { alc880_three_stack_mixer },
4897 .init_verbs = { alc880_volume_init_verbs,
4898 alc880_pin_clevo_init_verbs },
4899 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4900 .dac_nids = alc880_dac_nids,
4901 .hp_nid = 0x03,
4902 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4903 .channel_mode = alc880_threestack_modes,
4e195a7b 4904 .need_dac_fix = 1,
df694daa
KY
4905 .input_mux = &alc880_capture_source,
4906 },
ae6b813a
TI
4907 [ALC880_LG] = {
4908 .mixers = { alc880_lg_mixer },
4909 .init_verbs = { alc880_volume_init_verbs,
4910 alc880_lg_init_verbs },
4911 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4912 .dac_nids = alc880_lg_dac_nids,
4913 .dig_out_nid = ALC880_DIGOUT_NID,
4914 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4915 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4916 .need_dac_fix = 1,
ae6b813a 4917 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4918 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4919 .setup = alc880_lg_setup,
4920 .init_hook = alc_automute_amp,
cb53c626
TI
4921#ifdef CONFIG_SND_HDA_POWER_SAVE
4922 .loopbacks = alc880_lg_loopbacks,
4923#endif
ae6b813a 4924 },
d681518a
TI
4925 [ALC880_LG_LW] = {
4926 .mixers = { alc880_lg_lw_mixer },
4927 .init_verbs = { alc880_volume_init_verbs,
4928 alc880_lg_lw_init_verbs },
0a8c5da3 4929 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4930 .dac_nids = alc880_dac_nids,
4931 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4932 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4933 .channel_mode = alc880_lg_lw_modes,
d681518a 4934 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4935 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4936 .setup = alc880_lg_lw_setup,
4937 .init_hook = alc_automute_amp,
d681518a 4938 },
df99cd33
TI
4939 [ALC880_MEDION_RIM] = {
4940 .mixers = { alc880_medion_rim_mixer },
4941 .init_verbs = { alc880_volume_init_verbs,
4942 alc880_medion_rim_init_verbs,
4943 alc_gpio2_init_verbs },
4944 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4945 .dac_nids = alc880_dac_nids,
4946 .dig_out_nid = ALC880_DIGOUT_NID,
4947 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4948 .channel_mode = alc880_2_jack_modes,
4949 .input_mux = &alc880_medion_rim_capture_source,
4950 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4951 .setup = alc880_medion_rim_setup,
4952 .init_hook = alc880_medion_rim_automute,
df99cd33 4953 },
16ded525
TI
4954#ifdef CONFIG_SND_DEBUG
4955 [ALC880_TEST] = {
e9edcee0
TI
4956 .mixers = { alc880_test_mixer },
4957 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4958 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4959 .dac_nids = alc880_test_dac_nids,
4960 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4961 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4962 .channel_mode = alc880_test_modes,
4963 .input_mux = &alc880_test_capture_source,
4964 },
4965#endif
4966};
4967
e9edcee0
TI
4968/*
4969 * Automatic parse of I/O pins from the BIOS configuration
4970 */
4971
e9edcee0
TI
4972enum {
4973 ALC_CTL_WIDGET_VOL,
4974 ALC_CTL_WIDGET_MUTE,
4975 ALC_CTL_BIND_MUTE,
4976};
c8b6bf9b 4977static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4978 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4979 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4980 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4981};
4982
4983/* add dynamic controls */
f12ab1e0 4984static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 4985 int cidx, unsigned long val)
e9edcee0 4986{
c8b6bf9b 4987 struct snd_kcontrol_new *knew;
e9edcee0 4988
603c4019
TI
4989 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4990 knew = snd_array_new(&spec->kctls);
4991 if (!knew)
4992 return -ENOMEM;
e9edcee0 4993 *knew = alc880_control_templates[type];
543537bd 4994 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4995 if (!knew->name)
e9edcee0 4996 return -ENOMEM;
66ceeb6b 4997 knew->index = cidx;
4d02d1b6 4998 if (get_amp_nid_(val))
5e26dfd0 4999 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5000 knew->private_value = val;
e9edcee0
TI
5001 return 0;
5002}
5003
0afe5f89
TI
5004static int add_control_with_pfx(struct alc_spec *spec, int type,
5005 const char *pfx, const char *dir,
66ceeb6b 5006 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5007{
5008 char name[32];
5009 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5010 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5011}
5012
66ceeb6b
TI
5013#define add_pb_vol_ctrl(spec, type, pfx, val) \
5014 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5015#define add_pb_sw_ctrl(spec, type, pfx, val) \
5016 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5017#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5018 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5019#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5020 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5021
e9edcee0
TI
5022#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5023#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5024#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5025#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5026#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5027#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5028#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5029#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5030#define ALC880_PIN_CD_NID 0x1c
5031
5032/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5033static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5034 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5035{
5036 hda_nid_t nid;
5037 int assigned[4];
5038 int i, j;
5039
5040 memset(assigned, 0, sizeof(assigned));
b0af0de5 5041 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5042
5043 /* check the pins hardwired to audio widget */
5044 for (i = 0; i < cfg->line_outs; i++) {
5045 nid = cfg->line_out_pins[i];
5046 if (alc880_is_fixed_pin(nid)) {
5047 int idx = alc880_fixed_pin_idx(nid);
5014f193 5048 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5049 assigned[idx] = 1;
5050 }
5051 }
5052 /* left pins can be connect to any audio widget */
5053 for (i = 0; i < cfg->line_outs; i++) {
5054 nid = cfg->line_out_pins[i];
5055 if (alc880_is_fixed_pin(nid))
5056 continue;
5057 /* search for an empty channel */
5058 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
5059 if (!assigned[j]) {
5060 spec->multiout.dac_nids[i] =
5061 alc880_idx_to_dac(j);
e9edcee0
TI
5062 assigned[j] = 1;
5063 break;
5064 }
5065 }
5066 }
5067 spec->multiout.num_dacs = cfg->line_outs;
5068 return 0;
5069}
5070
bcb2f0f5
TI
5071static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5072 bool can_be_master)
5073{
5074 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5075 return "Master";
5076
5077 switch (cfg->line_out_type) {
5078 case AUTO_PIN_SPEAKER_OUT:
5079 return "Speaker";
5080 case AUTO_PIN_HP_OUT:
5081 return "Headphone";
5082 default:
5083 if (cfg->line_outs == 1)
5084 return "PCM";
5085 break;
5086 }
5087 return NULL;
5088}
5089
e9edcee0 5090/* add playback controls from the parsed DAC table */
df694daa
KY
5091static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5092 const struct auto_pin_cfg *cfg)
e9edcee0 5093{
f12ab1e0
TI
5094 static const char *chname[4] = {
5095 "Front", "Surround", NULL /*CLFE*/, "Side"
5096 };
bcb2f0f5 5097 const char *pfx = alc_get_line_out_pfx(cfg, false);
e9edcee0
TI
5098 hda_nid_t nid;
5099 int i, err;
5100
5101 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 5102 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5103 continue;
5104 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5105 if (!pfx && i == 2) {
e9edcee0 5106 /* Center/LFE */
0afe5f89
TI
5107 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5108 "Center",
f12ab1e0
TI
5109 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5110 HDA_OUTPUT));
5111 if (err < 0)
e9edcee0 5112 return err;
0afe5f89
TI
5113 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5114 "LFE",
f12ab1e0
TI
5115 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5116 HDA_OUTPUT));
5117 if (err < 0)
e9edcee0 5118 return err;
0afe5f89
TI
5119 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5120 "Center",
f12ab1e0
TI
5121 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5122 HDA_INPUT));
5123 if (err < 0)
e9edcee0 5124 return err;
0afe5f89
TI
5125 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5126 "LFE",
f12ab1e0
TI
5127 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5128 HDA_INPUT));
5129 if (err < 0)
e9edcee0
TI
5130 return err;
5131 } else {
bcb2f0f5
TI
5132 const char *name = pfx;
5133 if (!name)
5134 name = chname[i];
5135 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5136 name, i,
f12ab1e0
TI
5137 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5138 HDA_OUTPUT));
5139 if (err < 0)
e9edcee0 5140 return err;
bcb2f0f5
TI
5141 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5142 name, i,
f12ab1e0
TI
5143 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5144 HDA_INPUT));
5145 if (err < 0)
e9edcee0
TI
5146 return err;
5147 }
5148 }
e9edcee0
TI
5149 return 0;
5150}
5151
8d88bc3d
TI
5152/* add playback controls for speaker and HP outputs */
5153static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5154 const char *pfx)
e9edcee0
TI
5155{
5156 hda_nid_t nid;
5157 int err;
5158
f12ab1e0 5159 if (!pin)
e9edcee0
TI
5160 return 0;
5161
5162 if (alc880_is_fixed_pin(pin)) {
5163 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5164 /* specify the DAC as the extra output */
f12ab1e0 5165 if (!spec->multiout.hp_nid)
e9edcee0 5166 spec->multiout.hp_nid = nid;
82bc955f
TI
5167 else
5168 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5169 /* control HP volume/switch on the output mixer amp */
5170 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5171 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5172 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5173 if (err < 0)
e9edcee0 5174 return err;
0afe5f89 5175 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5176 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5177 if (err < 0)
e9edcee0
TI
5178 return err;
5179 } else if (alc880_is_multi_pin(pin)) {
5180 /* set manual connection */
e9edcee0 5181 /* we have only a switch on HP-out PIN */
0afe5f89 5182 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5183 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5184 if (err < 0)
e9edcee0
TI
5185 return err;
5186 }
5187 return 0;
5188}
5189
5190/* create input playback/capture controls for the given pin */
f12ab1e0 5191static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5192 const char *ctlname, int ctlidx,
df694daa 5193 int idx, hda_nid_t mix_nid)
e9edcee0 5194{
df694daa 5195 int err;
e9edcee0 5196
66ceeb6b 5197 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5198 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5199 if (err < 0)
e9edcee0 5200 return err;
66ceeb6b 5201 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5202 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5203 if (err < 0)
e9edcee0
TI
5204 return err;
5205 return 0;
5206}
5207
05f5f477
TI
5208static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5209{
5210 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5211 return (pincap & AC_PINCAP_IN) != 0;
5212}
5213
e9edcee0 5214/* create playback/capture controls for input pins */
05f5f477
TI
5215static int alc_auto_create_input_ctls(struct hda_codec *codec,
5216 const struct auto_pin_cfg *cfg,
5217 hda_nid_t mixer,
5218 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5219{
05f5f477 5220 struct alc_spec *spec = codec->spec;
61b9b9b1 5221 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5222 int i, err, idx, type_idx = 0;
5223 const char *prev_label = NULL;
e9edcee0 5224
66ceeb6b 5225 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5226 hda_nid_t pin;
10a20af7 5227 const char *label;
05f5f477 5228
66ceeb6b 5229 pin = cfg->inputs[i].pin;
05f5f477
TI
5230 if (!alc_is_input_pin(codec, pin))
5231 continue;
5232
5322bf27
DH
5233 label = hda_get_autocfg_input_label(codec, cfg, i);
5234 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5235 type_idx++;
5236 else
5237 type_idx = 0;
5322bf27
DH
5238 prev_label = label;
5239
05f5f477
TI
5240 if (mixer) {
5241 idx = get_connection_index(codec, mixer, pin);
5242 if (idx >= 0) {
5243 err = new_analog_input(spec, pin,
10a20af7
TI
5244 label, type_idx,
5245 idx, mixer);
05f5f477
TI
5246 if (err < 0)
5247 return err;
5248 }
5249 }
5250
5251 if (!cap1)
5252 continue;
5253 idx = get_connection_index(codec, cap1, pin);
5254 if (idx < 0 && cap2)
5255 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5256 if (idx >= 0)
5257 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5258 }
5259 return 0;
5260}
5261
05f5f477
TI
5262static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5263 const struct auto_pin_cfg *cfg)
5264{
5265 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5266}
5267
f6c7e546
TI
5268static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5269 unsigned int pin_type)
5270{
5271 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5272 pin_type);
5273 /* unmute pin */
d260cdf6
TI
5274 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5275 AMP_OUT_UNMUTE);
f6c7e546
TI
5276}
5277
df694daa
KY
5278static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5279 hda_nid_t nid, int pin_type,
e9edcee0
TI
5280 int dac_idx)
5281{
f6c7e546 5282 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5283 /* need the manual connection? */
5284 if (alc880_is_multi_pin(nid)) {
5285 struct alc_spec *spec = codec->spec;
5286 int idx = alc880_multi_pin_idx(nid);
5287 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5288 AC_VERB_SET_CONNECT_SEL,
5289 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5290 }
5291}
5292
baba8ee9
TI
5293static int get_pin_type(int line_out_type)
5294{
5295 if (line_out_type == AUTO_PIN_HP_OUT)
5296 return PIN_HP;
5297 else
5298 return PIN_OUT;
5299}
5300
e9edcee0
TI
5301static void alc880_auto_init_multi_out(struct hda_codec *codec)
5302{
5303 struct alc_spec *spec = codec->spec;
5304 int i;
ea1fb29a 5305
e9edcee0
TI
5306 for (i = 0; i < spec->autocfg.line_outs; i++) {
5307 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5308 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5309 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5310 }
5311}
5312
8d88bc3d 5313static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5314{
5315 struct alc_spec *spec = codec->spec;
5316 hda_nid_t pin;
5317
82bc955f 5318 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5319 if (pin) /* connect to front */
5320 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5321 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5322 if (pin) /* connect to front */
5323 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5324}
5325
5326static void alc880_auto_init_analog_input(struct hda_codec *codec)
5327{
5328 struct alc_spec *spec = codec->spec;
66ceeb6b 5329 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5330 int i;
5331
66ceeb6b
TI
5332 for (i = 0; i < cfg->num_inputs; i++) {
5333 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5334 if (alc_is_input_pin(codec, nid)) {
30ea098f 5335 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5336 if (nid != ALC880_PIN_CD_NID &&
5337 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5338 snd_hda_codec_write(codec, nid, 0,
5339 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5340 AMP_OUT_MUTE);
5341 }
5342 }
5343}
5344
7f311a46
TI
5345static void alc880_auto_init_input_src(struct hda_codec *codec)
5346{
5347 struct alc_spec *spec = codec->spec;
5348 int c;
5349
5350 for (c = 0; c < spec->num_adc_nids; c++) {
5351 unsigned int mux_idx;
5352 const struct hda_input_mux *imux;
5353 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5354 imux = &spec->input_mux[mux_idx];
5355 if (!imux->num_items && mux_idx > 0)
5356 imux = &spec->input_mux[0];
5357 if (imux)
5358 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5359 AC_VERB_SET_CONNECT_SEL,
5360 imux->items[0].index);
5361 }
5362}
5363
e9edcee0 5364/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5365/* return 1 if successful, 0 if the proper config is not found,
5366 * or a negative error code
5367 */
e9edcee0
TI
5368static int alc880_parse_auto_config(struct hda_codec *codec)
5369{
5370 struct alc_spec *spec = codec->spec;
757899ac 5371 int err;
df694daa 5372 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5373
f12ab1e0
TI
5374 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5375 alc880_ignore);
5376 if (err < 0)
e9edcee0 5377 return err;
f12ab1e0 5378 if (!spec->autocfg.line_outs)
e9edcee0 5379 return 0; /* can't find valid BIOS pin config */
df694daa 5380
f12ab1e0
TI
5381 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5382 if (err < 0)
5383 return err;
5384 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5385 if (err < 0)
5386 return err;
5387 err = alc880_auto_create_extra_out(spec,
5388 spec->autocfg.speaker_pins[0],
5389 "Speaker");
5390 if (err < 0)
5391 return err;
5392 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5393 "Headphone");
5394 if (err < 0)
5395 return err;
05f5f477 5396 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5397 if (err < 0)
e9edcee0
TI
5398 return err;
5399
5400 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5401
757899ac 5402 alc_auto_parse_digital(codec);
e9edcee0 5403
603c4019 5404 if (spec->kctls.list)
d88897ea 5405 add_mixer(spec, spec->kctls.list);
e9edcee0 5406
d88897ea 5407 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5408
a1e8d2da 5409 spec->num_mux_defs = 1;
61b9b9b1 5410 spec->input_mux = &spec->private_imux[0];
e9edcee0 5411
6227cdce 5412 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5413
e9edcee0
TI
5414 return 1;
5415}
5416
ae6b813a
TI
5417/* additional initialization for auto-configuration model */
5418static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5419{
f6c7e546 5420 struct alc_spec *spec = codec->spec;
e9edcee0 5421 alc880_auto_init_multi_out(codec);
8d88bc3d 5422 alc880_auto_init_extra_out(codec);
e9edcee0 5423 alc880_auto_init_analog_input(codec);
7f311a46 5424 alc880_auto_init_input_src(codec);
757899ac 5425 alc_auto_init_digital(codec);
f6c7e546 5426 if (spec->unsol_event)
7fb0d78f 5427 alc_inithook(codec);
e9edcee0
TI
5428}
5429
b59bdf3b
TI
5430/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5431 * one of two digital mic pins, e.g. on ALC272
5432 */
5433static void fixup_automic_adc(struct hda_codec *codec)
5434{
5435 struct alc_spec *spec = codec->spec;
5436 int i;
5437
5438 for (i = 0; i < spec->num_adc_nids; i++) {
5439 hda_nid_t cap = spec->capsrc_nids ?
5440 spec->capsrc_nids[i] : spec->adc_nids[i];
5441 int iidx, eidx;
5442
5443 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5444 if (iidx < 0)
5445 continue;
5446 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5447 if (eidx < 0)
5448 continue;
5449 spec->int_mic.mux_idx = iidx;
5450 spec->ext_mic.mux_idx = eidx;
5451 if (spec->capsrc_nids)
5452 spec->capsrc_nids += i;
5453 spec->adc_nids += i;
5454 spec->num_adc_nids = 1;
5455 return;
5456 }
5457 snd_printd(KERN_INFO "hda_codec: %s: "
5458 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5459 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5460 spec->auto_mic = 0; /* disable auto-mic to be sure */
5461}
5462
748cce43
TI
5463/* select or unmute the given capsrc route */
5464static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5465 int idx)
5466{
5467 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5468 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5469 HDA_AMP_MUTE, 0);
5470 } else {
5471 snd_hda_codec_write_cache(codec, cap, 0,
5472 AC_VERB_SET_CONNECT_SEL, idx);
5473 }
5474}
5475
840b64c0
TI
5476/* set the default connection to that pin */
5477static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5478{
5479 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5480 int i;
5481
eaa9b3a7
TI
5482 for (i = 0; i < spec->num_adc_nids; i++) {
5483 hda_nid_t cap = spec->capsrc_nids ?
5484 spec->capsrc_nids[i] : spec->adc_nids[i];
5485 int idx;
5486
5487 idx = get_connection_index(codec, cap, pin);
5488 if (idx < 0)
5489 continue;
748cce43 5490 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5491 return i; /* return the found index */
5492 }
5493 return -1; /* not found */
5494}
5495
5496/* choose the ADC/MUX containing the input pin and initialize the setup */
5497static void fixup_single_adc(struct hda_codec *codec)
5498{
5499 struct alc_spec *spec = codec->spec;
66ceeb6b 5500 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5501 int i;
5502
5503 /* search for the input pin; there must be only one */
66ceeb6b 5504 if (cfg->num_inputs != 1)
eaa9b3a7 5505 return;
66ceeb6b 5506 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5507 if (i >= 0) {
5508 /* use only this ADC */
5509 if (spec->capsrc_nids)
5510 spec->capsrc_nids += i;
5511 spec->adc_nids += i;
5512 spec->num_adc_nids = 1;
eaa9b3a7
TI
5513 }
5514}
5515
840b64c0
TI
5516/* initialize dual adcs */
5517static void fixup_dual_adc_switch(struct hda_codec *codec)
5518{
5519 struct alc_spec *spec = codec->spec;
5520 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5521 init_capsrc_for_pin(codec, spec->int_mic.pin);
5522}
5523
b59bdf3b 5524static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5525{
b59bdf3b 5526 struct alc_spec *spec = codec->spec;
a23b688f
TI
5527 static struct snd_kcontrol_new *caps[2][3] = {
5528 { alc_capture_mixer_nosrc1,
5529 alc_capture_mixer_nosrc2,
5530 alc_capture_mixer_nosrc3 },
5531 { alc_capture_mixer1,
5532 alc_capture_mixer2,
5533 alc_capture_mixer3 },
f9e336f6 5534 };
a23b688f 5535 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5536 int mux = 0;
840b64c0
TI
5537 int num_adcs = spec->num_adc_nids;
5538 if (spec->dual_adc_switch)
5539 fixup_dual_adc_switch(codec);
5540 else if (spec->auto_mic)
b59bdf3b 5541 fixup_automic_adc(codec);
eaa9b3a7
TI
5542 else if (spec->input_mux) {
5543 if (spec->input_mux->num_items > 1)
5544 mux = 1;
5545 else if (spec->input_mux->num_items == 1)
5546 fixup_single_adc(codec);
5547 }
840b64c0
TI
5548 if (spec->dual_adc_switch)
5549 num_adcs = 1;
5550 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5551 }
f9e336f6
TI
5552}
5553
6694635d
TI
5554/* fill adc_nids (and capsrc_nids) containing all active input pins */
5555static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5556 int num_nids)
5557{
5558 struct alc_spec *spec = codec->spec;
66ceeb6b 5559 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5560 int n;
5561 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5562
5563 for (n = 0; n < num_nids; n++) {
5564 hda_nid_t adc, cap;
5565 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5566 int nconns, i, j;
5567
5568 adc = nids[n];
5569 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5570 continue;
5571 cap = adc;
5572 nconns = snd_hda_get_connections(codec, cap, conn,
5573 ARRAY_SIZE(conn));
5574 if (nconns == 1) {
5575 cap = conn[0];
5576 nconns = snd_hda_get_connections(codec, cap, conn,
5577 ARRAY_SIZE(conn));
5578 }
5579 if (nconns <= 0)
5580 continue;
5581 if (!fallback_adc) {
5582 fallback_adc = adc;
5583 fallback_cap = cap;
5584 }
66ceeb6b
TI
5585 for (i = 0; i < cfg->num_inputs; i++) {
5586 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5587 for (j = 0; j < nconns; j++) {
5588 if (conn[j] == nid)
5589 break;
5590 }
5591 if (j >= nconns)
5592 break;
5593 }
66ceeb6b 5594 if (i >= cfg->num_inputs) {
6694635d
TI
5595 int num_adcs = spec->num_adc_nids;
5596 spec->private_adc_nids[num_adcs] = adc;
5597 spec->private_capsrc_nids[num_adcs] = cap;
5598 spec->num_adc_nids++;
5599 spec->adc_nids = spec->private_adc_nids;
5600 if (adc != cap)
5601 spec->capsrc_nids = spec->private_capsrc_nids;
5602 }
5603 }
5604 if (!spec->num_adc_nids) {
5605 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5606 " using fallback 0x%x\n",
5607 codec->chip_name, fallback_adc);
6694635d
TI
5608 spec->private_adc_nids[0] = fallback_adc;
5609 spec->adc_nids = spec->private_adc_nids;
5610 if (fallback_adc != fallback_cap) {
5611 spec->private_capsrc_nids[0] = fallback_cap;
5612 spec->capsrc_nids = spec->private_adc_nids;
5613 }
5614 }
5615}
5616
67d634c0 5617#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5618#define set_beep_amp(spec, nid, idx, dir) \
5619 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5620
5621static struct snd_pci_quirk beep_white_list[] = {
5622 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5623 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5624 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5625 {}
5626};
5627
5628static inline int has_cdefine_beep(struct hda_codec *codec)
5629{
5630 struct alc_spec *spec = codec->spec;
5631 const struct snd_pci_quirk *q;
5632 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5633 if (q)
5634 return q->value;
5635 return spec->cdefine.enable_pcbeep;
5636}
67d634c0
TI
5637#else
5638#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5639#define has_cdefine_beep(codec) 0
67d634c0 5640#endif
45bdd1c1
TI
5641
5642/*
5643 * OK, here we have finally the patch for ALC880
5644 */
5645
1da177e4
LT
5646static int patch_alc880(struct hda_codec *codec)
5647{
5648 struct alc_spec *spec;
5649 int board_config;
df694daa 5650 int err;
1da177e4 5651
e560d8d8 5652 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5653 if (spec == NULL)
5654 return -ENOMEM;
5655
5656 codec->spec = spec;
5657
f5fcc13c
TI
5658 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5659 alc880_models,
5660 alc880_cfg_tbl);
5661 if (board_config < 0) {
9a11f1aa
TI
5662 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5663 codec->chip_name);
e9edcee0 5664 board_config = ALC880_AUTO;
1da177e4 5665 }
1da177e4 5666
e9edcee0
TI
5667 if (board_config == ALC880_AUTO) {
5668 /* automatic parse from the BIOS config */
5669 err = alc880_parse_auto_config(codec);
5670 if (err < 0) {
5671 alc_free(codec);
5672 return err;
f12ab1e0 5673 } else if (!err) {
9c7f852e
TI
5674 printk(KERN_INFO
5675 "hda_codec: Cannot set up configuration "
5676 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5677 board_config = ALC880_3ST;
5678 }
1da177e4
LT
5679 }
5680
680cd536
KK
5681 err = snd_hda_attach_beep_device(codec, 0x1);
5682 if (err < 0) {
5683 alc_free(codec);
5684 return err;
5685 }
5686
df694daa 5687 if (board_config != ALC880_AUTO)
e9c364c0 5688 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5689
1da177e4
LT
5690 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5691 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5692 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5693
1da177e4
LT
5694 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5695 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5696
f12ab1e0 5697 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5698 /* check whether NID 0x07 is valid */
54d17403 5699 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5700 /* get type */
a22d543a 5701 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5702 if (wcap != AC_WID_AUD_IN) {
5703 spec->adc_nids = alc880_adc_nids_alt;
5704 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5705 } else {
5706 spec->adc_nids = alc880_adc_nids;
5707 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5708 }
5709 }
b59bdf3b 5710 set_capture_mixer(codec);
45bdd1c1 5711 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5712
2134ea4f
TI
5713 spec->vmaster_nid = 0x0c;
5714
1da177e4 5715 codec->patch_ops = alc_patch_ops;
e9edcee0 5716 if (board_config == ALC880_AUTO)
ae6b813a 5717 spec->init_hook = alc880_auto_init;
cb53c626
TI
5718#ifdef CONFIG_SND_HDA_POWER_SAVE
5719 if (!spec->loopback.amplist)
5720 spec->loopback.amplist = alc880_loopbacks;
5721#endif
1da177e4
LT
5722
5723 return 0;
5724}
5725
e9edcee0 5726
1da177e4
LT
5727/*
5728 * ALC260 support
5729 */
5730
e9edcee0
TI
5731static hda_nid_t alc260_dac_nids[1] = {
5732 /* front */
5733 0x02,
5734};
5735
5736static hda_nid_t alc260_adc_nids[1] = {
5737 /* ADC0 */
5738 0x04,
5739};
5740
df694daa 5741static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5742 /* ADC1 */
5743 0x05,
5744};
5745
d57fdac0
JW
5746/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5747 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5748 */
5749static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5750 /* ADC0, ADC1 */
5751 0x04, 0x05
5752};
5753
e9edcee0
TI
5754#define ALC260_DIGOUT_NID 0x03
5755#define ALC260_DIGIN_NID 0x06
5756
5757static struct hda_input_mux alc260_capture_source = {
5758 .num_items = 4,
5759 .items = {
5760 { "Mic", 0x0 },
5761 { "Front Mic", 0x1 },
5762 { "Line", 0x2 },
5763 { "CD", 0x4 },
5764 },
5765};
5766
17e7aec6 5767/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5768 * headphone jack and the internal CD lines since these are the only pins at
5769 * which audio can appear. For flexibility, also allow the option of
5770 * recording the mixer output on the second ADC (ADC0 doesn't have a
5771 * connection to the mixer output).
a9430dd8 5772 */
a1e8d2da
JW
5773static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5774 {
5775 .num_items = 3,
5776 .items = {
5777 { "Mic/Line", 0x0 },
5778 { "CD", 0x4 },
5779 { "Headphone", 0x2 },
5780 },
a9430dd8 5781 },
a1e8d2da
JW
5782 {
5783 .num_items = 4,
5784 .items = {
5785 { "Mic/Line", 0x0 },
5786 { "CD", 0x4 },
5787 { "Headphone", 0x2 },
5788 { "Mixer", 0x5 },
5789 },
5790 },
5791
a9430dd8
JW
5792};
5793
a1e8d2da
JW
5794/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5795 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5796 */
a1e8d2da
JW
5797static struct hda_input_mux alc260_acer_capture_sources[2] = {
5798 {
5799 .num_items = 4,
5800 .items = {
5801 { "Mic", 0x0 },
5802 { "Line", 0x2 },
5803 { "CD", 0x4 },
5804 { "Headphone", 0x5 },
5805 },
5806 },
5807 {
5808 .num_items = 5,
5809 .items = {
5810 { "Mic", 0x0 },
5811 { "Line", 0x2 },
5812 { "CD", 0x4 },
5813 { "Headphone", 0x6 },
5814 { "Mixer", 0x5 },
5815 },
0bfc90e9
JW
5816 },
5817};
cc959489
MS
5818
5819/* Maxdata Favorit 100XS */
5820static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5821 {
5822 .num_items = 2,
5823 .items = {
5824 { "Line/Mic", 0x0 },
5825 { "CD", 0x4 },
5826 },
5827 },
5828 {
5829 .num_items = 3,
5830 .items = {
5831 { "Line/Mic", 0x0 },
5832 { "CD", 0x4 },
5833 { "Mixer", 0x5 },
5834 },
5835 },
5836};
5837
1da177e4
LT
5838/*
5839 * This is just place-holder, so there's something for alc_build_pcms to look
5840 * at when it calculates the maximum number of channels. ALC260 has no mixer
5841 * element which allows changing the channel mode, so the verb list is
5842 * never used.
5843 */
d2a6d7dc 5844static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5845 { 2, NULL },
5846};
5847
df694daa
KY
5848
5849/* Mixer combinations
5850 *
5851 * basic: base_output + input + pc_beep + capture
5852 * HP: base_output + input + capture_alt
5853 * HP_3013: hp_3013 + input + capture
5854 * fujitsu: fujitsu + capture
0bfc90e9 5855 * acer: acer + capture
df694daa
KY
5856 */
5857
5858static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5859 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5860 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5861 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5862 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5863 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5864 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5865 { } /* end */
f12ab1e0 5866};
1da177e4 5867
df694daa 5868static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5869 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5870 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5871 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5872 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5873 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5874 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5875 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5876 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5877 { } /* end */
5878};
5879
bec15c3a
TI
5880/* update HP, line and mono out pins according to the master switch */
5881static void alc260_hp_master_update(struct hda_codec *codec,
5882 hda_nid_t hp, hda_nid_t line,
5883 hda_nid_t mono)
5884{
5885 struct alc_spec *spec = codec->spec;
5886 unsigned int val = spec->master_sw ? PIN_HP : 0;
5887 /* change HP and line-out pins */
30cde0aa 5888 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5889 val);
30cde0aa 5890 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5891 val);
5892 /* mono (speaker) depending on the HP jack sense */
5893 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5894 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5895 val);
5896}
5897
5898static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5899 struct snd_ctl_elem_value *ucontrol)
5900{
5901 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5902 struct alc_spec *spec = codec->spec;
5903 *ucontrol->value.integer.value = spec->master_sw;
5904 return 0;
5905}
5906
5907static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5908 struct snd_ctl_elem_value *ucontrol)
5909{
5910 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5911 struct alc_spec *spec = codec->spec;
5912 int val = !!*ucontrol->value.integer.value;
5913 hda_nid_t hp, line, mono;
5914
5915 if (val == spec->master_sw)
5916 return 0;
5917 spec->master_sw = val;
5918 hp = (kcontrol->private_value >> 16) & 0xff;
5919 line = (kcontrol->private_value >> 8) & 0xff;
5920 mono = kcontrol->private_value & 0xff;
5921 alc260_hp_master_update(codec, hp, line, mono);
5922 return 1;
5923}
5924
5925static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5926 {
5927 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5928 .name = "Master Playback Switch",
5b0cb1d8 5929 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5930 .info = snd_ctl_boolean_mono_info,
5931 .get = alc260_hp_master_sw_get,
5932 .put = alc260_hp_master_sw_put,
5933 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5934 },
5935 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5936 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5937 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5938 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5939 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5940 HDA_OUTPUT),
5941 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5942 { } /* end */
5943};
5944
5945static struct hda_verb alc260_hp_unsol_verbs[] = {
5946 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5947 {},
5948};
5949
5950static void alc260_hp_automute(struct hda_codec *codec)
5951{
5952 struct alc_spec *spec = codec->spec;
bec15c3a 5953
864f92be 5954 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5955 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5956}
5957
5958static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5959{
5960 if ((res >> 26) == ALC880_HP_EVENT)
5961 alc260_hp_automute(codec);
5962}
5963
df694daa 5964static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5965 {
5966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5967 .name = "Master Playback Switch",
5b0cb1d8 5968 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5969 .info = snd_ctl_boolean_mono_info,
5970 .get = alc260_hp_master_sw_get,
5971 .put = alc260_hp_master_sw_put,
30cde0aa 5972 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5973 },
df694daa
KY
5974 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5975 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5976 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5977 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5978 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5979 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5980 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5981 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5982 { } /* end */
5983};
5984
3f878308
KY
5985static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5986 .ops = &snd_hda_bind_vol,
5987 .values = {
5988 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5989 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5990 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5991 0
5992 },
5993};
5994
5995static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5996 .ops = &snd_hda_bind_sw,
5997 .values = {
5998 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5999 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6000 0
6001 },
6002};
6003
6004static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6005 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6006 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6007 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6008 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6009 { } /* end */
6010};
6011
bec15c3a
TI
6012static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6013 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6014 {},
6015};
6016
6017static void alc260_hp_3013_automute(struct hda_codec *codec)
6018{
6019 struct alc_spec *spec = codec->spec;
bec15c3a 6020
864f92be 6021 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 6022 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
6023}
6024
6025static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6026 unsigned int res)
6027{
6028 if ((res >> 26) == ALC880_HP_EVENT)
6029 alc260_hp_3013_automute(codec);
6030}
6031
3f878308
KY
6032static void alc260_hp_3012_automute(struct hda_codec *codec)
6033{
864f92be 6034 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 6035
3f878308
KY
6036 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6037 bits);
6038 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6039 bits);
6040 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6041 bits);
6042}
6043
6044static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6045 unsigned int res)
6046{
6047 if ((res >> 26) == ALC880_HP_EVENT)
6048 alc260_hp_3012_automute(codec);
6049}
6050
6051/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6052 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6053 */
c8b6bf9b 6054static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6055 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6056 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6057 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6058 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6059 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6060 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6061 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6062 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6063 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6064 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6065 { } /* end */
6066};
6067
a1e8d2da
JW
6068/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6069 * versions of the ALC260 don't act on requests to enable mic bias from NID
6070 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6071 * datasheet doesn't mention this restriction. At this stage it's not clear
6072 * whether this behaviour is intentional or is a hardware bug in chip
6073 * revisions available in early 2006. Therefore for now allow the
6074 * "Headphone Jack Mode" control to span all choices, but if it turns out
6075 * that the lack of mic bias for this NID is intentional we could change the
6076 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6077 *
6078 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6079 * don't appear to make the mic bias available from the "line" jack, even
6080 * though the NID used for this jack (0x14) can supply it. The theory is
6081 * that perhaps Acer have included blocking capacitors between the ALC260
6082 * and the output jack. If this turns out to be the case for all such
6083 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6084 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6085 *
6086 * The C20x Tablet series have a mono internal speaker which is controlled
6087 * via the chip's Mono sum widget and pin complex, so include the necessary
6088 * controls for such models. On models without a "mono speaker" the control
6089 * won't do anything.
a1e8d2da 6090 */
0bfc90e9
JW
6091static struct snd_kcontrol_new alc260_acer_mixer[] = {
6092 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6093 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6094 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6095 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6096 HDA_OUTPUT),
31bffaa9 6097 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6098 HDA_INPUT),
0bfc90e9
JW
6099 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6100 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6101 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6102 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6103 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6104 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6105 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6106 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6107 { } /* end */
6108};
6109
cc959489
MS
6110/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6111 */
6112static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6113 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6114 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6115 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6116 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6117 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6118 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6119 { } /* end */
6120};
6121
bc9f98a9
KY
6122/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6123 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6124 */
6125static struct snd_kcontrol_new alc260_will_mixer[] = {
6126 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6127 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6129 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6130 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6131 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6132 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6133 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6134 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6135 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6136 { } /* end */
6137};
6138
6139/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6140 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6141 */
6142static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6143 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6144 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6146 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6147 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6148 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6149 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6150 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6151 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6152 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6153 { } /* end */
6154};
6155
df694daa
KY
6156/*
6157 * initialization verbs
6158 */
1da177e4
LT
6159static struct hda_verb alc260_init_verbs[] = {
6160 /* Line In pin widget for input */
05acb863 6161 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6162 /* CD pin widget for input */
05acb863 6163 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6164 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6165 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6166 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6167 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6168 /* LINE-2 is used for line-out in rear */
05acb863 6169 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6170 /* select line-out */
fd56f2db 6171 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6172 /* LINE-OUT pin */
05acb863 6173 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6174 /* enable HP */
05acb863 6175 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6176 /* enable Mono */
05acb863
TI
6177 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6178 /* mute capture amp left and right */
16ded525 6179 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6180 /* set connection select to line in (default select for this ADC) */
6181 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6182 /* mute capture amp left and right */
6183 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6184 /* set connection select to line in (default select for this ADC) */
6185 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6186 /* set vol=0 Line-Out mixer amp left and right */
6187 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6188 /* unmute pin widget amp left and right (no gain on this amp) */
6189 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6190 /* set vol=0 HP mixer amp left and right */
6191 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6192 /* unmute pin widget amp left and right (no gain on this amp) */
6193 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6194 /* set vol=0 Mono mixer amp left and right */
6195 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6196 /* unmute pin widget amp left and right (no gain on this amp) */
6197 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6198 /* unmute LINE-2 out pin */
6199 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6200 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6201 * Line In 2 = 0x03
6202 */
cb53c626
TI
6203 /* mute analog inputs */
6204 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6205 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6206 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6207 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6208 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6209 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6210 /* mute Front out path */
6211 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6212 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6213 /* mute Headphone out path */
6214 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6215 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6216 /* mute Mono out path */
6217 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6218 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6219 { }
6220};
6221
474167d6 6222#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6223static struct hda_verb alc260_hp_init_verbs[] = {
6224 /* Headphone and output */
6225 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6226 /* mono output */
6227 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6228 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6229 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6230 /* Mic2 (front panel) pin widget for input and vref at 80% */
6231 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6232 /* Line In pin widget for input */
6233 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6234 /* Line-2 pin widget for output */
6235 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6236 /* CD pin widget for input */
6237 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6238 /* unmute amp left and right */
6239 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6240 /* set connection select to line in (default select for this ADC) */
6241 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6242 /* unmute Line-Out mixer amp left and right (volume = 0) */
6243 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6244 /* mute pin widget amp left and right (no gain on this amp) */
6245 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6246 /* unmute HP mixer amp left and right (volume = 0) */
6247 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6248 /* mute pin widget amp left and right (no gain on this amp) */
6249 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6250 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6251 * Line In 2 = 0x03
6252 */
cb53c626
TI
6253 /* mute analog inputs */
6254 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6256 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6259 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6260 /* Unmute Front out path */
6261 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6262 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6263 /* Unmute Headphone out path */
6264 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6265 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6266 /* Unmute Mono out path */
6267 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6268 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6269 { }
6270};
474167d6 6271#endif
df694daa
KY
6272
6273static struct hda_verb alc260_hp_3013_init_verbs[] = {
6274 /* Line out and output */
6275 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6276 /* mono output */
6277 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6278 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6279 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6280 /* Mic2 (front panel) pin widget for input and vref at 80% */
6281 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6282 /* Line In pin widget for input */
6283 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6284 /* Headphone pin widget for output */
6285 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6286 /* CD pin widget for input */
6287 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6288 /* unmute amp left and right */
6289 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6290 /* set connection select to line in (default select for this ADC) */
6291 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6292 /* unmute Line-Out mixer amp left and right (volume = 0) */
6293 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6294 /* mute pin widget amp left and right (no gain on this amp) */
6295 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6296 /* unmute HP mixer amp left and right (volume = 0) */
6297 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6298 /* mute pin widget amp left and right (no gain on this amp) */
6299 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6300 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6301 * Line In 2 = 0x03
6302 */
cb53c626
TI
6303 /* mute analog inputs */
6304 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6305 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6306 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6307 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6308 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6309 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6310 /* Unmute Front out path */
6311 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6312 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6313 /* Unmute Headphone out path */
6314 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6315 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6316 /* Unmute Mono out path */
6317 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6318 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6319 { }
6320};
6321
a9430dd8 6322/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6323 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6324 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6325 */
6326static struct hda_verb alc260_fujitsu_init_verbs[] = {
6327 /* Disable all GPIOs */
6328 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6329 /* Internal speaker is connected to headphone pin */
6330 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6331 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6332 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6333 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6334 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6335 /* Ensure all other unused pins are disabled and muted. */
6336 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6337 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6338 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6339 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6340 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6341 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6343 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6344
6345 /* Disable digital (SPDIF) pins */
6346 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6347 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6348
ea1fb29a 6349 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6350 * when acting as an output.
6351 */
6352 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6353
f7ace40d 6354 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6355 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6357 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6358 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6359 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6360 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6361 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6362 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6363 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6364
f7ace40d
JW
6365 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6366 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6367 /* Unmute Line1 pin widget output buffer since it starts as an output.
6368 * If the pin mode is changed by the user the pin mode control will
6369 * take care of enabling the pin's input/output buffers as needed.
6370 * Therefore there's no need to enable the input buffer at this
6371 * stage.
cdcd9268 6372 */
f7ace40d 6373 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6374 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6375 * mixer ctrl)
6376 */
f7ace40d
JW
6377 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6378
6379 /* Mute capture amp left and right */
6380 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6381 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6382 * in (on mic1 pin)
6383 */
6384 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6385
6386 /* Do the same for the second ADC: mute capture input amp and
6387 * set ADC connection to line in (on mic1 pin)
6388 */
6389 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6390 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6391
6392 /* Mute all inputs to mixer widget (even unconnected ones) */
6393 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6394 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6395 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6397 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6398 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6400 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6401
6402 { }
a9430dd8
JW
6403};
6404
0bfc90e9
JW
6405/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6406 * similar laptops (adapted from Fujitsu init verbs).
6407 */
6408static struct hda_verb alc260_acer_init_verbs[] = {
6409 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6410 * the headphone jack. Turn this on and rely on the standard mute
6411 * methods whenever the user wants to turn these outputs off.
6412 */
6413 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6414 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6415 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6416 /* Internal speaker/Headphone jack is connected to Line-out pin */
6417 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6418 /* Internal microphone/Mic jack is connected to Mic1 pin */
6419 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6420 /* Line In jack is connected to Line1 pin */
6421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6422 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6423 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6424 /* Ensure all other unused pins are disabled and muted. */
6425 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6426 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6427 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6428 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6429 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6431 /* Disable digital (SPDIF) pins */
6432 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6433 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6434
ea1fb29a 6435 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6436 * bus when acting as outputs.
6437 */
6438 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6439 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6440
6441 /* Start with output sum widgets muted and their output gains at min */
6442 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6443 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6444 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6445 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6447 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6448 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6449 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6450 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6451
f12ab1e0
TI
6452 /* Unmute Line-out pin widget amp left and right
6453 * (no equiv mixer ctrl)
6454 */
0bfc90e9 6455 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6456 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6457 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6458 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6459 * inputs. If the pin mode is changed by the user the pin mode control
6460 * will take care of enabling the pin's input/output buffers as needed.
6461 * Therefore there's no need to enable the input buffer at this
6462 * stage.
6463 */
6464 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6465 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6466
6467 /* Mute capture amp left and right */
6468 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6469 /* Set ADC connection select to match default mixer setting - mic
6470 * (on mic1 pin)
6471 */
6472 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6473
6474 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6475 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6476 */
6477 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6478 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6479
6480 /* Mute all inputs to mixer widget (even unconnected ones) */
6481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6482 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6485 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6487 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6489
6490 { }
6491};
6492
cc959489
MS
6493/* Initialisation sequence for Maxdata Favorit 100XS
6494 * (adapted from Acer init verbs).
6495 */
6496static struct hda_verb alc260_favorit100_init_verbs[] = {
6497 /* GPIO 0 enables the output jack.
6498 * Turn this on and rely on the standard mute
6499 * methods whenever the user wants to turn these outputs off.
6500 */
6501 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6502 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6503 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6504 /* Line/Mic input jack is connected to Mic1 pin */
6505 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6506 /* Ensure all other unused pins are disabled and muted. */
6507 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6508 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6509 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6510 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6511 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6512 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6514 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6515 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6516 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6517 /* Disable digital (SPDIF) pins */
6518 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6519 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6520
6521 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6522 * bus when acting as outputs.
6523 */
6524 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6525 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6526
6527 /* Start with output sum widgets muted and their output gains at min */
6528 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6531 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6533 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6534 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6535 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6536 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6537
6538 /* Unmute Line-out pin widget amp left and right
6539 * (no equiv mixer ctrl)
6540 */
6541 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6542 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6543 * inputs. If the pin mode is changed by the user the pin mode control
6544 * will take care of enabling the pin's input/output buffers as needed.
6545 * Therefore there's no need to enable the input buffer at this
6546 * stage.
6547 */
6548 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6549
6550 /* Mute capture amp left and right */
6551 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6552 /* Set ADC connection select to match default mixer setting - mic
6553 * (on mic1 pin)
6554 */
6555 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6556
6557 /* Do similar with the second ADC: mute capture input amp and
6558 * set ADC connection to mic to match ALSA's default state.
6559 */
6560 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6561 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6562
6563 /* Mute all inputs to mixer widget (even unconnected ones) */
6564 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6570 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6571 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6572
6573 { }
6574};
6575
bc9f98a9
KY
6576static struct hda_verb alc260_will_verbs[] = {
6577 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6578 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6579 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6580 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6581 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6582 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6583 {}
6584};
6585
6586static struct hda_verb alc260_replacer_672v_verbs[] = {
6587 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6588 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6589 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6590
6591 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6592 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6593 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6594
6595 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6596 {}
6597};
6598
6599/* toggle speaker-output according to the hp-jack state */
6600static void alc260_replacer_672v_automute(struct hda_codec *codec)
6601{
6602 unsigned int present;
6603
6604 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6605 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6606 if (present) {
82beb8fd
TI
6607 snd_hda_codec_write_cache(codec, 0x01, 0,
6608 AC_VERB_SET_GPIO_DATA, 1);
6609 snd_hda_codec_write_cache(codec, 0x0f, 0,
6610 AC_VERB_SET_PIN_WIDGET_CONTROL,
6611 PIN_HP);
bc9f98a9 6612 } else {
82beb8fd
TI
6613 snd_hda_codec_write_cache(codec, 0x01, 0,
6614 AC_VERB_SET_GPIO_DATA, 0);
6615 snd_hda_codec_write_cache(codec, 0x0f, 0,
6616 AC_VERB_SET_PIN_WIDGET_CONTROL,
6617 PIN_OUT);
bc9f98a9
KY
6618 }
6619}
6620
6621static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6622 unsigned int res)
6623{
6624 if ((res >> 26) == ALC880_HP_EVENT)
6625 alc260_replacer_672v_automute(codec);
6626}
6627
3f878308
KY
6628static struct hda_verb alc260_hp_dc7600_verbs[] = {
6629 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6630 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6631 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6632 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6633 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6634 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6635 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6636 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6637 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6638 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6639 {}
6640};
6641
7cf51e48
JW
6642/* Test configuration for debugging, modelled after the ALC880 test
6643 * configuration.
6644 */
6645#ifdef CONFIG_SND_DEBUG
6646static hda_nid_t alc260_test_dac_nids[1] = {
6647 0x02,
6648};
6649static hda_nid_t alc260_test_adc_nids[2] = {
6650 0x04, 0x05,
6651};
a1e8d2da 6652/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6653 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6654 * is NID 0x04.
17e7aec6 6655 */
a1e8d2da
JW
6656static struct hda_input_mux alc260_test_capture_sources[2] = {
6657 {
6658 .num_items = 7,
6659 .items = {
6660 { "MIC1 pin", 0x0 },
6661 { "MIC2 pin", 0x1 },
6662 { "LINE1 pin", 0x2 },
6663 { "LINE2 pin", 0x3 },
6664 { "CD pin", 0x4 },
6665 { "LINE-OUT pin", 0x5 },
6666 { "HP-OUT pin", 0x6 },
6667 },
6668 },
6669 {
6670 .num_items = 8,
6671 .items = {
6672 { "MIC1 pin", 0x0 },
6673 { "MIC2 pin", 0x1 },
6674 { "LINE1 pin", 0x2 },
6675 { "LINE2 pin", 0x3 },
6676 { "CD pin", 0x4 },
6677 { "Mixer", 0x5 },
6678 { "LINE-OUT pin", 0x6 },
6679 { "HP-OUT pin", 0x7 },
6680 },
7cf51e48
JW
6681 },
6682};
6683static struct snd_kcontrol_new alc260_test_mixer[] = {
6684 /* Output driver widgets */
6685 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6686 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6687 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6688 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6689 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6690 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6691
a1e8d2da
JW
6692 /* Modes for retasking pin widgets
6693 * Note: the ALC260 doesn't seem to act on requests to enable mic
6694 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6695 * mention this restriction. At this stage it's not clear whether
6696 * this behaviour is intentional or is a hardware bug in chip
6697 * revisions available at least up until early 2006. Therefore for
6698 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6699 * choices, but if it turns out that the lack of mic bias for these
6700 * NIDs is intentional we could change their modes from
6701 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6702 */
7cf51e48
JW
6703 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6704 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6705 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6706 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6707 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6708 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6709
6710 /* Loopback mixer controls */
6711 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6712 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6713 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6714 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6715 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6716 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6717 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6718 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6719 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6720 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6721 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6722 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6723 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6724 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6725
6726 /* Controls for GPIO pins, assuming they are configured as outputs */
6727 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6728 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6729 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6730 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6731
92621f13
JW
6732 /* Switches to allow the digital IO pins to be enabled. The datasheet
6733 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6734 * make this output available should provide clarification.
92621f13
JW
6735 */
6736 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6737 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6738
f8225f6d
JW
6739 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6740 * this output to turn on an external amplifier.
6741 */
6742 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6743 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6744
7cf51e48
JW
6745 { } /* end */
6746};
6747static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6748 /* Enable all GPIOs as outputs with an initial value of 0 */
6749 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6750 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6751 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6752
7cf51e48
JW
6753 /* Enable retasking pins as output, initially without power amp */
6754 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6755 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6756 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6757 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6758 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6759 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6760
92621f13
JW
6761 /* Disable digital (SPDIF) pins initially, but users can enable
6762 * them via a mixer switch. In the case of SPDIF-out, this initverb
6763 * payload also sets the generation to 0, output to be in "consumer"
6764 * PCM format, copyright asserted, no pre-emphasis and no validity
6765 * control.
6766 */
7cf51e48
JW
6767 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6768 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6769
ea1fb29a 6770 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6771 * OUT1 sum bus when acting as an output.
6772 */
6773 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6774 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6775 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6776 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6777
6778 /* Start with output sum widgets muted and their output gains at min */
6779 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6780 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6781 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6782 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6783 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6784 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6785 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6786 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6787 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6788
cdcd9268
JW
6789 /* Unmute retasking pin widget output buffers since the default
6790 * state appears to be output. As the pin mode is changed by the
6791 * user the pin mode control will take care of enabling the pin's
6792 * input/output buffers as needed.
6793 */
7cf51e48
JW
6794 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6795 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6798 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6799 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6800 /* Also unmute the mono-out pin widget */
6801 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6802
7cf51e48
JW
6803 /* Mute capture amp left and right */
6804 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6805 /* Set ADC connection select to match default mixer setting (mic1
6806 * pin)
7cf51e48
JW
6807 */
6808 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6809
6810 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6811 * set ADC connection to mic1 pin
7cf51e48
JW
6812 */
6813 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6814 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6815
6816 /* Mute all inputs to mixer widget (even unconnected ones) */
6817 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6820 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6821 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6822 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6823 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6824 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6825
6826 { }
6827};
6828#endif
6829
6330079f
TI
6830#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6831#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6832
a3bcba38
TI
6833#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6834#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6835
df694daa
KY
6836/*
6837 * for BIOS auto-configuration
6838 */
16ded525 6839
df694daa 6840static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6841 const char *pfx, int *vol_bits)
df694daa
KY
6842{
6843 hda_nid_t nid_vol;
6844 unsigned long vol_val, sw_val;
df694daa
KY
6845 int err;
6846
6847 if (nid >= 0x0f && nid < 0x11) {
6848 nid_vol = nid - 0x7;
6849 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6850 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6851 } else if (nid == 0x11) {
6852 nid_vol = nid - 0x7;
6853 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6854 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6855 } else if (nid >= 0x12 && nid <= 0x15) {
6856 nid_vol = 0x08;
6857 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6858 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6859 } else
6860 return 0; /* N/A */
ea1fb29a 6861
863b4518
TI
6862 if (!(*vol_bits & (1 << nid_vol))) {
6863 /* first control for the volume widget */
0afe5f89 6864 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6865 if (err < 0)
6866 return err;
6867 *vol_bits |= (1 << nid_vol);
6868 }
0afe5f89 6869 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6870 if (err < 0)
df694daa
KY
6871 return err;
6872 return 1;
6873}
6874
6875/* add playback controls from the parsed DAC table */
6876static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6877 const struct auto_pin_cfg *cfg)
6878{
6879 hda_nid_t nid;
6880 int err;
863b4518 6881 int vols = 0;
df694daa
KY
6882
6883 spec->multiout.num_dacs = 1;
6884 spec->multiout.dac_nids = spec->private_dac_nids;
6885 spec->multiout.dac_nids[0] = 0x02;
6886
6887 nid = cfg->line_out_pins[0];
6888 if (nid) {
23112d6d
TI
6889 const char *pfx;
6890 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6891 pfx = "Master";
6892 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6893 pfx = "Speaker";
6894 else
6895 pfx = "Front";
6896 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6897 if (err < 0)
6898 return err;
6899 }
6900
82bc955f 6901 nid = cfg->speaker_pins[0];
df694daa 6902 if (nid) {
863b4518 6903 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6904 if (err < 0)
6905 return err;
6906 }
6907
eb06ed8f 6908 nid = cfg->hp_pins[0];
df694daa 6909 if (nid) {
863b4518
TI
6910 err = alc260_add_playback_controls(spec, nid, "Headphone",
6911 &vols);
df694daa
KY
6912 if (err < 0)
6913 return err;
6914 }
f12ab1e0 6915 return 0;
df694daa
KY
6916}
6917
6918/* create playback/capture controls for input pins */
05f5f477 6919static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6920 const struct auto_pin_cfg *cfg)
6921{
05f5f477 6922 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6923}
6924
6925static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6926 hda_nid_t nid, int pin_type,
6927 int sel_idx)
6928{
f6c7e546 6929 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6930 /* need the manual connection? */
6931 if (nid >= 0x12) {
6932 int idx = nid - 0x12;
6933 snd_hda_codec_write(codec, idx + 0x0b, 0,
6934 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6935 }
6936}
6937
6938static void alc260_auto_init_multi_out(struct hda_codec *codec)
6939{
6940 struct alc_spec *spec = codec->spec;
6941 hda_nid_t nid;
6942
f12ab1e0 6943 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6944 if (nid) {
6945 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6946 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6947 }
ea1fb29a 6948
82bc955f 6949 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6950 if (nid)
6951 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6952
eb06ed8f 6953 nid = spec->autocfg.hp_pins[0];
df694daa 6954 if (nid)
baba8ee9 6955 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6956}
df694daa
KY
6957
6958#define ALC260_PIN_CD_NID 0x16
6959static void alc260_auto_init_analog_input(struct hda_codec *codec)
6960{
6961 struct alc_spec *spec = codec->spec;
66ceeb6b 6962 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6963 int i;
6964
66ceeb6b
TI
6965 for (i = 0; i < cfg->num_inputs; i++) {
6966 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6967 if (nid >= 0x12) {
30ea098f 6968 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6969 if (nid != ALC260_PIN_CD_NID &&
6970 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6971 snd_hda_codec_write(codec, nid, 0,
6972 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6973 AMP_OUT_MUTE);
6974 }
6975 }
6976}
6977
7f311a46
TI
6978#define alc260_auto_init_input_src alc880_auto_init_input_src
6979
df694daa
KY
6980/*
6981 * generic initialization of ADC, input mixers and output mixers
6982 */
6983static struct hda_verb alc260_volume_init_verbs[] = {
6984 /*
6985 * Unmute ADC0-1 and set the default input to mic-in
6986 */
6987 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6988 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6989 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6990 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6991
df694daa
KY
6992 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6993 * mixer widget
f12ab1e0
TI
6994 * Note: PASD motherboards uses the Line In 2 as the input for
6995 * front panel mic (mic 2)
df694daa
KY
6996 */
6997 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6998 /* mute analog inputs */
6999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7000 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7001 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7002 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7003 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7004
7005 /*
7006 * Set up output mixers (0x08 - 0x0a)
7007 */
7008 /* set vol=0 to output mixers */
7009 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7010 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7011 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7012 /* set up input amps for analog loopback */
7013 /* Amp Indices: DAC = 0, mixer = 1 */
7014 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7015 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7016 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7017 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7018 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7019 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7020
df694daa
KY
7021 { }
7022};
7023
7024static int alc260_parse_auto_config(struct hda_codec *codec)
7025{
7026 struct alc_spec *spec = codec->spec;
df694daa
KY
7027 int err;
7028 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7029
f12ab1e0
TI
7030 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7031 alc260_ignore);
7032 if (err < 0)
df694daa 7033 return err;
f12ab1e0
TI
7034 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7035 if (err < 0)
4a471b7d 7036 return err;
603c4019 7037 if (!spec->kctls.list)
df694daa 7038 return 0; /* can't find valid BIOS pin config */
05f5f477 7039 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7040 if (err < 0)
df694daa
KY
7041 return err;
7042
7043 spec->multiout.max_channels = 2;
7044
0852d7a6 7045 if (spec->autocfg.dig_outs)
df694daa 7046 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7047 if (spec->kctls.list)
d88897ea 7048 add_mixer(spec, spec->kctls.list);
df694daa 7049
d88897ea 7050 add_verb(spec, alc260_volume_init_verbs);
df694daa 7051
a1e8d2da 7052 spec->num_mux_defs = 1;
61b9b9b1 7053 spec->input_mux = &spec->private_imux[0];
df694daa 7054
6227cdce 7055 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7056
df694daa
KY
7057 return 1;
7058}
7059
ae6b813a
TI
7060/* additional initialization for auto-configuration model */
7061static void alc260_auto_init(struct hda_codec *codec)
df694daa 7062{
f6c7e546 7063 struct alc_spec *spec = codec->spec;
df694daa
KY
7064 alc260_auto_init_multi_out(codec);
7065 alc260_auto_init_analog_input(codec);
7f311a46 7066 alc260_auto_init_input_src(codec);
757899ac 7067 alc_auto_init_digital(codec);
f6c7e546 7068 if (spec->unsol_event)
7fb0d78f 7069 alc_inithook(codec);
df694daa
KY
7070}
7071
cb53c626
TI
7072#ifdef CONFIG_SND_HDA_POWER_SAVE
7073static struct hda_amp_list alc260_loopbacks[] = {
7074 { 0x07, HDA_INPUT, 0 },
7075 { 0x07, HDA_INPUT, 1 },
7076 { 0x07, HDA_INPUT, 2 },
7077 { 0x07, HDA_INPUT, 3 },
7078 { 0x07, HDA_INPUT, 4 },
7079 { } /* end */
7080};
7081#endif
7082
fc091769
TI
7083/*
7084 * Pin config fixes
7085 */
7086enum {
7087 PINFIX_HP_DC5750,
7088};
7089
fc091769
TI
7090static const struct alc_fixup alc260_fixups[] = {
7091 [PINFIX_HP_DC5750] = {
73413b12
TI
7092 .pins = (const struct alc_pincfg[]) {
7093 { 0x11, 0x90130110 }, /* speaker */
7094 { }
7095 }
fc091769
TI
7096 },
7097};
7098
7099static struct snd_pci_quirk alc260_fixup_tbl[] = {
7100 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7101 {}
7102};
7103
df694daa
KY
7104/*
7105 * ALC260 configurations
7106 */
f5fcc13c
TI
7107static const char *alc260_models[ALC260_MODEL_LAST] = {
7108 [ALC260_BASIC] = "basic",
7109 [ALC260_HP] = "hp",
7110 [ALC260_HP_3013] = "hp-3013",
2922c9af 7111 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7112 [ALC260_FUJITSU_S702X] = "fujitsu",
7113 [ALC260_ACER] = "acer",
bc9f98a9
KY
7114 [ALC260_WILL] = "will",
7115 [ALC260_REPLACER_672V] = "replacer",
cc959489 7116 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7117#ifdef CONFIG_SND_DEBUG
f5fcc13c 7118 [ALC260_TEST] = "test",
7cf51e48 7119#endif
f5fcc13c
TI
7120 [ALC260_AUTO] = "auto",
7121};
7122
7123static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7124 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7125 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7126 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7127 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7128 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7129 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7130 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7131 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7132 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7133 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7134 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7135 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7136 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7137 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7138 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7139 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7140 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7141 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7142 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7143 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7144 {}
7145};
7146
7147static struct alc_config_preset alc260_presets[] = {
7148 [ALC260_BASIC] = {
7149 .mixers = { alc260_base_output_mixer,
45bdd1c1 7150 alc260_input_mixer },
df694daa
KY
7151 .init_verbs = { alc260_init_verbs },
7152 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7153 .dac_nids = alc260_dac_nids,
f9e336f6 7154 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7155 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7156 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7157 .channel_mode = alc260_modes,
7158 .input_mux = &alc260_capture_source,
7159 },
7160 [ALC260_HP] = {
bec15c3a 7161 .mixers = { alc260_hp_output_mixer,
f9e336f6 7162 alc260_input_mixer },
bec15c3a
TI
7163 .init_verbs = { alc260_init_verbs,
7164 alc260_hp_unsol_verbs },
df694daa
KY
7165 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7166 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7167 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7168 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7169 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7170 .channel_mode = alc260_modes,
7171 .input_mux = &alc260_capture_source,
bec15c3a
TI
7172 .unsol_event = alc260_hp_unsol_event,
7173 .init_hook = alc260_hp_automute,
df694daa 7174 },
3f878308
KY
7175 [ALC260_HP_DC7600] = {
7176 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7177 alc260_input_mixer },
3f878308
KY
7178 .init_verbs = { alc260_init_verbs,
7179 alc260_hp_dc7600_verbs },
7180 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7181 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7182 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7183 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7184 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7185 .channel_mode = alc260_modes,
7186 .input_mux = &alc260_capture_source,
7187 .unsol_event = alc260_hp_3012_unsol_event,
7188 .init_hook = alc260_hp_3012_automute,
7189 },
df694daa
KY
7190 [ALC260_HP_3013] = {
7191 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7192 alc260_input_mixer },
bec15c3a
TI
7193 .init_verbs = { alc260_hp_3013_init_verbs,
7194 alc260_hp_3013_unsol_verbs },
df694daa
KY
7195 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7196 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7197 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7198 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7199 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7200 .channel_mode = alc260_modes,
7201 .input_mux = &alc260_capture_source,
bec15c3a
TI
7202 .unsol_event = alc260_hp_3013_unsol_event,
7203 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7204 },
7205 [ALC260_FUJITSU_S702X] = {
f9e336f6 7206 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7207 .init_verbs = { alc260_fujitsu_init_verbs },
7208 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7209 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7210 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7211 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7212 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7213 .channel_mode = alc260_modes,
a1e8d2da
JW
7214 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7215 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7216 },
0bfc90e9 7217 [ALC260_ACER] = {
f9e336f6 7218 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7219 .init_verbs = { alc260_acer_init_verbs },
7220 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7221 .dac_nids = alc260_dac_nids,
7222 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7223 .adc_nids = alc260_dual_adc_nids,
7224 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7225 .channel_mode = alc260_modes,
a1e8d2da
JW
7226 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7227 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7228 },
cc959489
MS
7229 [ALC260_FAVORIT100] = {
7230 .mixers = { alc260_favorit100_mixer },
7231 .init_verbs = { alc260_favorit100_init_verbs },
7232 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7233 .dac_nids = alc260_dac_nids,
7234 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7235 .adc_nids = alc260_dual_adc_nids,
7236 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7237 .channel_mode = alc260_modes,
7238 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7239 .input_mux = alc260_favorit100_capture_sources,
7240 },
bc9f98a9 7241 [ALC260_WILL] = {
f9e336f6 7242 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7243 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7244 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7245 .dac_nids = alc260_dac_nids,
7246 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7247 .adc_nids = alc260_adc_nids,
7248 .dig_out_nid = ALC260_DIGOUT_NID,
7249 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7250 .channel_mode = alc260_modes,
7251 .input_mux = &alc260_capture_source,
7252 },
7253 [ALC260_REPLACER_672V] = {
f9e336f6 7254 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7255 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7256 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7257 .dac_nids = alc260_dac_nids,
7258 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7259 .adc_nids = alc260_adc_nids,
7260 .dig_out_nid = ALC260_DIGOUT_NID,
7261 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7262 .channel_mode = alc260_modes,
7263 .input_mux = &alc260_capture_source,
7264 .unsol_event = alc260_replacer_672v_unsol_event,
7265 .init_hook = alc260_replacer_672v_automute,
7266 },
7cf51e48
JW
7267#ifdef CONFIG_SND_DEBUG
7268 [ALC260_TEST] = {
f9e336f6 7269 .mixers = { alc260_test_mixer },
7cf51e48
JW
7270 .init_verbs = { alc260_test_init_verbs },
7271 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7272 .dac_nids = alc260_test_dac_nids,
7273 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7274 .adc_nids = alc260_test_adc_nids,
7275 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7276 .channel_mode = alc260_modes,
a1e8d2da
JW
7277 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7278 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7279 },
7280#endif
df694daa
KY
7281};
7282
7283static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7284{
7285 struct alc_spec *spec;
df694daa 7286 int err, board_config;
1da177e4 7287
e560d8d8 7288 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7289 if (spec == NULL)
7290 return -ENOMEM;
7291
7292 codec->spec = spec;
7293
f5fcc13c
TI
7294 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7295 alc260_models,
7296 alc260_cfg_tbl);
7297 if (board_config < 0) {
9a11f1aa 7298 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7299 codec->chip_name);
df694daa 7300 board_config = ALC260_AUTO;
16ded525 7301 }
1da177e4 7302
fc091769
TI
7303 if (board_config == ALC260_AUTO)
7304 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1);
7305
df694daa
KY
7306 if (board_config == ALC260_AUTO) {
7307 /* automatic parse from the BIOS config */
7308 err = alc260_parse_auto_config(codec);
7309 if (err < 0) {
7310 alc_free(codec);
7311 return err;
f12ab1e0 7312 } else if (!err) {
9c7f852e
TI
7313 printk(KERN_INFO
7314 "hda_codec: Cannot set up configuration "
7315 "from BIOS. Using base mode...\n");
df694daa
KY
7316 board_config = ALC260_BASIC;
7317 }
a9430dd8 7318 }
e9edcee0 7319
680cd536
KK
7320 err = snd_hda_attach_beep_device(codec, 0x1);
7321 if (err < 0) {
7322 alc_free(codec);
7323 return err;
7324 }
7325
df694daa 7326 if (board_config != ALC260_AUTO)
e9c364c0 7327 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7328
1da177e4
LT
7329 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7330 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7331 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7332
a3bcba38
TI
7333 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7334 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7335
4ef0ef19
TI
7336 if (!spec->adc_nids && spec->input_mux) {
7337 /* check whether NID 0x04 is valid */
7338 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7339 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7340 /* get type */
7341 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7342 spec->adc_nids = alc260_adc_nids_alt;
7343 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7344 } else {
7345 spec->adc_nids = alc260_adc_nids;
7346 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7347 }
7348 }
b59bdf3b 7349 set_capture_mixer(codec);
45bdd1c1 7350 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7351
fc091769
TI
7352 if (board_config == ALC260_AUTO)
7353 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0);
7354
2134ea4f
TI
7355 spec->vmaster_nid = 0x08;
7356
1da177e4 7357 codec->patch_ops = alc_patch_ops;
df694daa 7358 if (board_config == ALC260_AUTO)
ae6b813a 7359 spec->init_hook = alc260_auto_init;
cb53c626
TI
7360#ifdef CONFIG_SND_HDA_POWER_SAVE
7361 if (!spec->loopback.amplist)
7362 spec->loopback.amplist = alc260_loopbacks;
7363#endif
1da177e4
LT
7364
7365 return 0;
7366}
7367
e9edcee0 7368
1da177e4 7369/*
4953550a 7370 * ALC882/883/885/888/889 support
1da177e4
LT
7371 *
7372 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7373 * configuration. Each pin widget can choose any input DACs and a mixer.
7374 * Each ADC is connected from a mixer of all inputs. This makes possible
7375 * 6-channel independent captures.
7376 *
7377 * In addition, an independent DAC for the multi-playback (not used in this
7378 * driver yet).
7379 */
df694daa
KY
7380#define ALC882_DIGOUT_NID 0x06
7381#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7382#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7383#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7384#define ALC1200_DIGOUT_NID 0x10
7385
1da177e4 7386
d2a6d7dc 7387static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7388 { 8, NULL }
7389};
7390
4953550a 7391/* DACs */
1da177e4
LT
7392static hda_nid_t alc882_dac_nids[4] = {
7393 /* front, rear, clfe, rear_surr */
7394 0x02, 0x03, 0x04, 0x05
7395};
4953550a 7396#define alc883_dac_nids alc882_dac_nids
1da177e4 7397
4953550a 7398/* ADCs */
df694daa
KY
7399#define alc882_adc_nids alc880_adc_nids
7400#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7401#define alc883_adc_nids alc882_adc_nids_alt
7402static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7403static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7404#define alc889_adc_nids alc880_adc_nids
1da177e4 7405
e1406348
TI
7406static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7407static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7408#define alc883_capsrc_nids alc882_capsrc_nids_alt
7409static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7410#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7411
1da177e4
LT
7412/* input MUX */
7413/* FIXME: should be a matrix-type input source selection */
7414
7415static struct hda_input_mux alc882_capture_source = {
7416 .num_items = 4,
7417 .items = {
7418 { "Mic", 0x0 },
7419 { "Front Mic", 0x1 },
7420 { "Line", 0x2 },
7421 { "CD", 0x4 },
7422 },
7423};
41d5545d 7424
4953550a
TI
7425#define alc883_capture_source alc882_capture_source
7426
87a8c370
JK
7427static struct hda_input_mux alc889_capture_source = {
7428 .num_items = 3,
7429 .items = {
7430 { "Front Mic", 0x0 },
7431 { "Mic", 0x3 },
7432 { "Line", 0x2 },
7433 },
7434};
7435
41d5545d
KS
7436static struct hda_input_mux mb5_capture_source = {
7437 .num_items = 3,
7438 .items = {
7439 { "Mic", 0x1 },
b8f171e7 7440 { "Line", 0x7 },
41d5545d
KS
7441 { "CD", 0x4 },
7442 },
7443};
7444
e458b1fa
LY
7445static struct hda_input_mux macmini3_capture_source = {
7446 .num_items = 2,
7447 .items = {
7448 { "Line", 0x2 },
7449 { "CD", 0x4 },
7450 },
7451};
7452
4953550a
TI
7453static struct hda_input_mux alc883_3stack_6ch_intel = {
7454 .num_items = 4,
7455 .items = {
7456 { "Mic", 0x1 },
7457 { "Front Mic", 0x0 },
7458 { "Line", 0x2 },
7459 { "CD", 0x4 },
7460 },
7461};
7462
7463static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7464 .num_items = 2,
7465 .items = {
7466 { "Mic", 0x1 },
7467 { "Line", 0x2 },
7468 },
7469};
7470
7471static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7472 .num_items = 4,
7473 .items = {
7474 { "Mic", 0x0 },
28c4edb7 7475 { "Internal Mic", 0x1 },
4953550a
TI
7476 { "Line", 0x2 },
7477 { "CD", 0x4 },
7478 },
7479};
7480
7481static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7482 .num_items = 2,
7483 .items = {
7484 { "Mic", 0x0 },
28c4edb7 7485 { "Internal Mic", 0x1 },
4953550a
TI
7486 },
7487};
7488
7489static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7490 .num_items = 3,
7491 .items = {
7492 { "Mic", 0x0 },
7493 { "Front Mic", 0x1 },
7494 { "Line", 0x4 },
7495 },
7496};
7497
7498static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7499 .num_items = 2,
7500 .items = {
7501 { "Mic", 0x0 },
7502 { "Line", 0x2 },
7503 },
7504};
7505
7506static struct hda_input_mux alc889A_mb31_capture_source = {
7507 .num_items = 2,
7508 .items = {
7509 { "Mic", 0x0 },
7510 /* Front Mic (0x01) unused */
7511 { "Line", 0x2 },
7512 /* Line 2 (0x03) unused */
af901ca1 7513 /* CD (0x04) unused? */
4953550a
TI
7514 },
7515};
7516
b7cccc52
JM
7517static struct hda_input_mux alc889A_imac91_capture_source = {
7518 .num_items = 2,
7519 .items = {
7520 { "Mic", 0x01 },
7521 { "Line", 0x2 }, /* Not sure! */
7522 },
7523};
7524
4953550a
TI
7525/*
7526 * 2ch mode
7527 */
7528static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7529 { 2, NULL }
7530};
7531
272a527c
KY
7532/*
7533 * 2ch mode
7534 */
7535static struct hda_verb alc882_3ST_ch2_init[] = {
7536 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7537 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7538 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7539 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7540 { } /* end */
7541};
7542
4953550a
TI
7543/*
7544 * 4ch mode
7545 */
7546static struct hda_verb alc882_3ST_ch4_init[] = {
7547 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7548 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7549 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7550 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7551 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7552 { } /* end */
7553};
7554
272a527c
KY
7555/*
7556 * 6ch mode
7557 */
7558static struct hda_verb alc882_3ST_ch6_init[] = {
7559 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7560 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7561 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7562 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7563 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7564 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7565 { } /* end */
7566};
7567
4953550a 7568static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7569 { 2, alc882_3ST_ch2_init },
4953550a 7570 { 4, alc882_3ST_ch4_init },
272a527c
KY
7571 { 6, alc882_3ST_ch6_init },
7572};
7573
4953550a
TI
7574#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7575
a65cc60f 7576/*
7577 * 2ch mode
7578 */
7579static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7580 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7581 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7582 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7583 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7584 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7585 { } /* end */
7586};
7587
7588/*
7589 * 4ch mode
7590 */
7591static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7592 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7593 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7594 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7595 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7596 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7597 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7598 { } /* end */
7599};
7600
7601/*
7602 * 6ch mode
7603 */
7604static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7605 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7606 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7607 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7608 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7609 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7610 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7611 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7612 { } /* end */
7613};
7614
7615static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7616 { 2, alc883_3ST_ch2_clevo_init },
7617 { 4, alc883_3ST_ch4_clevo_init },
7618 { 6, alc883_3ST_ch6_clevo_init },
7619};
7620
7621
df694daa
KY
7622/*
7623 * 6ch mode
7624 */
7625static struct hda_verb alc882_sixstack_ch6_init[] = {
7626 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7627 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7628 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7629 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7630 { } /* end */
7631};
7632
7633/*
7634 * 8ch mode
7635 */
7636static struct hda_verb alc882_sixstack_ch8_init[] = {
7637 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7638 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7639 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7640 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7641 { } /* end */
7642};
7643
7644static struct hda_channel_mode alc882_sixstack_modes[2] = {
7645 { 6, alc882_sixstack_ch6_init },
7646 { 8, alc882_sixstack_ch8_init },
7647};
7648
76e6f5a9
RH
7649
7650/* Macbook Air 2,1 */
7651
7652static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7653 { 2, NULL },
7654};
7655
87350ad0 7656/*
def319f9 7657 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7658 */
7659
7660/*
7661 * 2ch mode
7662 */
7663static struct hda_verb alc885_mbp_ch2_init[] = {
7664 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7665 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7666 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7667 { } /* end */
7668};
7669
7670/*
a3f730af 7671 * 4ch mode
87350ad0 7672 */
a3f730af 7673static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7674 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7675 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7676 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7677 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7678 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7679 { } /* end */
7680};
7681
a3f730af 7682static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7683 { 2, alc885_mbp_ch2_init },
a3f730af 7684 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7685};
7686
92b9de83
KS
7687/*
7688 * 2ch
7689 * Speakers/Woofer/HP = Front
7690 * LineIn = Input
7691 */
7692static struct hda_verb alc885_mb5_ch2_init[] = {
7693 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7695 { } /* end */
7696};
7697
7698/*
7699 * 6ch mode
7700 * Speakers/HP = Front
7701 * Woofer = LFE
7702 * LineIn = Surround
7703 */
7704static struct hda_verb alc885_mb5_ch6_init[] = {
7705 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7706 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7707 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7708 { } /* end */
7709};
7710
7711static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7712 { 2, alc885_mb5_ch2_init },
7713 { 6, alc885_mb5_ch6_init },
7714};
87350ad0 7715
d01aecdf 7716#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7717
7718/*
7719 * 2ch mode
7720 */
7721static struct hda_verb alc883_4ST_ch2_init[] = {
7722 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7723 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7724 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7725 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7726 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7727 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7728 { } /* end */
7729};
7730
7731/*
7732 * 4ch mode
7733 */
7734static struct hda_verb alc883_4ST_ch4_init[] = {
7735 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7736 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7737 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7738 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7739 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7740 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7741 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7742 { } /* end */
7743};
7744
7745/*
7746 * 6ch mode
7747 */
7748static struct hda_verb alc883_4ST_ch6_init[] = {
7749 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7750 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7751 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7752 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7753 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7754 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7755 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7756 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7757 { } /* end */
7758};
7759
7760/*
7761 * 8ch mode
7762 */
7763static struct hda_verb alc883_4ST_ch8_init[] = {
7764 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7765 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7766 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7767 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7768 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7769 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7770 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7771 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7772 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7773 { } /* end */
7774};
7775
7776static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7777 { 2, alc883_4ST_ch2_init },
7778 { 4, alc883_4ST_ch4_init },
7779 { 6, alc883_4ST_ch6_init },
7780 { 8, alc883_4ST_ch8_init },
7781};
7782
7783
7784/*
7785 * 2ch mode
7786 */
7787static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7788 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7789 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7790 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7791 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7792 { } /* end */
7793};
7794
7795/*
7796 * 4ch mode
7797 */
7798static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7799 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7800 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7801 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7802 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7803 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7804 { } /* end */
7805};
7806
7807/*
7808 * 6ch mode
7809 */
7810static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7811 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7812 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7813 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7814 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7815 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7816 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7817 { } /* end */
7818};
7819
7820static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7821 { 2, alc883_3ST_ch2_intel_init },
7822 { 4, alc883_3ST_ch4_intel_init },
7823 { 6, alc883_3ST_ch6_intel_init },
7824};
7825
dd7714c9
WF
7826/*
7827 * 2ch mode
7828 */
7829static struct hda_verb alc889_ch2_intel_init[] = {
7830 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7831 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7832 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7833 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7834 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7835 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7836 { } /* end */
7837};
7838
87a8c370
JK
7839/*
7840 * 6ch mode
7841 */
7842static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7843 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7844 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7845 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7846 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7847 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7848 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7849 { } /* end */
7850};
7851
7852/*
7853 * 8ch mode
7854 */
7855static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7856 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7857 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7858 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7859 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7860 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7861 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7862 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7863 { } /* end */
7864};
7865
dd7714c9
WF
7866static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7867 { 2, alc889_ch2_intel_init },
87a8c370
JK
7868 { 6, alc889_ch6_intel_init },
7869 { 8, alc889_ch8_intel_init },
7870};
7871
4953550a
TI
7872/*
7873 * 6ch mode
7874 */
7875static struct hda_verb alc883_sixstack_ch6_init[] = {
7876 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7877 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7878 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7879 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7880 { } /* end */
7881};
7882
7883/*
7884 * 8ch mode
7885 */
7886static struct hda_verb alc883_sixstack_ch8_init[] = {
7887 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7888 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7889 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7890 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7891 { } /* end */
7892};
7893
7894static struct hda_channel_mode alc883_sixstack_modes[2] = {
7895 { 6, alc883_sixstack_ch6_init },
7896 { 8, alc883_sixstack_ch8_init },
7897};
7898
7899
1da177e4
LT
7900/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7901 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7902 */
c8b6bf9b 7903static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7904 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7905 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7906 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7907 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7908 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7909 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7910 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7911 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7912 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7913 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7914 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7915 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7916 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7917 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7918 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 7920 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
7921 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7922 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 7923 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 7924 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7925 { } /* end */
7926};
7927
76e6f5a9
RH
7928/* Macbook Air 2,1 same control for HP and internal Speaker */
7929
7930static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7931 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7932 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7933 { }
7934};
7935
7936
87350ad0 7937static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7938 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7939 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7940 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7941 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7942 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7943 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7944 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7945 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7946 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
7947 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7948 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
7949 { } /* end */
7950};
41d5545d
KS
7951
7952static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7953 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7954 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7955 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7956 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7957 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7958 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7959 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7960 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7961 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7962 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7963 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7964 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
7965 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7966 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
7967 { } /* end */
7968};
92b9de83 7969
e458b1fa
LY
7970static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7971 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7972 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7973 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7974 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7975 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7976 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7977 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7978 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7979 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7980 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 7981 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
7982 { } /* end */
7983};
7984
4b7e1803 7985static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7986 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7987 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7988 { } /* end */
7989};
7990
7991
bdd148a3
KY
7992static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7993 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7994 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7995 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7996 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7997 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7998 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7999 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8000 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8002 { } /* end */
8003};
8004
272a527c
KY
8005static struct snd_kcontrol_new alc882_targa_mixer[] = {
8006 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8007 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8008 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8009 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8010 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8011 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8012 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8013 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8014 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8015 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8016 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8017 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8018 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8019 { } /* end */
8020};
8021
8022/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8023 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8024 */
8025static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8026 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8027 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8028 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8029 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8030 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8031 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8032 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8033 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8034 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8035 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8037 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8038 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8039 { } /* end */
8040};
8041
914759b7
TI
8042static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8043 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8044 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8045 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8046 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8047 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8048 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8049 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8050 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8051 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8052 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8053 { } /* end */
8054};
8055
df694daa
KY
8056static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8057 {
8058 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8059 .name = "Channel Mode",
8060 .info = alc_ch_mode_info,
8061 .get = alc_ch_mode_get,
8062 .put = alc_ch_mode_put,
8063 },
8064 { } /* end */
8065};
8066
4953550a 8067static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8068 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8070 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8071 /* Rear mixer */
05acb863
TI
8072 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8073 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8074 /* CLFE mixer */
05acb863
TI
8075 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8076 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8077 /* Side mixer */
05acb863
TI
8078 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8079 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8080
e9edcee0 8081 /* Front Pin: output 0 (0x0c) */
05acb863 8082 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8083 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8084 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8085 /* Rear Pin: output 1 (0x0d) */
05acb863 8086 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8087 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8088 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8089 /* CLFE Pin: output 2 (0x0e) */
05acb863 8090 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8091 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8092 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8093 /* Side Pin: output 3 (0x0f) */
05acb863 8094 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8095 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8096 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8097 /* Mic (rear) pin: input vref at 80% */
16ded525 8098 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8099 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8100 /* Front Mic pin: input vref at 80% */
16ded525 8101 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8102 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8103 /* Line In pin: input */
05acb863 8104 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8105 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8106 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8107 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8108 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8109 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8110 /* CD pin widget for input */
05acb863 8111 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8112
8113 /* FIXME: use matrix-type input source selection */
8114 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8115 /* Input mixer2 */
05acb863 8116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8117 /* Input mixer3 */
05acb863 8118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8119 /* ADC2: mute amp left and right */
8120 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8121 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8122 /* ADC3: mute amp left and right */
8123 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8124 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8125
8126 { }
8127};
8128
4953550a
TI
8129static struct hda_verb alc882_adc1_init_verbs[] = {
8130 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8131 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8132 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8133 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8134 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8135 /* ADC1: mute amp left and right */
8136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8137 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8138 { }
8139};
8140
4b146cb0
TI
8141static struct hda_verb alc882_eapd_verbs[] = {
8142 /* change to EAPD mode */
8143 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8144 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8145 { }
4b146cb0
TI
8146};
8147
87a8c370
JK
8148static struct hda_verb alc889_eapd_verbs[] = {
8149 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8150 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8151 { }
8152};
8153
6732bd0d
WF
8154static struct hda_verb alc_hp15_unsol_verbs[] = {
8155 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8157 {}
8158};
87a8c370
JK
8159
8160static struct hda_verb alc885_init_verbs[] = {
8161 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8162 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8164 /* Rear mixer */
88102f3f
KY
8165 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8166 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8167 /* CLFE mixer */
88102f3f
KY
8168 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8169 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8170 /* Side mixer */
88102f3f
KY
8171 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8172 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8173
8174 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8175 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8176 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8177 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8178 /* Front Pin: output 0 (0x0c) */
8179 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8180 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8181 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8182 /* Rear Pin: output 1 (0x0d) */
8183 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8184 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8185 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8186 /* CLFE Pin: output 2 (0x0e) */
8187 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8188 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8189 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8190 /* Side Pin: output 3 (0x0f) */
8191 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8192 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8193 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8194 /* Mic (rear) pin: input vref at 80% */
8195 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8196 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8197 /* Front Mic pin: input vref at 80% */
8198 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8199 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8200 /* Line In pin: input */
8201 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8202 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8203
8204 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8205 /* Input mixer1 */
88102f3f 8206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8207 /* Input mixer2 */
8208 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8209 /* Input mixer3 */
88102f3f 8210 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8211 /* ADC2: mute amp left and right */
8212 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8213 /* ADC3: mute amp left and right */
8214 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8215
8216 { }
8217};
8218
8219static struct hda_verb alc885_init_input_verbs[] = {
8220 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8221 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8222 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8223 { }
8224};
8225
8226
8227/* Unmute Selector 24h and set the default input to front mic */
8228static struct hda_verb alc889_init_input_verbs[] = {
8229 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8230 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8231 { }
8232};
8233
8234
4953550a
TI
8235#define alc883_init_verbs alc882_base_init_verbs
8236
9102cd1c
TD
8237/* Mac Pro test */
8238static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8239 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8240 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8241 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8242 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8243 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8244 /* FIXME: this looks suspicious...
d355c82a
JK
8245 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8246 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8247 */
9102cd1c
TD
8248 { } /* end */
8249};
8250
8251static struct hda_verb alc882_macpro_init_verbs[] = {
8252 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8253 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8256 /* Front Pin: output 0 (0x0c) */
8257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8259 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8260 /* Front Mic pin: input vref at 80% */
8261 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8262 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8263 /* Speaker: output */
8264 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8265 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8266 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8267 /* Headphone output (output 0 - 0x0c) */
8268 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8269 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8270 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8271
8272 /* FIXME: use matrix-type input source selection */
8273 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8274 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8275 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8276 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8277 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8278 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8279 /* Input mixer2 */
8280 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8281 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8282 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8283 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8284 /* Input mixer3 */
8285 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8286 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8287 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8288 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8289 /* ADC1: mute amp left and right */
8290 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8291 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8292 /* ADC2: mute amp left and right */
8293 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8294 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8295 /* ADC3: mute amp left and right */
8296 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8297 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8298
8299 { }
8300};
f12ab1e0 8301
41d5545d
KS
8302/* Macbook 5,1 */
8303static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8304 /* DACs */
8305 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8306 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8307 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8308 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8309 /* Front mixer */
41d5545d
KS
8310 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8313 /* Surround mixer */
8314 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8316 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8317 /* LFE mixer */
8318 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8319 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8320 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8321 /* HP mixer */
8322 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8323 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8324 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8325 /* Front Pin (0x0c) */
41d5545d
KS
8326 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8327 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8328 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8329 /* LFE Pin (0x0e) */
8330 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8331 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8332 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8333 /* HP Pin (0x0f) */
41d5545d
KS
8334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8335 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8336 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8337 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8338 /* Front Mic pin: input vref at 80% */
8339 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8340 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8341 /* Line In pin */
8342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8343 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8344
b8f171e7
AM
8345 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8346 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8348 { }
8349};
8350
e458b1fa
LY
8351/* Macmini 3,1 */
8352static struct hda_verb alc885_macmini3_init_verbs[] = {
8353 /* DACs */
8354 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8355 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8356 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8357 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8358 /* Front mixer */
8359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8362 /* Surround mixer */
8363 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8365 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8366 /* LFE mixer */
8367 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8368 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8369 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8370 /* HP mixer */
8371 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8372 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8374 /* Front Pin (0x0c) */
8375 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8376 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8377 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8378 /* LFE Pin (0x0e) */
8379 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8380 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8381 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8382 /* HP Pin (0x0f) */
8383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8384 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8386 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8387 /* Line In pin */
8388 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8389 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8390
8391 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8392 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8393 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8394 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8395 { }
8396};
8397
76e6f5a9
RH
8398
8399static struct hda_verb alc885_mba21_init_verbs[] = {
8400 /*Internal and HP Speaker Mixer*/
8401 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8404 /*Internal Speaker Pin (0x0c)*/
8405 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8406 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8407 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8408 /* HP Pin: output 0 (0x0e) */
8409 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8410 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8411 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8412 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8413 /* Line in (is hp when jack connected)*/
8414 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8415 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8416
8417 { }
8418 };
8419
8420
87350ad0
TI
8421/* Macbook Pro rev3 */
8422static struct hda_verb alc885_mbp3_init_verbs[] = {
8423 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8424 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8427 /* Rear mixer */
8428 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8429 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8431 /* HP mixer */
8432 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8433 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8434 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8435 /* Front Pin: output 0 (0x0c) */
8436 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8437 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8438 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8439 /* HP Pin: output 0 (0x0e) */
87350ad0 8440 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8441 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8442 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8444 /* Mic (rear) pin: input vref at 80% */
8445 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8446 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8447 /* Front Mic pin: input vref at 80% */
8448 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8449 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8450 /* Line In pin: use output 1 when in LineOut mode */
8451 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8452 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8453 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8454
8455 /* FIXME: use matrix-type input source selection */
8456 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8457 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8458 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8459 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8461 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8462 /* Input mixer2 */
8463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8467 /* Input mixer3 */
8468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8472 /* ADC1: mute amp left and right */
8473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8474 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8475 /* ADC2: mute amp left and right */
8476 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8477 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8478 /* ADC3: mute amp left and right */
8479 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8480 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8481
8482 { }
8483};
8484
4b7e1803
JM
8485/* iMac 9,1 */
8486static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8487 /* Internal Speaker Pin (0x0c) */
8488 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8489 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8490 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8491 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8492 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8493 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8494 /* HP Pin: Rear */
4b7e1803
JM
8495 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8496 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8497 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8498 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8499 /* Line in Rear */
8500 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8502 /* Front Mic pin: input vref at 80% */
8503 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8504 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8505 /* Rear mixer */
8506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8508 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8509 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8513 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8514 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8515 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8518 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8519 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8523 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8528 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8530 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8531 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8532 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8533 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8534 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8536 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8537 { }
8538};
8539
c54728d8
NF
8540/* iMac 24 mixer. */
8541static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8542 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8543 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8544 { } /* end */
8545};
8546
8547/* iMac 24 init verbs. */
8548static struct hda_verb alc885_imac24_init_verbs[] = {
8549 /* Internal speakers: output 0 (0x0c) */
8550 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8551 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8552 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8553 /* Internal speakers: output 0 (0x0c) */
8554 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8555 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8556 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8557 /* Headphone: output 0 (0x0c) */
8558 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8559 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8561 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8562 /* Front Mic: input vref at 80% */
8563 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8564 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8565 { }
8566};
8567
8568/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8569static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8570{
a9fd4f3f 8571 struct alc_spec *spec = codec->spec;
c54728d8 8572
a9fd4f3f
TI
8573 spec->autocfg.hp_pins[0] = 0x14;
8574 spec->autocfg.speaker_pins[0] = 0x18;
8575 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8576}
8577
9d54f08b
TI
8578#define alc885_mb5_setup alc885_imac24_setup
8579#define alc885_macmini3_setup alc885_imac24_setup
8580
76e6f5a9
RH
8581/* Macbook Air 2,1 */
8582static void alc885_mba21_setup(struct hda_codec *codec)
8583{
8584 struct alc_spec *spec = codec->spec;
8585
8586 spec->autocfg.hp_pins[0] = 0x14;
8587 spec->autocfg.speaker_pins[0] = 0x18;
8588}
8589
8590
8591
4f5d1706 8592static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8593{
a9fd4f3f 8594 struct alc_spec *spec = codec->spec;
87350ad0 8595
a9fd4f3f
TI
8596 spec->autocfg.hp_pins[0] = 0x15;
8597 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8598}
8599
9d54f08b 8600static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8601{
9d54f08b 8602 struct alc_spec *spec = codec->spec;
4b7e1803 8603
9d54f08b 8604 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8605 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8606 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8607}
87350ad0 8608
272a527c
KY
8609static struct hda_verb alc882_targa_verbs[] = {
8610 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8612
8613 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8614 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8615
272a527c
KY
8616 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8617 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8618 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8619
8620 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8621 { } /* end */
8622};
8623
8624/* toggle speaker-output according to the hp-jack state */
8625static void alc882_targa_automute(struct hda_codec *codec)
8626{
a9fd4f3f
TI
8627 struct alc_spec *spec = codec->spec;
8628 alc_automute_amp(codec);
82beb8fd 8629 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8630 spec->jack_present ? 1 : 3);
8631}
8632
4f5d1706 8633static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8634{
8635 struct alc_spec *spec = codec->spec;
8636
8637 spec->autocfg.hp_pins[0] = 0x14;
8638 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8639}
8640
8641static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8642{
a9fd4f3f 8643 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8644 alc882_targa_automute(codec);
272a527c
KY
8645}
8646
8647static struct hda_verb alc882_asus_a7j_verbs[] = {
8648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8650
8651 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8653 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8654
272a527c
KY
8655 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8657 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8658
8659 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8660 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8661 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8662 { } /* end */
8663};
8664
914759b7
TI
8665static struct hda_verb alc882_asus_a7m_verbs[] = {
8666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8668
8669 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8671 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8672
914759b7
TI
8673 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8674 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8675 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8676
8677 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8678 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8679 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8680 { } /* end */
8681};
8682
9102cd1c
TD
8683static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8684{
8685 unsigned int gpiostate, gpiomask, gpiodir;
8686
8687 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8688 AC_VERB_GET_GPIO_DATA, 0);
8689
8690 if (!muted)
8691 gpiostate |= (1 << pin);
8692 else
8693 gpiostate &= ~(1 << pin);
8694
8695 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8696 AC_VERB_GET_GPIO_MASK, 0);
8697 gpiomask |= (1 << pin);
8698
8699 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8700 AC_VERB_GET_GPIO_DIRECTION, 0);
8701 gpiodir |= (1 << pin);
8702
8703
8704 snd_hda_codec_write(codec, codec->afg, 0,
8705 AC_VERB_SET_GPIO_MASK, gpiomask);
8706 snd_hda_codec_write(codec, codec->afg, 0,
8707 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8708
8709 msleep(1);
8710
8711 snd_hda_codec_write(codec, codec->afg, 0,
8712 AC_VERB_SET_GPIO_DATA, gpiostate);
8713}
8714
7debbe51
TI
8715/* set up GPIO at initialization */
8716static void alc885_macpro_init_hook(struct hda_codec *codec)
8717{
8718 alc882_gpio_mute(codec, 0, 0);
8719 alc882_gpio_mute(codec, 1, 0);
8720}
8721
8722/* set up GPIO and update auto-muting at initialization */
8723static void alc885_imac24_init_hook(struct hda_codec *codec)
8724{
8725 alc885_macpro_init_hook(codec);
4f5d1706 8726 alc_automute_amp(codec);
7debbe51
TI
8727}
8728
df694daa
KY
8729/*
8730 * generic initialization of ADC, input mixers and output mixers
8731 */
4953550a 8732static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8733 /*
8734 * Unmute ADC0-2 and set the default input to mic-in
8735 */
4953550a
TI
8736 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8738 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8739 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8740
4953550a
TI
8741 /*
8742 * Set up output mixers (0x0c - 0x0f)
8743 */
8744 /* set vol=0 to output mixers */
8745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8746 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8747 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8748 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8749 /* set up input amps for analog loopback */
8750 /* Amp Indices: DAC = 0, mixer = 1 */
8751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8753 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8754 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8755 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8756 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8757 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8758 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8759 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8760 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8761
4953550a
TI
8762 /* FIXME: use matrix-type input source selection */
8763 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8764 /* Input mixer2 */
88102f3f 8765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8766 /* Input mixer3 */
88102f3f 8767 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8768 { }
9c7f852e
TI
8769};
8770
eb4c41d3
TS
8771/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8772static struct hda_verb alc889A_mb31_ch2_init[] = {
8773 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8774 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8775 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8776 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8777 { } /* end */
8778};
8779
8780/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8781static struct hda_verb alc889A_mb31_ch4_init[] = {
8782 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8783 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8784 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8785 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8786 { } /* end */
8787};
8788
8789/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8790static struct hda_verb alc889A_mb31_ch5_init[] = {
8791 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8792 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8793 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8794 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8795 { } /* end */
8796};
8797
8798/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8799static struct hda_verb alc889A_mb31_ch6_init[] = {
8800 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8801 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8802 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8803 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8804 { } /* end */
8805};
8806
8807static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8808 { 2, alc889A_mb31_ch2_init },
8809 { 4, alc889A_mb31_ch4_init },
8810 { 5, alc889A_mb31_ch5_init },
8811 { 6, alc889A_mb31_ch6_init },
8812};
8813
b373bdeb
AN
8814static struct hda_verb alc883_medion_eapd_verbs[] = {
8815 /* eanable EAPD on medion laptop */
8816 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8817 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8818 { }
8819};
8820
4953550a 8821#define alc883_base_mixer alc882_base_mixer
834be88d 8822
a8848bd6
AS
8823static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8824 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8825 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8826 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8827 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8828 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8829 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8830 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8831 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8832 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8834 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8835 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8836 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8837 { } /* end */
8838};
8839
0c4cc443 8840static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8841 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8842 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8843 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8844 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8845 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8846 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8847 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8848 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8849 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8850 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8851 { } /* end */
8852};
8853
fb97dc67
J
8854static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8855 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8856 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8857 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8858 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8860 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8861 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8862 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8863 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8864 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8865 { } /* end */
8866};
8867
9c7f852e
TI
8868static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8869 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8870 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8871 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8872 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8873 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8874 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8875 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8876 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8877 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8878 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8879 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8880 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8881 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8882 { } /* end */
8883};
df694daa 8884
9c7f852e
TI
8885static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8886 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8887 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8888 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8889 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8890 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8891 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8892 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8893 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8894 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8895 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8896 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8897 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8898 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8899 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8900 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8901 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8902 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8903 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8904 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8905 { } /* end */
8906};
8907
17bba1b7
J
8908static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8909 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8910 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8911 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8912 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8913 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8914 HDA_OUTPUT),
8915 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8916 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8917 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8918 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8919 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8920 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8921 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8922 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8923 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8924 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
8925 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8926 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8927 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 8928 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8929 { } /* end */
8930};
8931
87a8c370
JK
8932static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8933 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8934 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8935 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8936 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8937 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8938 HDA_OUTPUT),
8939 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8940 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8941 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8942 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8943 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8944 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8945 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8946 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8947 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 8948 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
8949 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8950 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8951 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
8952 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8953 { } /* end */
8954};
8955
d1d985f0 8956static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8957 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8958 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8959 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8960 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8961 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8962 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8963 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8964 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8965 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8966 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8967 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8968 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8969 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8970 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8971 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
8972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8973 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8974 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 8975 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8976 { } /* end */
8977};
8978
c259249f 8979static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8980 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8981 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8982 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8983 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8985 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8986 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8987 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8988 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8989 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8990 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8991 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8992 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8993 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8995 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 8996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8997 { } /* end */
f12ab1e0 8998};
ccc656ce 8999
c259249f 9000static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9001 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9002 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9004 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9005 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9006 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9007 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9008 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9009 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9010 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9011 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9012 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9013 { } /* end */
f12ab1e0 9014};
ccc656ce 9015
b99dba34
TI
9016static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9017 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9018 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9019 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9020 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9021 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9022 { } /* end */
9023};
9024
bc9f98a9
KY
9025static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9026 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9027 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9028 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9029 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9030 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9031 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9032 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9033 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9034 { } /* end */
f12ab1e0 9035};
bc9f98a9 9036
272a527c
KY
9037static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9038 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9039 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9040 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9041 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9042 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9045 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9046 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
9047 { } /* end */
9048};
9049
7ad7b218
MC
9050static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9051 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9052 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9053 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9054 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9055 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9056 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9057 { } /* end */
9058};
9059
9060static struct hda_verb alc883_medion_wim2160_verbs[] = {
9061 /* Unmute front mixer */
9062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9063 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9064
9065 /* Set speaker pin to front mixer */
9066 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9067
9068 /* Init headphone pin */
9069 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9070 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9071 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9072 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9073
9074 { } /* end */
9075};
9076
9077/* toggle speaker-output according to the hp-jack state */
9078static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9079{
9080 struct alc_spec *spec = codec->spec;
9081
9082 spec->autocfg.hp_pins[0] = 0x1a;
9083 spec->autocfg.speaker_pins[0] = 0x15;
9084}
9085
2880a867 9086static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9087 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9088 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9089 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9090 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9091 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9092 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9093 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9094 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9095 { } /* end */
d1a991a6 9096};
2880a867 9097
d2fd4b09
TV
9098static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9099 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9100 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9103 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9104 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9106 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9107 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9108 { } /* end */
9109};
9110
e2757d5e
KY
9111static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9113 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9114 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9115 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9116 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9117 0x0d, 1, 0x0, HDA_OUTPUT),
9118 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9119 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9120 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9121 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9122 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9123 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9124 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9128 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9129 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9130 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9131 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9132 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9133 { } /* end */
9134};
9135
eb4c41d3
TS
9136static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9137 /* Output mixers */
9138 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9139 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9140 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9141 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9142 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9143 HDA_OUTPUT),
9144 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9145 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9146 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9147 /* Output switches */
9148 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9149 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9150 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9151 /* Boost mixers */
5f99f86a
DH
9152 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9153 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9154 /* Input mixers */
9155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9156 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9157 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9158 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9159 { } /* end */
9160};
9161
3e1647c5
GG
9162static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9163 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9164 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9165 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9167 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9169 { } /* end */
9170};
9171
e2757d5e
KY
9172static struct hda_bind_ctls alc883_bind_cap_vol = {
9173 .ops = &snd_hda_bind_vol,
9174 .values = {
9175 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9176 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9177 0
9178 },
9179};
9180
9181static struct hda_bind_ctls alc883_bind_cap_switch = {
9182 .ops = &snd_hda_bind_sw,
9183 .values = {
9184 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9185 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9186 0
9187 },
9188};
9189
9190static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9191 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9192 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9194 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9195 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9196 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9197 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9198 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9199 { } /* end */
9200};
df694daa 9201
4953550a
TI
9202static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9203 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9204 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9205 {
9206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9207 /* .name = "Capture Source", */
9208 .name = "Input Source",
9209 .count = 1,
9210 .info = alc_mux_enum_info,
9211 .get = alc_mux_enum_get,
9212 .put = alc_mux_enum_put,
9213 },
9214 { } /* end */
9215};
9c7f852e 9216
4953550a
TI
9217static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9218 {
9219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9220 .name = "Channel Mode",
9221 .info = alc_ch_mode_info,
9222 .get = alc_ch_mode_get,
9223 .put = alc_ch_mode_put,
9224 },
9225 { } /* end */
9c7f852e
TI
9226};
9227
a8848bd6 9228/* toggle speaker-output according to the hp-jack state */
4f5d1706 9229static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9230{
a9fd4f3f 9231 struct alc_spec *spec = codec->spec;
a8848bd6 9232
a9fd4f3f
TI
9233 spec->autocfg.hp_pins[0] = 0x15;
9234 spec->autocfg.speaker_pins[0] = 0x14;
9235 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9236}
9237
a8848bd6
AS
9238static struct hda_verb alc883_mitac_verbs[] = {
9239 /* HP */
9240 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9241 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9242 /* Subwoofer */
9243 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9244 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9245
9246 /* enable unsolicited event */
9247 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9248 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9249
9250 { } /* end */
9251};
9252
a65cc60f 9253static struct hda_verb alc883_clevo_m540r_verbs[] = {
9254 /* HP */
9255 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9256 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9257 /* Int speaker */
9258 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9259
9260 /* enable unsolicited event */
9261 /*
9262 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9263 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9264 */
9265
9266 { } /* end */
9267};
9268
0c4cc443 9269static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9270 /* HP */
9271 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9272 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9273 /* Int speaker */
9274 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9275 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9276
9277 /* enable unsolicited event */
9278 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9279 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9280
9281 { } /* end */
9282};
9283
fb97dc67
J
9284static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9285 /* HP */
9286 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9288 /* Subwoofer */
9289 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9291
9292 /* enable unsolicited event */
9293 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9294
9295 { } /* end */
9296};
9297
c259249f 9298static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9299 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9301
9302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9303 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9304
64a8be74
DH
9305/* Connect Line-Out side jack (SPDIF) to Side */
9306 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9307 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9308 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9309/* Connect Mic jack to CLFE */
9310 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9311 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9312 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9313/* Connect Line-in jack to Surround */
9314 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9315 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9316 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9317/* Connect HP out jack to Front */
9318 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9319 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9320 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9321
9322 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9323
9324 { } /* end */
9325};
9326
bc9f98a9
KY
9327static struct hda_verb alc883_lenovo_101e_verbs[] = {
9328 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9329 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9330 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9331 { } /* end */
9332};
9333
272a527c
KY
9334static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9335 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9336 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9337 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9339 { } /* end */
9340};
9341
9342static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9343 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9344 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9346 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9347 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9348 { } /* end */
9349};
9350
189609ae
KY
9351static struct hda_verb alc883_haier_w66_verbs[] = {
9352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9354
9355 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9356
9357 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9358 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9359 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9360 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9361 { } /* end */
9362};
9363
e2757d5e
KY
9364static struct hda_verb alc888_lenovo_sky_verbs[] = {
9365 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9367 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9368 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9369 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9370 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9371 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9372 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9373 { } /* end */
9374};
9375
8718b700
HRK
9376static struct hda_verb alc888_6st_dell_verbs[] = {
9377 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9378 { }
9379};
9380
3e1647c5
GG
9381static struct hda_verb alc883_vaiott_verbs[] = {
9382 /* HP */
9383 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9384 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9385
9386 /* enable unsolicited event */
9387 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9388
9389 { } /* end */
9390};
9391
4f5d1706 9392static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9393{
a9fd4f3f 9394 struct alc_spec *spec = codec->spec;
8718b700 9395
a9fd4f3f
TI
9396 spec->autocfg.hp_pins[0] = 0x1b;
9397 spec->autocfg.speaker_pins[0] = 0x14;
9398 spec->autocfg.speaker_pins[1] = 0x16;
9399 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9400}
9401
4723c022 9402static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9403 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9404 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9405 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9406 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9407 { } /* end */
5795b9e6
CM
9408};
9409
3ea0d7cf
HRK
9410/*
9411 * 2ch mode
9412 */
4723c022 9413static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9414 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9415 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9416 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9417 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9418 { } /* end */
8341de60
CM
9419};
9420
3ea0d7cf
HRK
9421/*
9422 * 4ch mode
9423 */
9424static struct hda_verb alc888_3st_hp_4ch_init[] = {
9425 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9426 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9427 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9428 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9429 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9430 { } /* end */
9431};
9432
9433/*
9434 * 6ch mode
9435 */
4723c022 9436static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9437 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9438 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9439 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9440 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9441 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9442 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9443 { } /* end */
8341de60
CM
9444};
9445
3ea0d7cf 9446static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9447 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9448 { 4, alc888_3st_hp_4ch_init },
4723c022 9449 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9450};
9451
272a527c
KY
9452/* toggle front-jack and RCA according to the hp-jack state */
9453static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9454{
864f92be 9455 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9456
47fd830a
TI
9457 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9458 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9459 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9460 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9461}
9462
9463/* toggle RCA according to the front-jack state */
9464static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9465{
864f92be 9466 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9467
47fd830a
TI
9468 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9469 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9470}
47fd830a 9471
272a527c
KY
9472static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9473 unsigned int res)
9474{
9475 if ((res >> 26) == ALC880_HP_EVENT)
9476 alc888_lenovo_ms7195_front_automute(codec);
9477 if ((res >> 26) == ALC880_FRONT_EVENT)
9478 alc888_lenovo_ms7195_rca_automute(codec);
9479}
9480
272a527c 9481/* toggle speaker-output according to the hp-jack state */
dc427170 9482static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9483{
a9fd4f3f 9484 struct alc_spec *spec = codec->spec;
272a527c 9485
a9fd4f3f
TI
9486 spec->autocfg.hp_pins[0] = 0x14;
9487 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9488}
9489
ccc656ce 9490/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9491#define alc883_targa_init_hook alc882_targa_init_hook
9492#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9493
4f5d1706 9494static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9495{
a9fd4f3f
TI
9496 struct alc_spec *spec = codec->spec;
9497
9498 spec->autocfg.hp_pins[0] = 0x15;
9499 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9500}
9501
9502static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9503{
a9fd4f3f 9504 alc_automute_amp(codec);
eeb43387 9505 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9506}
9507
9508static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9509 unsigned int res)
9510{
0c4cc443 9511 switch (res >> 26) {
0c4cc443 9512 case ALC880_MIC_EVENT:
eeb43387 9513 alc88x_simple_mic_automute(codec);
0c4cc443 9514 break;
a9fd4f3f
TI
9515 default:
9516 alc_automute_amp_unsol_event(codec, res);
9517 break;
0c4cc443 9518 }
368c7a95
J
9519}
9520
fb97dc67 9521/* toggle speaker-output according to the hp-jack state */
4f5d1706 9522static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9523{
a9fd4f3f 9524 struct alc_spec *spec = codec->spec;
fb97dc67 9525
a9fd4f3f
TI
9526 spec->autocfg.hp_pins[0] = 0x14;
9527 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9528}
9529
4f5d1706 9530static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9531{
a9fd4f3f 9532 struct alc_spec *spec = codec->spec;
189609ae 9533
a9fd4f3f
TI
9534 spec->autocfg.hp_pins[0] = 0x1b;
9535 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9536}
9537
bc9f98a9
KY
9538static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9539{
864f92be 9540 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9541
47fd830a
TI
9542 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9543 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9544}
9545
9546static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9547{
864f92be 9548 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9549
47fd830a
TI
9550 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9551 HDA_AMP_MUTE, bits);
9552 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9553 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9554}
9555
9556static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9557 unsigned int res)
9558{
9559 if ((res >> 26) == ALC880_HP_EVENT)
9560 alc883_lenovo_101e_all_automute(codec);
9561 if ((res >> 26) == ALC880_FRONT_EVENT)
9562 alc883_lenovo_101e_ispeaker_automute(codec);
9563}
9564
676a9b53 9565/* toggle speaker-output according to the hp-jack state */
4f5d1706 9566static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9567{
a9fd4f3f 9568 struct alc_spec *spec = codec->spec;
676a9b53 9569
a9fd4f3f
TI
9570 spec->autocfg.hp_pins[0] = 0x14;
9571 spec->autocfg.speaker_pins[0] = 0x15;
9572 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9573}
9574
d1a991a6
KY
9575static struct hda_verb alc883_acer_eapd_verbs[] = {
9576 /* HP Pin: output 0 (0x0c) */
9577 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9578 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9579 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9580 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9581 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9582 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9583 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9584 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9585 /* eanable EAPD on medion laptop */
9586 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9587 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9588 /* enable unsolicited event */
9589 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9590 { }
9591};
9592
4f5d1706 9593static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9594{
a9fd4f3f 9595 struct alc_spec *spec = codec->spec;
5795b9e6 9596
a9fd4f3f
TI
9597 spec->autocfg.hp_pins[0] = 0x1b;
9598 spec->autocfg.speaker_pins[0] = 0x14;
9599 spec->autocfg.speaker_pins[1] = 0x15;
9600 spec->autocfg.speaker_pins[2] = 0x16;
9601 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9602}
9603
4f5d1706 9604static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9605{
a9fd4f3f 9606 struct alc_spec *spec = codec->spec;
e2757d5e 9607
a9fd4f3f
TI
9608 spec->autocfg.hp_pins[0] = 0x1b;
9609 spec->autocfg.speaker_pins[0] = 0x14;
9610 spec->autocfg.speaker_pins[1] = 0x15;
9611 spec->autocfg.speaker_pins[2] = 0x16;
9612 spec->autocfg.speaker_pins[3] = 0x17;
9613 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9614}
9615
4f5d1706 9616static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9617{
9618 struct alc_spec *spec = codec->spec;
9619
9620 spec->autocfg.hp_pins[0] = 0x15;
9621 spec->autocfg.speaker_pins[0] = 0x14;
9622 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9623}
9624
e2757d5e
KY
9625static struct hda_verb alc888_asus_m90v_verbs[] = {
9626 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9627 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9628 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9629 /* enable unsolicited event */
9630 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9631 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9632 { } /* end */
9633};
9634
4f5d1706 9635static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9636{
a9fd4f3f 9637 struct alc_spec *spec = codec->spec;
e2757d5e 9638
a9fd4f3f
TI
9639 spec->autocfg.hp_pins[0] = 0x1b;
9640 spec->autocfg.speaker_pins[0] = 0x14;
9641 spec->autocfg.speaker_pins[1] = 0x15;
9642 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9643 spec->ext_mic.pin = 0x18;
9644 spec->int_mic.pin = 0x19;
9645 spec->ext_mic.mux_idx = 0;
9646 spec->int_mic.mux_idx = 1;
9647 spec->auto_mic = 1;
e2757d5e
KY
9648}
9649
9650static struct hda_verb alc888_asus_eee1601_verbs[] = {
9651 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9652 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9653 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9656 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9657 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9658 /* enable unsolicited event */
9659 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9660 { } /* end */
9661};
9662
e2757d5e
KY
9663static void alc883_eee1601_inithook(struct hda_codec *codec)
9664{
a9fd4f3f
TI
9665 struct alc_spec *spec = codec->spec;
9666
9667 spec->autocfg.hp_pins[0] = 0x14;
9668 spec->autocfg.speaker_pins[0] = 0x1b;
9669 alc_automute_pin(codec);
e2757d5e
KY
9670}
9671
eb4c41d3
TS
9672static struct hda_verb alc889A_mb31_verbs[] = {
9673 /* Init rear pin (used as headphone output) */
9674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9675 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9676 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9677 /* Init line pin (used as output in 4ch and 6ch mode) */
9678 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9679 /* Init line 2 pin (used as headphone out by default) */
9680 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9681 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9682 { } /* end */
9683};
9684
9685/* Mute speakers according to the headphone jack state */
9686static void alc889A_mb31_automute(struct hda_codec *codec)
9687{
9688 unsigned int present;
9689
9690 /* Mute only in 2ch or 4ch mode */
9691 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9692 == 0x00) {
864f92be 9693 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9694 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9695 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9696 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9697 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9698 }
9699}
9700
9701static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9702{
9703 if ((res >> 26) == ALC880_HP_EVENT)
9704 alc889A_mb31_automute(codec);
9705}
9706
4953550a 9707
cb53c626 9708#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9709#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9710#endif
9711
def319f9 9712/* pcm configuration: identical with ALC880 */
4953550a
TI
9713#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9714#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9715#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9716#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9717
9718static hda_nid_t alc883_slave_dig_outs[] = {
9719 ALC1200_DIGOUT_NID, 0,
9720};
9721
9722static hda_nid_t alc1200_slave_dig_outs[] = {
9723 ALC883_DIGOUT_NID, 0,
9724};
9c7f852e
TI
9725
9726/*
9727 * configuration and preset
9728 */
4953550a
TI
9729static const char *alc882_models[ALC882_MODEL_LAST] = {
9730 [ALC882_3ST_DIG] = "3stack-dig",
9731 [ALC882_6ST_DIG] = "6stack-dig",
9732 [ALC882_ARIMA] = "arima",
9733 [ALC882_W2JC] = "w2jc",
9734 [ALC882_TARGA] = "targa",
9735 [ALC882_ASUS_A7J] = "asus-a7j",
9736 [ALC882_ASUS_A7M] = "asus-a7m",
9737 [ALC885_MACPRO] = "macpro",
9738 [ALC885_MB5] = "mb5",
e458b1fa 9739 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9740 [ALC885_MBA21] = "mba21",
4953550a
TI
9741 [ALC885_MBP3] = "mbp3",
9742 [ALC885_IMAC24] = "imac24",
4b7e1803 9743 [ALC885_IMAC91] = "imac91",
4953550a 9744 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9745 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9746 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9747 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9748 [ALC883_TARGA_DIG] = "targa-dig",
9749 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9750 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9751 [ALC883_ACER] = "acer",
2880a867 9752 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9753 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9754 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9755 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9756 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9757 [ALC883_MEDION] = "medion",
7ad7b218 9758 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9759 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9760 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9761 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9762 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9763 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9764 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9765 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9766 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9767 [ALC883_MITAC] = "mitac",
a65cc60f 9768 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9769 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9770 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9771 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9772 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9773 [ALC889A_INTEL] = "intel-alc889a",
9774 [ALC889_INTEL] = "intel-x58",
3ab90935 9775 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9776 [ALC889A_MB31] = "mb31",
3e1647c5 9777 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9778 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9779};
9780
4953550a
TI
9781static struct snd_pci_quirk alc882_cfg_tbl[] = {
9782 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9783
ac3e3741 9784 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9785 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9786 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9787 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9788 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9789 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9790 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9791 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9792 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9793 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9794 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9795 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9796 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9797 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9798 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9799 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9800 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9801 ALC888_ACER_ASPIRE_6530G),
cc374c47 9802 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9803 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9804 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9805 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9806 /* default Acer -- disabled as it causes more problems.
9807 * model=auto should work fine now
9808 */
9809 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9810
5795b9e6 9811 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9812
febe3375 9813 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9814 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9815 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9816 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9817 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9818 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9819
9820 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9821 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9822 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9823 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9824 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9825 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9826 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9827 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9828 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9829 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9830 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9831
9832 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9833 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9834 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9835 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9836 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9837 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9838 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9839 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9840 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9841
6f3bf657 9842 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9843 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9844 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9845 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9846 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9847 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9848 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9849 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9850 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9851 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9852 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9853 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9854 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9855 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9856 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9857 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9858 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9859 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9860 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9861 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9862 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9863 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9864 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9865 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9866 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9867 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9868 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9869 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9870 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9871 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9872 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9873
ac3e3741 9874 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9875 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9876 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9877 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9878 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9879 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9880 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9881 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9882 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9883 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9884 ALC883_FUJITSU_PI2515),
bfb53037 9885 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9886 ALC888_FUJITSU_XA3530),
272a527c 9887 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9888 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9889 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9890 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9891 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9892 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9893 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9894 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9895
17bba1b7
J
9896 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9897 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9898 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9899 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9900 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9901 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9902 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9903
4953550a 9904 {}
f3cd3f5d
WF
9905};
9906
4953550a
TI
9907/* codec SSID table for Intel Mac */
9908static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9909 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9910 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9911 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9912 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9913 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9914 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9915 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9916 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9917 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9918 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9919 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9920 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9921 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9922 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9923 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9924 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9925 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9926 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9927 * so apparently no perfect solution yet
4953550a
TI
9928 */
9929 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9930 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9931 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9932 {} /* terminator */
b25c9da1
WF
9933};
9934
4953550a
TI
9935static struct alc_config_preset alc882_presets[] = {
9936 [ALC882_3ST_DIG] = {
9937 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9938 .init_verbs = { alc882_base_init_verbs,
9939 alc882_adc1_init_verbs },
4953550a
TI
9940 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9941 .dac_nids = alc882_dac_nids,
9942 .dig_out_nid = ALC882_DIGOUT_NID,
9943 .dig_in_nid = ALC882_DIGIN_NID,
9944 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9945 .channel_mode = alc882_ch_modes,
9946 .need_dac_fix = 1,
9947 .input_mux = &alc882_capture_source,
9948 },
9949 [ALC882_6ST_DIG] = {
9950 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9951 .init_verbs = { alc882_base_init_verbs,
9952 alc882_adc1_init_verbs },
4953550a
TI
9953 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9954 .dac_nids = alc882_dac_nids,
9955 .dig_out_nid = ALC882_DIGOUT_NID,
9956 .dig_in_nid = ALC882_DIGIN_NID,
9957 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9958 .channel_mode = alc882_sixstack_modes,
9959 .input_mux = &alc882_capture_source,
9960 },
9961 [ALC882_ARIMA] = {
9962 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9963 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9964 alc882_eapd_verbs },
4953550a
TI
9965 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9966 .dac_nids = alc882_dac_nids,
9967 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9968 .channel_mode = alc882_sixstack_modes,
9969 .input_mux = &alc882_capture_source,
9970 },
9971 [ALC882_W2JC] = {
9972 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9973 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9974 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9975 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9976 .dac_nids = alc882_dac_nids,
9977 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9978 .channel_mode = alc880_threestack_modes,
9979 .need_dac_fix = 1,
9980 .input_mux = &alc882_capture_source,
9981 .dig_out_nid = ALC882_DIGOUT_NID,
9982 },
76e6f5a9
RH
9983 [ALC885_MBA21] = {
9984 .mixers = { alc885_mba21_mixer },
9985 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9986 .num_dacs = 2,
9987 .dac_nids = alc882_dac_nids,
9988 .channel_mode = alc885_mba21_ch_modes,
9989 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9990 .input_mux = &alc882_capture_source,
9991 .unsol_event = alc_automute_amp_unsol_event,
9992 .setup = alc885_mba21_setup,
9993 .init_hook = alc_automute_amp,
9994 },
4953550a
TI
9995 [ALC885_MBP3] = {
9996 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9997 .init_verbs = { alc885_mbp3_init_verbs,
9998 alc880_gpio1_init_verbs },
be0ae923 9999 .num_dacs = 2,
4953550a 10000 .dac_nids = alc882_dac_nids,
be0ae923
TI
10001 .hp_nid = 0x04,
10002 .channel_mode = alc885_mbp_4ch_modes,
10003 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10004 .input_mux = &alc882_capture_source,
10005 .dig_out_nid = ALC882_DIGOUT_NID,
10006 .dig_in_nid = ALC882_DIGIN_NID,
10007 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10008 .setup = alc885_mbp3_setup,
10009 .init_hook = alc_automute_amp,
4953550a
TI
10010 },
10011 [ALC885_MB5] = {
10012 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10013 .init_verbs = { alc885_mb5_init_verbs,
10014 alc880_gpio1_init_verbs },
10015 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10016 .dac_nids = alc882_dac_nids,
10017 .channel_mode = alc885_mb5_6ch_modes,
10018 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10019 .input_mux = &mb5_capture_source,
10020 .dig_out_nid = ALC882_DIGOUT_NID,
10021 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10022 .unsol_event = alc_automute_amp_unsol_event,
10023 .setup = alc885_mb5_setup,
10024 .init_hook = alc_automute_amp,
4953550a 10025 },
e458b1fa
LY
10026 [ALC885_MACMINI3] = {
10027 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10028 .init_verbs = { alc885_macmini3_init_verbs,
10029 alc880_gpio1_init_verbs },
10030 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10031 .dac_nids = alc882_dac_nids,
10032 .channel_mode = alc885_macmini3_6ch_modes,
10033 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10034 .input_mux = &macmini3_capture_source,
10035 .dig_out_nid = ALC882_DIGOUT_NID,
10036 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10037 .unsol_event = alc_automute_amp_unsol_event,
10038 .setup = alc885_macmini3_setup,
10039 .init_hook = alc_automute_amp,
e458b1fa 10040 },
4953550a
TI
10041 [ALC885_MACPRO] = {
10042 .mixers = { alc882_macpro_mixer },
10043 .init_verbs = { alc882_macpro_init_verbs },
10044 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10045 .dac_nids = alc882_dac_nids,
10046 .dig_out_nid = ALC882_DIGOUT_NID,
10047 .dig_in_nid = ALC882_DIGIN_NID,
10048 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10049 .channel_mode = alc882_ch_modes,
10050 .input_mux = &alc882_capture_source,
10051 .init_hook = alc885_macpro_init_hook,
10052 },
10053 [ALC885_IMAC24] = {
10054 .mixers = { alc885_imac24_mixer },
10055 .init_verbs = { alc885_imac24_init_verbs },
10056 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10057 .dac_nids = alc882_dac_nids,
10058 .dig_out_nid = ALC882_DIGOUT_NID,
10059 .dig_in_nid = ALC882_DIGIN_NID,
10060 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10061 .channel_mode = alc882_ch_modes,
10062 .input_mux = &alc882_capture_source,
10063 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 10064 .setup = alc885_imac24_setup,
4953550a
TI
10065 .init_hook = alc885_imac24_init_hook,
10066 },
4b7e1803 10067 [ALC885_IMAC91] = {
b7cccc52 10068 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10069 .init_verbs = { alc885_imac91_init_verbs,
10070 alc880_gpio1_init_verbs },
10071 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10072 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10073 .channel_mode = alc885_mba21_ch_modes,
10074 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10075 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10076 .dig_out_nid = ALC882_DIGOUT_NID,
10077 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10078 .unsol_event = alc_automute_amp_unsol_event,
10079 .setup = alc885_imac91_setup,
10080 .init_hook = alc_automute_amp,
4b7e1803 10081 },
4953550a
TI
10082 [ALC882_TARGA] = {
10083 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10084 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10085 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10086 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10087 .dac_nids = alc882_dac_nids,
10088 .dig_out_nid = ALC882_DIGOUT_NID,
10089 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10090 .adc_nids = alc882_adc_nids,
10091 .capsrc_nids = alc882_capsrc_nids,
10092 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10093 .channel_mode = alc882_3ST_6ch_modes,
10094 .need_dac_fix = 1,
10095 .input_mux = &alc882_capture_source,
10096 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10097 .setup = alc882_targa_setup,
10098 .init_hook = alc882_targa_automute,
4953550a
TI
10099 },
10100 [ALC882_ASUS_A7J] = {
10101 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10102 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10103 alc882_asus_a7j_verbs},
4953550a
TI
10104 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10105 .dac_nids = alc882_dac_nids,
10106 .dig_out_nid = ALC882_DIGOUT_NID,
10107 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10108 .adc_nids = alc882_adc_nids,
10109 .capsrc_nids = alc882_capsrc_nids,
10110 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10111 .channel_mode = alc882_3ST_6ch_modes,
10112 .need_dac_fix = 1,
10113 .input_mux = &alc882_capture_source,
10114 },
10115 [ALC882_ASUS_A7M] = {
10116 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10117 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10118 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10119 alc882_asus_a7m_verbs },
10120 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10121 .dac_nids = alc882_dac_nids,
10122 .dig_out_nid = ALC882_DIGOUT_NID,
10123 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10124 .channel_mode = alc880_threestack_modes,
10125 .need_dac_fix = 1,
10126 .input_mux = &alc882_capture_source,
10127 },
9c7f852e
TI
10128 [ALC883_3ST_2ch_DIG] = {
10129 .mixers = { alc883_3ST_2ch_mixer },
10130 .init_verbs = { alc883_init_verbs },
10131 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10132 .dac_nids = alc883_dac_nids,
10133 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10134 .dig_in_nid = ALC883_DIGIN_NID,
10135 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10136 .channel_mode = alc883_3ST_2ch_modes,
10137 .input_mux = &alc883_capture_source,
10138 },
10139 [ALC883_3ST_6ch_DIG] = {
10140 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10141 .init_verbs = { alc883_init_verbs },
10142 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10143 .dac_nids = alc883_dac_nids,
10144 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10145 .dig_in_nid = ALC883_DIGIN_NID,
10146 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10147 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10148 .need_dac_fix = 1,
9c7f852e 10149 .input_mux = &alc883_capture_source,
f12ab1e0 10150 },
9c7f852e
TI
10151 [ALC883_3ST_6ch] = {
10152 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10153 .init_verbs = { alc883_init_verbs },
10154 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10155 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10156 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10157 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10158 .need_dac_fix = 1,
9c7f852e 10159 .input_mux = &alc883_capture_source,
f12ab1e0 10160 },
17bba1b7
J
10161 [ALC883_3ST_6ch_INTEL] = {
10162 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10163 .init_verbs = { alc883_init_verbs },
10164 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10165 .dac_nids = alc883_dac_nids,
10166 .dig_out_nid = ALC883_DIGOUT_NID,
10167 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10168 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10169 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10170 .channel_mode = alc883_3ST_6ch_intel_modes,
10171 .need_dac_fix = 1,
10172 .input_mux = &alc883_3stack_6ch_intel,
10173 },
87a8c370
JK
10174 [ALC889A_INTEL] = {
10175 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10176 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10177 alc_hp15_unsol_verbs },
87a8c370
JK
10178 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10179 .dac_nids = alc883_dac_nids,
10180 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10181 .adc_nids = alc889_adc_nids,
10182 .dig_out_nid = ALC883_DIGOUT_NID,
10183 .dig_in_nid = ALC883_DIGIN_NID,
10184 .slave_dig_outs = alc883_slave_dig_outs,
10185 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10186 .channel_mode = alc889_8ch_intel_modes,
10187 .capsrc_nids = alc889_capsrc_nids,
10188 .input_mux = &alc889_capture_source,
4f5d1706
TI
10189 .setup = alc889_automute_setup,
10190 .init_hook = alc_automute_amp,
6732bd0d 10191 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10192 .need_dac_fix = 1,
10193 },
10194 [ALC889_INTEL] = {
10195 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10196 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10197 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10198 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10199 .dac_nids = alc883_dac_nids,
10200 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10201 .adc_nids = alc889_adc_nids,
10202 .dig_out_nid = ALC883_DIGOUT_NID,
10203 .dig_in_nid = ALC883_DIGIN_NID,
10204 .slave_dig_outs = alc883_slave_dig_outs,
10205 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10206 .channel_mode = alc889_8ch_intel_modes,
10207 .capsrc_nids = alc889_capsrc_nids,
10208 .input_mux = &alc889_capture_source,
4f5d1706 10209 .setup = alc889_automute_setup,
6732bd0d
WF
10210 .init_hook = alc889_intel_init_hook,
10211 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10212 .need_dac_fix = 1,
10213 },
9c7f852e
TI
10214 [ALC883_6ST_DIG] = {
10215 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10216 .init_verbs = { alc883_init_verbs },
10217 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10218 .dac_nids = alc883_dac_nids,
10219 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10220 .dig_in_nid = ALC883_DIGIN_NID,
10221 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10222 .channel_mode = alc883_sixstack_modes,
10223 .input_mux = &alc883_capture_source,
10224 },
ccc656ce 10225 [ALC883_TARGA_DIG] = {
c259249f 10226 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10227 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10228 alc883_targa_verbs},
ccc656ce
KY
10229 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10230 .dac_nids = alc883_dac_nids,
10231 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10232 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10233 .channel_mode = alc883_3ST_6ch_modes,
10234 .need_dac_fix = 1,
10235 .input_mux = &alc883_capture_source,
c259249f 10236 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10237 .setup = alc882_targa_setup,
10238 .init_hook = alc882_targa_automute,
ccc656ce
KY
10239 },
10240 [ALC883_TARGA_2ch_DIG] = {
c259249f 10241 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10242 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10243 alc883_targa_verbs},
ccc656ce
KY
10244 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10245 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10246 .adc_nids = alc883_adc_nids_alt,
10247 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10248 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10249 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10250 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10251 .channel_mode = alc883_3ST_2ch_modes,
10252 .input_mux = &alc883_capture_source,
c259249f 10253 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10254 .setup = alc882_targa_setup,
10255 .init_hook = alc882_targa_automute,
ccc656ce 10256 },
64a8be74 10257 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10258 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10259 alc883_chmode_mixer },
64a8be74 10260 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10261 alc883_targa_verbs },
64a8be74
DH
10262 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10263 .dac_nids = alc883_dac_nids,
10264 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10265 .adc_nids = alc883_adc_nids_rev,
10266 .capsrc_nids = alc883_capsrc_nids_rev,
10267 .dig_out_nid = ALC883_DIGOUT_NID,
10268 .dig_in_nid = ALC883_DIGIN_NID,
10269 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10270 .channel_mode = alc883_4ST_8ch_modes,
10271 .need_dac_fix = 1,
10272 .input_mux = &alc883_capture_source,
c259249f 10273 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10274 .setup = alc882_targa_setup,
10275 .init_hook = alc882_targa_automute,
64a8be74 10276 },
bab282b9 10277 [ALC883_ACER] = {
676a9b53 10278 .mixers = { alc883_base_mixer },
bab282b9
VA
10279 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10280 * and the headphone jack. Turn this on and rely on the
10281 * standard mute methods whenever the user wants to turn
10282 * these outputs off.
10283 */
10284 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10285 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10286 .dac_nids = alc883_dac_nids,
bab282b9
VA
10287 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10288 .channel_mode = alc883_3ST_2ch_modes,
10289 .input_mux = &alc883_capture_source,
10290 },
2880a867 10291 [ALC883_ACER_ASPIRE] = {
676a9b53 10292 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10293 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10294 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10295 .dac_nids = alc883_dac_nids,
10296 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10297 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10298 .channel_mode = alc883_3ST_2ch_modes,
10299 .input_mux = &alc883_capture_source,
a9fd4f3f 10300 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10301 .setup = alc883_acer_aspire_setup,
10302 .init_hook = alc_automute_amp,
d1a991a6 10303 },
5b2d1eca 10304 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10305 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10306 alc883_chmode_mixer },
10307 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10308 alc888_acer_aspire_4930g_verbs },
10309 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10310 .dac_nids = alc883_dac_nids,
10311 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10312 .adc_nids = alc883_adc_nids_rev,
10313 .capsrc_nids = alc883_capsrc_nids_rev,
10314 .dig_out_nid = ALC883_DIGOUT_NID,
10315 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10316 .channel_mode = alc883_3ST_6ch_modes,
10317 .need_dac_fix = 1,
973b8cb0 10318 .const_channel_count = 6,
5b2d1eca 10319 .num_mux_defs =
ef8ef5fb
VP
10320 ARRAY_SIZE(alc888_2_capture_sources),
10321 .input_mux = alc888_2_capture_sources,
d2fd4b09 10322 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10323 .setup = alc888_acer_aspire_4930g_setup,
10324 .init_hook = alc_automute_amp,
d2fd4b09
TV
10325 },
10326 [ALC888_ACER_ASPIRE_6530G] = {
10327 .mixers = { alc888_acer_aspire_6530_mixer },
10328 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10329 alc888_acer_aspire_6530g_verbs },
10330 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10331 .dac_nids = alc883_dac_nids,
10332 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10333 .adc_nids = alc883_adc_nids_rev,
10334 .capsrc_nids = alc883_capsrc_nids_rev,
10335 .dig_out_nid = ALC883_DIGOUT_NID,
10336 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10337 .channel_mode = alc883_3ST_2ch_modes,
10338 .num_mux_defs =
10339 ARRAY_SIZE(alc888_2_capture_sources),
10340 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10341 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10342 .setup = alc888_acer_aspire_6530g_setup,
10343 .init_hook = alc_automute_amp,
5b2d1eca 10344 },
3b315d70 10345 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10346 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10347 alc883_chmode_mixer },
10348 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10349 alc889_acer_aspire_8930g_verbs,
10350 alc889_eapd_verbs},
3b315d70
HM
10351 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10352 .dac_nids = alc883_dac_nids,
018df418
HM
10353 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10354 .adc_nids = alc889_adc_nids,
10355 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10356 .dig_out_nid = ALC883_DIGOUT_NID,
10357 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10358 .channel_mode = alc883_3ST_6ch_modes,
10359 .need_dac_fix = 1,
10360 .const_channel_count = 6,
10361 .num_mux_defs =
018df418
HM
10362 ARRAY_SIZE(alc889_capture_sources),
10363 .input_mux = alc889_capture_sources,
3b315d70 10364 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10365 .setup = alc889_acer_aspire_8930g_setup,
10366 .init_hook = alc_automute_amp,
f5de24b0 10367#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10368 .power_hook = alc_power_eapd,
f5de24b0 10369#endif
3b315d70 10370 },
fc86f954
DK
10371 [ALC888_ACER_ASPIRE_7730G] = {
10372 .mixers = { alc883_3ST_6ch_mixer,
10373 alc883_chmode_mixer },
10374 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10375 alc888_acer_aspire_7730G_verbs },
10376 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10377 .dac_nids = alc883_dac_nids,
10378 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10379 .adc_nids = alc883_adc_nids_rev,
10380 .capsrc_nids = alc883_capsrc_nids_rev,
10381 .dig_out_nid = ALC883_DIGOUT_NID,
10382 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10383 .channel_mode = alc883_3ST_6ch_modes,
10384 .need_dac_fix = 1,
10385 .const_channel_count = 6,
10386 .input_mux = &alc883_capture_source,
10387 .unsol_event = alc_automute_amp_unsol_event,
d9477207 10388 .setup = alc888_acer_aspire_7730g_setup,
fc86f954
DK
10389 .init_hook = alc_automute_amp,
10390 },
c07584c8
TD
10391 [ALC883_MEDION] = {
10392 .mixers = { alc883_fivestack_mixer,
10393 alc883_chmode_mixer },
10394 .init_verbs = { alc883_init_verbs,
b373bdeb 10395 alc883_medion_eapd_verbs },
c07584c8
TD
10396 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10397 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10398 .adc_nids = alc883_adc_nids_alt,
10399 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10400 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10401 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10402 .channel_mode = alc883_sixstack_modes,
10403 .input_mux = &alc883_capture_source,
b373bdeb 10404 },
7ad7b218
MC
10405 [ALC883_MEDION_WIM2160] = {
10406 .mixers = { alc883_medion_wim2160_mixer },
10407 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10408 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10409 .dac_nids = alc883_dac_nids,
10410 .dig_out_nid = ALC883_DIGOUT_NID,
10411 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10412 .adc_nids = alc883_adc_nids,
10413 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10414 .channel_mode = alc883_3ST_2ch_modes,
10415 .input_mux = &alc883_capture_source,
10416 .unsol_event = alc_automute_amp_unsol_event,
10417 .setup = alc883_medion_wim2160_setup,
10418 .init_hook = alc_automute_amp,
10419 },
b373bdeb 10420 [ALC883_LAPTOP_EAPD] = {
676a9b53 10421 .mixers = { alc883_base_mixer },
b373bdeb
AN
10422 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10423 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10424 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10425 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10426 .channel_mode = alc883_3ST_2ch_modes,
10427 .input_mux = &alc883_capture_source,
10428 },
a65cc60f 10429 [ALC883_CLEVO_M540R] = {
10430 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10431 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10432 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10433 .dac_nids = alc883_dac_nids,
10434 .dig_out_nid = ALC883_DIGOUT_NID,
10435 .dig_in_nid = ALC883_DIGIN_NID,
10436 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10437 .channel_mode = alc883_3ST_6ch_clevo_modes,
10438 .need_dac_fix = 1,
10439 .input_mux = &alc883_capture_source,
10440 /* This machine has the hardware HP auto-muting, thus
10441 * we need no software mute via unsol event
10442 */
10443 },
0c4cc443
HRK
10444 [ALC883_CLEVO_M720] = {
10445 .mixers = { alc883_clevo_m720_mixer },
10446 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10447 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10448 .dac_nids = alc883_dac_nids,
10449 .dig_out_nid = ALC883_DIGOUT_NID,
10450 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10451 .channel_mode = alc883_3ST_2ch_modes,
10452 .input_mux = &alc883_capture_source,
0c4cc443 10453 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10454 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10455 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10456 },
bc9f98a9
KY
10457 [ALC883_LENOVO_101E_2ch] = {
10458 .mixers = { alc883_lenovo_101e_2ch_mixer},
10459 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10460 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10461 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10462 .adc_nids = alc883_adc_nids_alt,
10463 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10464 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10465 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10466 .channel_mode = alc883_3ST_2ch_modes,
10467 .input_mux = &alc883_lenovo_101e_capture_source,
10468 .unsol_event = alc883_lenovo_101e_unsol_event,
10469 .init_hook = alc883_lenovo_101e_all_automute,
10470 },
272a527c
KY
10471 [ALC883_LENOVO_NB0763] = {
10472 .mixers = { alc883_lenovo_nb0763_mixer },
10473 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10474 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10475 .dac_nids = alc883_dac_nids,
272a527c
KY
10476 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10477 .channel_mode = alc883_3ST_2ch_modes,
10478 .need_dac_fix = 1,
10479 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10480 .unsol_event = alc_automute_amp_unsol_event,
dc427170 10481 .setup = alc883_lenovo_nb0763_setup,
4f5d1706 10482 .init_hook = alc_automute_amp,
272a527c
KY
10483 },
10484 [ALC888_LENOVO_MS7195_DIG] = {
10485 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10486 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10487 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10488 .dac_nids = alc883_dac_nids,
10489 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10490 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10491 .channel_mode = alc883_3ST_6ch_modes,
10492 .need_dac_fix = 1,
10493 .input_mux = &alc883_capture_source,
10494 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10495 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10496 },
10497 [ALC883_HAIER_W66] = {
c259249f 10498 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10499 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10500 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10501 .dac_nids = alc883_dac_nids,
10502 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10503 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10504 .channel_mode = alc883_3ST_2ch_modes,
10505 .input_mux = &alc883_capture_source,
a9fd4f3f 10506 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10507 .setup = alc883_haier_w66_setup,
10508 .init_hook = alc_automute_amp,
eea6419e 10509 },
4723c022 10510 [ALC888_3ST_HP] = {
eea6419e 10511 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10512 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10513 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10514 .dac_nids = alc883_dac_nids,
4723c022
CM
10515 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10516 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10517 .need_dac_fix = 1,
10518 .input_mux = &alc883_capture_source,
a9fd4f3f 10519 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10520 .setup = alc888_3st_hp_setup,
10521 .init_hook = alc_automute_amp,
8341de60 10522 },
5795b9e6 10523 [ALC888_6ST_DELL] = {
f24dbdc6 10524 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10525 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10526 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10527 .dac_nids = alc883_dac_nids,
10528 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10529 .dig_in_nid = ALC883_DIGIN_NID,
10530 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10531 .channel_mode = alc883_sixstack_modes,
10532 .input_mux = &alc883_capture_source,
a9fd4f3f 10533 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10534 .setup = alc888_6st_dell_setup,
10535 .init_hook = alc_automute_amp,
5795b9e6 10536 },
a8848bd6
AS
10537 [ALC883_MITAC] = {
10538 .mixers = { alc883_mitac_mixer },
10539 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10540 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10541 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10542 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10543 .channel_mode = alc883_3ST_2ch_modes,
10544 .input_mux = &alc883_capture_source,
a9fd4f3f 10545 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10546 .setup = alc883_mitac_setup,
10547 .init_hook = alc_automute_amp,
a8848bd6 10548 },
fb97dc67
J
10549 [ALC883_FUJITSU_PI2515] = {
10550 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10551 .init_verbs = { alc883_init_verbs,
10552 alc883_2ch_fujitsu_pi2515_verbs},
10553 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10554 .dac_nids = alc883_dac_nids,
10555 .dig_out_nid = ALC883_DIGOUT_NID,
10556 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10557 .channel_mode = alc883_3ST_2ch_modes,
10558 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10559 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10560 .setup = alc883_2ch_fujitsu_pi2515_setup,
10561 .init_hook = alc_automute_amp,
fb97dc67 10562 },
ef8ef5fb
VP
10563 [ALC888_FUJITSU_XA3530] = {
10564 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10565 .init_verbs = { alc883_init_verbs,
10566 alc888_fujitsu_xa3530_verbs },
10567 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10568 .dac_nids = alc883_dac_nids,
10569 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10570 .adc_nids = alc883_adc_nids_rev,
10571 .capsrc_nids = alc883_capsrc_nids_rev,
10572 .dig_out_nid = ALC883_DIGOUT_NID,
10573 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10574 .channel_mode = alc888_4ST_8ch_intel_modes,
10575 .num_mux_defs =
10576 ARRAY_SIZE(alc888_2_capture_sources),
10577 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10578 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10579 .setup = alc888_fujitsu_xa3530_setup,
10580 .init_hook = alc_automute_amp,
ef8ef5fb 10581 },
e2757d5e
KY
10582 [ALC888_LENOVO_SKY] = {
10583 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10584 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10585 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10586 .dac_nids = alc883_dac_nids,
10587 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10588 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10589 .channel_mode = alc883_sixstack_modes,
10590 .need_dac_fix = 1,
10591 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10592 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10593 .setup = alc888_lenovo_sky_setup,
10594 .init_hook = alc_automute_amp,
e2757d5e
KY
10595 },
10596 [ALC888_ASUS_M90V] = {
10597 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10598 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10599 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10600 .dac_nids = alc883_dac_nids,
10601 .dig_out_nid = ALC883_DIGOUT_NID,
10602 .dig_in_nid = ALC883_DIGIN_NID,
10603 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10604 .channel_mode = alc883_3ST_6ch_modes,
10605 .need_dac_fix = 1,
10606 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10607 .unsol_event = alc_sku_unsol_event,
10608 .setup = alc883_mode2_setup,
10609 .init_hook = alc_inithook,
e2757d5e
KY
10610 },
10611 [ALC888_ASUS_EEE1601] = {
10612 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10613 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10614 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10615 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10616 .dac_nids = alc883_dac_nids,
10617 .dig_out_nid = ALC883_DIGOUT_NID,
10618 .dig_in_nid = ALC883_DIGIN_NID,
10619 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10620 .channel_mode = alc883_3ST_2ch_modes,
10621 .need_dac_fix = 1,
10622 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10623 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10624 .init_hook = alc883_eee1601_inithook,
10625 },
3ab90935
WF
10626 [ALC1200_ASUS_P5Q] = {
10627 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10628 .init_verbs = { alc883_init_verbs },
10629 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10630 .dac_nids = alc883_dac_nids,
10631 .dig_out_nid = ALC1200_DIGOUT_NID,
10632 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10633 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10634 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10635 .channel_mode = alc883_sixstack_modes,
10636 .input_mux = &alc883_capture_source,
10637 },
eb4c41d3
TS
10638 [ALC889A_MB31] = {
10639 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10640 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10641 alc880_gpio1_init_verbs },
10642 .adc_nids = alc883_adc_nids,
10643 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10644 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10645 .dac_nids = alc883_dac_nids,
10646 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10647 .channel_mode = alc889A_mb31_6ch_modes,
10648 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10649 .input_mux = &alc889A_mb31_capture_source,
10650 .dig_out_nid = ALC883_DIGOUT_NID,
10651 .unsol_event = alc889A_mb31_unsol_event,
10652 .init_hook = alc889A_mb31_automute,
10653 },
3e1647c5
GG
10654 [ALC883_SONY_VAIO_TT] = {
10655 .mixers = { alc883_vaiott_mixer },
10656 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10657 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10658 .dac_nids = alc883_dac_nids,
10659 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10660 .channel_mode = alc883_3ST_2ch_modes,
10661 .input_mux = &alc883_capture_source,
10662 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10663 .setup = alc883_vaiott_setup,
10664 .init_hook = alc_automute_amp,
3e1647c5 10665 },
9c7f852e
TI
10666};
10667
10668
4953550a
TI
10669/*
10670 * Pin config fixes
10671 */
10672enum {
954a29c8
TI
10673 PINFIX_ABIT_AW9D_MAX,
10674 PINFIX_PB_M5210,
c3d226ab 10675 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10676};
10677
f8f25ba3
TI
10678static const struct alc_fixup alc882_fixups[] = {
10679 [PINFIX_ABIT_AW9D_MAX] = {
73413b12
TI
10680 .pins = (const struct alc_pincfg[]) {
10681 { 0x15, 0x01080104 }, /* side */
10682 { 0x16, 0x01011012 }, /* rear */
10683 { 0x17, 0x01016011 }, /* clfe */
10684 { }
10685 }
f8f25ba3 10686 },
954a29c8 10687 [PINFIX_PB_M5210] = {
73413b12
TI
10688 .verbs = (const struct hda_verb[]) {
10689 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10690 {}
10691 }
954a29c8 10692 },
c3d226ab
DH
10693 [PINFIX_ACER_ASPIRE_7736] = {
10694 .sku = ALC_FIXUP_SKU_IGNORE,
10695 },
4953550a
TI
10696};
10697
f8f25ba3 10698static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10699 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a 10700 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10701 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10702 {}
10703};
10704
9c7f852e
TI
10705/*
10706 * BIOS auto configuration
10707 */
05f5f477
TI
10708static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10709 const struct auto_pin_cfg *cfg)
10710{
10711 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10712}
10713
4953550a 10714static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10715 hda_nid_t nid, int pin_type,
489008cd 10716 hda_nid_t dac)
9c7f852e 10717{
f12ab1e0
TI
10718 int idx;
10719
489008cd 10720 /* set as output */
f6c7e546 10721 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10722
10723 if (dac == 0x25)
9c7f852e 10724 idx = 4;
489008cd
TI
10725 else if (dac >= 0x02 && dac <= 0x05)
10726 idx = dac - 2;
f9700d5a 10727 else
489008cd 10728 return;
9c7f852e 10729 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10730}
10731
4953550a 10732static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10733{
10734 struct alc_spec *spec = codec->spec;
10735 int i;
10736
10737 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10738 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10739 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10740 if (nid)
4953550a 10741 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10742 spec->multiout.dac_nids[i]);
9c7f852e
TI
10743 }
10744}
10745
4953550a 10746static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10747{
10748 struct alc_spec *spec = codec->spec;
489008cd 10749 hda_nid_t pin, dac;
5855fb80 10750 int i;
9c7f852e 10751
5855fb80
TI
10752 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10753 pin = spec->autocfg.hp_pins[i];
10754 if (!pin)
10755 break;
489008cd
TI
10756 dac = spec->multiout.hp_nid;
10757 if (!dac)
10758 dac = spec->multiout.dac_nids[0]; /* to front */
10759 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10760 }
5855fb80
TI
10761 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10762 pin = spec->autocfg.speaker_pins[i];
10763 if (!pin)
10764 break;
489008cd
TI
10765 dac = spec->multiout.extra_out_nid[0];
10766 if (!dac)
10767 dac = spec->multiout.dac_nids[0]; /* to front */
10768 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10769 }
9c7f852e
TI
10770}
10771
4953550a 10772static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10773{
10774 struct alc_spec *spec = codec->spec;
66ceeb6b 10775 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10776 int i;
10777
66ceeb6b
TI
10778 for (i = 0; i < cfg->num_inputs; i++) {
10779 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10780 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10781 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10782 snd_hda_codec_write(codec, nid, 0,
10783 AC_VERB_SET_AMP_GAIN_MUTE,
10784 AMP_OUT_MUTE);
10785 }
10786}
10787
10788static void alc882_auto_init_input_src(struct hda_codec *codec)
10789{
10790 struct alc_spec *spec = codec->spec;
10791 int c;
10792
10793 for (c = 0; c < spec->num_adc_nids; c++) {
10794 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10795 hda_nid_t nid = spec->capsrc_nids[c];
10796 unsigned int mux_idx;
10797 const struct hda_input_mux *imux;
10798 int conns, mute, idx, item;
10799
10800 conns = snd_hda_get_connections(codec, nid, conn_list,
10801 ARRAY_SIZE(conn_list));
10802 if (conns < 0)
10803 continue;
10804 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10805 imux = &spec->input_mux[mux_idx];
5311114d
TI
10806 if (!imux->num_items && mux_idx > 0)
10807 imux = &spec->input_mux[0];
4953550a
TI
10808 for (idx = 0; idx < conns; idx++) {
10809 /* if the current connection is the selected one,
10810 * unmute it as default - otherwise mute it
10811 */
10812 mute = AMP_IN_MUTE(idx);
10813 for (item = 0; item < imux->num_items; item++) {
10814 if (imux->items[item].index == idx) {
10815 if (spec->cur_mux[c] == item)
10816 mute = AMP_IN_UNMUTE(idx);
10817 break;
10818 }
10819 }
10820 /* check if we have a selector or mixer
10821 * we could check for the widget type instead, but
10822 * just check for Amp-In presence (in case of mixer
10823 * without amp-in there is something wrong, this
10824 * function shouldn't be used or capsrc nid is wrong)
10825 */
10826 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10827 snd_hda_codec_write(codec, nid, 0,
10828 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10829 mute);
10830 else if (mute != AMP_IN_MUTE(idx))
10831 snd_hda_codec_write(codec, nid, 0,
10832 AC_VERB_SET_CONNECT_SEL,
10833 idx);
9c7f852e
TI
10834 }
10835 }
10836}
10837
4953550a
TI
10838/* add mic boosts if needed */
10839static int alc_auto_add_mic_boost(struct hda_codec *codec)
10840{
10841 struct alc_spec *spec = codec->spec;
66ceeb6b 10842 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10843 int i, err;
53e8c323 10844 int type_idx = 0;
4953550a 10845 hda_nid_t nid;
5322bf27 10846 const char *prev_label = NULL;
4953550a 10847
66ceeb6b 10848 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10849 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10850 break;
10851 nid = cfg->inputs[i].pin;
10852 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10853 const char *label;
10854 char boost_label[32];
10855
10856 label = hda_get_autocfg_input_label(codec, cfg, i);
10857 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10858 type_idx++;
10859 else
10860 type_idx = 0;
5322bf27
DH
10861 prev_label = label;
10862
10863 snprintf(boost_label, sizeof(boost_label),
10864 "%s Boost Volume", label);
10865 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10866 boost_label, type_idx,
4953550a 10867 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10868 if (err < 0)
10869 return err;
10870 }
4953550a
TI
10871 }
10872 return 0;
10873}
f511b01c 10874
9c7f852e 10875/* almost identical with ALC880 parser... */
4953550a 10876static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10877{
10878 struct alc_spec *spec = codec->spec;
05f5f477 10879 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10880 int err;
9c7f852e 10881
05f5f477
TI
10882 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10883 alc882_ignore);
9c7f852e
TI
10884 if (err < 0)
10885 return err;
05f5f477
TI
10886 if (!spec->autocfg.line_outs)
10887 return 0; /* can't find valid BIOS pin config */
776e184e 10888
05f5f477
TI
10889 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10890 if (err < 0)
10891 return err;
10892 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10893 if (err < 0)
10894 return err;
10895 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10896 "Headphone");
05f5f477
TI
10897 if (err < 0)
10898 return err;
10899 err = alc880_auto_create_extra_out(spec,
10900 spec->autocfg.speaker_pins[0],
10901 "Speaker");
10902 if (err < 0)
10903 return err;
05f5f477 10904 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10905 if (err < 0)
10906 return err;
10907
05f5f477
TI
10908 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10909
757899ac 10910 alc_auto_parse_digital(codec);
05f5f477
TI
10911
10912 if (spec->kctls.list)
10913 add_mixer(spec, spec->kctls.list);
10914
10915 add_verb(spec, alc883_auto_init_verbs);
4953550a 10916 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10917 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10918 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10919
05f5f477
TI
10920 spec->num_mux_defs = 1;
10921 spec->input_mux = &spec->private_imux[0];
10922
6227cdce 10923 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10924
10925 err = alc_auto_add_mic_boost(codec);
10926 if (err < 0)
10927 return err;
61b9b9b1 10928
776e184e 10929 return 1; /* config found */
9c7f852e
TI
10930}
10931
10932/* additional initialization for auto-configuration model */
4953550a 10933static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10934{
f6c7e546 10935 struct alc_spec *spec = codec->spec;
4953550a
TI
10936 alc882_auto_init_multi_out(codec);
10937 alc882_auto_init_hp_out(codec);
10938 alc882_auto_init_analog_input(codec);
10939 alc882_auto_init_input_src(codec);
757899ac 10940 alc_auto_init_digital(codec);
f6c7e546 10941 if (spec->unsol_event)
7fb0d78f 10942 alc_inithook(codec);
9c7f852e
TI
10943}
10944
4953550a 10945static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10946{
10947 struct alc_spec *spec;
10948 int err, board_config;
10949
10950 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10951 if (spec == NULL)
10952 return -ENOMEM;
10953
10954 codec->spec = spec;
10955
4953550a
TI
10956 switch (codec->vendor_id) {
10957 case 0x10ec0882:
10958 case 0x10ec0885:
10959 break;
10960 default:
10961 /* ALC883 and variants */
10962 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10963 break;
10964 }
2c3bf9ab 10965
4953550a
TI
10966 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10967 alc882_models,
10968 alc882_cfg_tbl);
10969
10970 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10971 board_config = snd_hda_check_board_codec_sid_config(codec,
10972 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10973
10974 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10975 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10976 codec->chip_name);
10977 board_config = ALC882_AUTO;
9c7f852e
TI
10978 }
10979
7fa90e87
TI
10980 if (board_config == ALC882_AUTO)
10981 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a 10982
90622917
DH
10983 alc_auto_parse_customize_define(codec);
10984
4953550a 10985 if (board_config == ALC882_AUTO) {
9c7f852e 10986 /* automatic parse from the BIOS config */
4953550a 10987 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10988 if (err < 0) {
10989 alc_free(codec);
10990 return err;
f12ab1e0 10991 } else if (!err) {
9c7f852e
TI
10992 printk(KERN_INFO
10993 "hda_codec: Cannot set up configuration "
10994 "from BIOS. Using base mode...\n");
4953550a 10995 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10996 }
10997 }
10998
dc1eae25 10999 if (has_cdefine_beep(codec)) {
8af2591d
TI
11000 err = snd_hda_attach_beep_device(codec, 0x1);
11001 if (err < 0) {
11002 alc_free(codec);
11003 return err;
11004 }
680cd536
KK
11005 }
11006
4953550a 11007 if (board_config != ALC882_AUTO)
e9c364c0 11008 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11009
4953550a
TI
11010 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11011 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11012 /* FIXME: setup DAC5 */
11013 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11014 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11015
11016 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11017 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11018
4953550a 11019 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11020 int i, j;
4953550a
TI
11021 spec->num_adc_nids = 0;
11022 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11023 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11024 hda_nid_t cap;
d11f74c6 11025 hda_nid_t items[16];
4953550a
TI
11026 hda_nid_t nid = alc882_adc_nids[i];
11027 unsigned int wcap = get_wcaps(codec, nid);
11028 /* get type */
a22d543a 11029 wcap = get_wcaps_type(wcap);
4953550a
TI
11030 if (wcap != AC_WID_AUD_IN)
11031 continue;
11032 spec->private_adc_nids[spec->num_adc_nids] = nid;
11033 err = snd_hda_get_connections(codec, nid, &cap, 1);
11034 if (err < 0)
11035 continue;
d11f74c6
TI
11036 err = snd_hda_get_connections(codec, cap, items,
11037 ARRAY_SIZE(items));
11038 if (err < 0)
11039 continue;
11040 for (j = 0; j < imux->num_items; j++)
11041 if (imux->items[j].index >= err)
11042 break;
11043 if (j < imux->num_items)
11044 continue;
4953550a
TI
11045 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11046 spec->num_adc_nids++;
61b9b9b1 11047 }
4953550a
TI
11048 spec->adc_nids = spec->private_adc_nids;
11049 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11050 }
11051
b59bdf3b 11052 set_capture_mixer(codec);
da00c244 11053
dc1eae25 11054 if (has_cdefine_beep(codec))
da00c244 11055 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11056
7fa90e87
TI
11057 if (board_config == ALC882_AUTO)
11058 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
11059
2134ea4f
TI
11060 spec->vmaster_nid = 0x0c;
11061
9c7f852e 11062 codec->patch_ops = alc_patch_ops;
4953550a
TI
11063 if (board_config == ALC882_AUTO)
11064 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11065
11066 alc_init_jacks(codec);
cb53c626
TI
11067#ifdef CONFIG_SND_HDA_POWER_SAVE
11068 if (!spec->loopback.amplist)
4953550a 11069 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11070#endif
9c7f852e
TI
11071
11072 return 0;
11073}
11074
4953550a 11075
9c7f852e
TI
11076/*
11077 * ALC262 support
11078 */
11079
11080#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11081#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11082
11083#define alc262_dac_nids alc260_dac_nids
11084#define alc262_adc_nids alc882_adc_nids
11085#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11086#define alc262_capsrc_nids alc882_capsrc_nids
11087#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11088
11089#define alc262_modes alc260_modes
11090#define alc262_capture_source alc882_capture_source
11091
4e555fe5
KY
11092static hda_nid_t alc262_dmic_adc_nids[1] = {
11093 /* ADC0 */
11094 0x09
11095};
11096
11097static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11098
9c7f852e
TI
11099static struct snd_kcontrol_new alc262_base_mixer[] = {
11100 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11101 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11102 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11103 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11104 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11105 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11106 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11107 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11108 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11109 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11110 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11111 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11112 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11113 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11114 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11115 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11116 { } /* end */
11117};
11118
ce875f07
TI
11119/* update HP, line and mono-out pins according to the master switch */
11120static void alc262_hp_master_update(struct hda_codec *codec)
11121{
11122 struct alc_spec *spec = codec->spec;
11123 int val = spec->master_sw;
11124
11125 /* HP & line-out */
11126 snd_hda_codec_write_cache(codec, 0x1b, 0,
11127 AC_VERB_SET_PIN_WIDGET_CONTROL,
11128 val ? PIN_HP : 0);
11129 snd_hda_codec_write_cache(codec, 0x15, 0,
11130 AC_VERB_SET_PIN_WIDGET_CONTROL,
11131 val ? PIN_HP : 0);
11132 /* mono (speaker) depending on the HP jack sense */
11133 val = val && !spec->jack_present;
11134 snd_hda_codec_write_cache(codec, 0x16, 0,
11135 AC_VERB_SET_PIN_WIDGET_CONTROL,
11136 val ? PIN_OUT : 0);
11137}
11138
11139static void alc262_hp_bpc_automute(struct hda_codec *codec)
11140{
11141 struct alc_spec *spec = codec->spec;
864f92be
WF
11142
11143 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11144 alc262_hp_master_update(codec);
11145}
11146
11147static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11148{
11149 if ((res >> 26) != ALC880_HP_EVENT)
11150 return;
11151 alc262_hp_bpc_automute(codec);
11152}
11153
11154static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11155{
11156 struct alc_spec *spec = codec->spec;
864f92be
WF
11157
11158 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11159 alc262_hp_master_update(codec);
11160}
11161
11162static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11163 unsigned int res)
11164{
11165 if ((res >> 26) != ALC880_HP_EVENT)
11166 return;
11167 alc262_hp_wildwest_automute(codec);
11168}
11169
b72519b5 11170#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11171
11172static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11173 struct snd_ctl_elem_value *ucontrol)
11174{
11175 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11176 struct alc_spec *spec = codec->spec;
11177 int val = !!*ucontrol->value.integer.value;
11178
11179 if (val == spec->master_sw)
11180 return 0;
11181 spec->master_sw = val;
11182 alc262_hp_master_update(codec);
11183 return 1;
11184}
11185
b72519b5
TI
11186#define ALC262_HP_MASTER_SWITCH \
11187 { \
11188 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11189 .name = "Master Playback Switch", \
11190 .info = snd_ctl_boolean_mono_info, \
11191 .get = alc262_hp_master_sw_get, \
11192 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11193 }, \
11194 { \
11195 .iface = NID_MAPPING, \
11196 .name = "Master Playback Switch", \
11197 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11198 }
11199
5b0cb1d8 11200
9c7f852e 11201static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11202 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11203 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11204 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11206 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11207 HDA_OUTPUT),
11208 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11209 HDA_OUTPUT),
9c7f852e
TI
11210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11212 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11213 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11214 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11215 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11216 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11217 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11218 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11219 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11220 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11221 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11222 { } /* end */
11223};
11224
cd7509a4 11225static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11226 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11227 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11228 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11229 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11230 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11231 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11232 HDA_OUTPUT),
11233 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11234 HDA_OUTPUT),
cd7509a4
KY
11235 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11236 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11237 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11238 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11239 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11240 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11241 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11242 { } /* end */
11243};
11244
11245static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11246 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11247 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11248 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11249 { } /* end */
11250};
11251
66d2a9d6 11252/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11253static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11254{
11255 struct alc_spec *spec = codec->spec;
66d2a9d6 11256
a9fd4f3f 11257 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11258 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11259}
11260
66d2a9d6 11261static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11262 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11263 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11264 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11265 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11268 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11269 { } /* end */
11270};
11271
11272static struct hda_verb alc262_hp_t5735_verbs[] = {
11273 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11274 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11275
11276 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11277 { }
11278};
11279
8c427226 11280static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11281 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11282 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11283 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11284 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11286 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11287 { } /* end */
11288};
11289
11290static struct hda_verb alc262_hp_rp5700_verbs[] = {
11291 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11292 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11293 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11294 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11295 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11296 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11297 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11299 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11300 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11301 {}
11302};
11303
11304static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11305 .num_items = 1,
11306 .items = {
11307 { "Line", 0x1 },
11308 },
11309};
11310
42171c17
TI
11311/* bind hp and internal speaker mute (with plug check) as master switch */
11312static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11313{
42171c17
TI
11314 struct alc_spec *spec = codec->spec;
11315 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11316 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11317 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11318 unsigned int mute;
0724ea2a 11319
42171c17
TI
11320 /* HP */
11321 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11322 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11323 HDA_AMP_MUTE, mute);
11324 /* mute internal speaker per jack sense */
11325 if (spec->jack_present)
11326 mute = HDA_AMP_MUTE;
11327 if (line_nid)
11328 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11329 HDA_AMP_MUTE, mute);
11330 if (speaker_nid && speaker_nid != line_nid)
11331 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11332 HDA_AMP_MUTE, mute);
42171c17
TI
11333}
11334
11335#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11336
11337static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11338 struct snd_ctl_elem_value *ucontrol)
11339{
11340 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11341 struct alc_spec *spec = codec->spec;
11342 int val = !!*ucontrol->value.integer.value;
11343
11344 if (val == spec->master_sw)
11345 return 0;
11346 spec->master_sw = val;
11347 alc262_hippo_master_update(codec);
11348 return 1;
11349}
11350
11351#define ALC262_HIPPO_MASTER_SWITCH \
11352 { \
11353 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11354 .name = "Master Playback Switch", \
11355 .info = snd_ctl_boolean_mono_info, \
11356 .get = alc262_hippo_master_sw_get, \
11357 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11358 }, \
11359 { \
11360 .iface = NID_MAPPING, \
11361 .name = "Master Playback Switch", \
11362 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11363 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11364 }
42171c17
TI
11365
11366static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11367 ALC262_HIPPO_MASTER_SWITCH,
11368 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11369 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11370 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11371 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11372 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11373 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11375 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11376 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11377 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11378 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11379 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11380 { } /* end */
11381};
11382
11383static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11384 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11385 ALC262_HIPPO_MASTER_SWITCH,
11386 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11387 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11388 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11389 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11390 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11391 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11392 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11393 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11394 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11395 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11396 { } /* end */
11397};
11398
11399/* mute/unmute internal speaker according to the hp jack and mute state */
11400static void alc262_hippo_automute(struct hda_codec *codec)
11401{
11402 struct alc_spec *spec = codec->spec;
11403 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11404
864f92be 11405 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11406 alc262_hippo_master_update(codec);
0724ea2a 11407}
5b31954e 11408
42171c17
TI
11409static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11410{
11411 if ((res >> 26) != ALC880_HP_EVENT)
11412 return;
11413 alc262_hippo_automute(codec);
11414}
11415
4f5d1706 11416static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11417{
11418 struct alc_spec *spec = codec->spec;
11419
11420 spec->autocfg.hp_pins[0] = 0x15;
11421 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11422}
11423
4f5d1706 11424static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11425{
11426 struct alc_spec *spec = codec->spec;
11427
11428 spec->autocfg.hp_pins[0] = 0x1b;
11429 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11430}
11431
11432
272a527c 11433static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11434 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11435 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11438 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11439 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11440 { } /* end */
11441};
11442
83c34218 11443static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11444 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11445 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11446 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11447 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11448 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11449 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11450 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11451 { } /* end */
11452};
272a527c 11453
ba340e82
TV
11454static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11455 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11456 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11457 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11458 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11459 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11460 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11462 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11463 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11464 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11465 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11466 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11467 { } /* end */
11468};
11469
11470static struct hda_verb alc262_tyan_verbs[] = {
11471 /* Headphone automute */
11472 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11473 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11474 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11475
11476 /* P11 AUX_IN, white 4-pin connector */
11477 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11478 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11479 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11480 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11481
11482 {}
11483};
11484
11485/* unsolicited event for HP jack sensing */
4f5d1706 11486static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11487{
a9fd4f3f 11488 struct alc_spec *spec = codec->spec;
ba340e82 11489
a9fd4f3f
TI
11490 spec->autocfg.hp_pins[0] = 0x1b;
11491 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11492}
11493
ba340e82 11494
9c7f852e
TI
11495#define alc262_capture_mixer alc882_capture_mixer
11496#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11497
11498/*
11499 * generic initialization of ADC, input mixers and output mixers
11500 */
11501static struct hda_verb alc262_init_verbs[] = {
11502 /*
11503 * Unmute ADC0-2 and set the default input to mic-in
11504 */
11505 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11506 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11507 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11508 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11509 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11510 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11511
cb53c626 11512 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11513 * mixer widget
f12ab1e0
TI
11514 * Note: PASD motherboards uses the Line In 2 as the input for
11515 * front panel mic (mic 2)
9c7f852e
TI
11516 */
11517 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11523
11524 /*
df694daa
KY
11525 * Set up output mixers (0x0c - 0x0e)
11526 */
11527 /* set vol=0 to output mixers */
11528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11529 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11530 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11531 /* set up input amps for analog loopback */
11532 /* Amp Indices: DAC = 0, mixer = 1 */
11533 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11534 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11535 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11536 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11537 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11539
11540 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11542 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11544 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11545 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11546
11547 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11548 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11549 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11550 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11551 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11552
df694daa
KY
11553 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11554 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11555
df694daa
KY
11556 /* FIXME: use matrix-type input source selection */
11557 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11558 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11559 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11560 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11561 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11562 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11563 /* Input mixer2 */
11564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11566 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11567 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11568 /* Input mixer3 */
11569 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11571 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11573
11574 { }
11575};
1da177e4 11576
4e555fe5
KY
11577static struct hda_verb alc262_eapd_verbs[] = {
11578 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11579 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11580 { }
11581};
11582
ccc656ce
KY
11583static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11584 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11585 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11586 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11587
11588 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11589 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11590 {}
11591};
11592
272a527c
KY
11593static struct hda_verb alc262_sony_unsol_verbs[] = {
11594 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11595 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11596 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11597
11598 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11599 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11600 {}
272a527c
KY
11601};
11602
4e555fe5
KY
11603static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11604 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11605 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11606 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11607 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11608 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11609 { } /* end */
11610};
11611
11612static struct hda_verb alc262_toshiba_s06_verbs[] = {
11613 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11615 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11616 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11617 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11618 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11619 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11620 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11621 {}
11622};
11623
4f5d1706 11624static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11625{
a9fd4f3f
TI
11626 struct alc_spec *spec = codec->spec;
11627
11628 spec->autocfg.hp_pins[0] = 0x15;
11629 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11630 spec->ext_mic.pin = 0x18;
11631 spec->ext_mic.mux_idx = 0;
11632 spec->int_mic.pin = 0x12;
11633 spec->int_mic.mux_idx = 9;
11634 spec->auto_mic = 1;
4e555fe5
KY
11635}
11636
e8f9ae2a
PT
11637/*
11638 * nec model
11639 * 0x15 = headphone
11640 * 0x16 = internal speaker
11641 * 0x18 = external mic
11642 */
11643
11644static struct snd_kcontrol_new alc262_nec_mixer[] = {
11645 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11646 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11647
11648 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11650 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11651
11652 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11653 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11654 { } /* end */
11655};
11656
11657static struct hda_verb alc262_nec_verbs[] = {
11658 /* Unmute Speaker */
11659 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11660
11661 /* Headphone */
11662 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11663 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11664
11665 /* External mic to headphone */
11666 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11667 /* External mic to speaker */
11668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11669 {}
11670};
11671
834be88d
TI
11672/*
11673 * fujitsu model
5d9fab2d
TV
11674 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11675 * 0x1b = port replicator headphone out
834be88d
TI
11676 */
11677
11678#define ALC_HP_EVENT 0x37
11679
11680static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11681 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11682 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11683 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11684 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11685 {}
11686};
11687
0e31daf7
J
11688static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11689 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11690 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11691 {}
11692};
11693
e2595322
DC
11694static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11695 /* Front Mic pin: input vref at 50% */
11696 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11697 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11698 {}
11699};
11700
834be88d 11701static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11702 .num_items = 3,
834be88d
TI
11703 .items = {
11704 { "Mic", 0x0 },
28c4edb7 11705 { "Internal Mic", 0x1 },
834be88d
TI
11706 { "CD", 0x4 },
11707 },
11708};
11709
9c7f852e
TI
11710static struct hda_input_mux alc262_HP_capture_source = {
11711 .num_items = 5,
11712 .items = {
11713 { "Mic", 0x0 },
accbe498 11714 { "Front Mic", 0x1 },
9c7f852e
TI
11715 { "Line", 0x2 },
11716 { "CD", 0x4 },
11717 { "AUX IN", 0x6 },
11718 },
11719};
11720
accbe498 11721static struct hda_input_mux alc262_HP_D7000_capture_source = {
11722 .num_items = 4,
11723 .items = {
11724 { "Mic", 0x0 },
11725 { "Front Mic", 0x2 },
11726 { "Line", 0x1 },
11727 { "CD", 0x4 },
11728 },
11729};
11730
ebc7a406 11731/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11732static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11733{
11734 struct alc_spec *spec = codec->spec;
11735 unsigned int mute;
11736
f12ab1e0 11737 if (force || !spec->sense_updated) {
864f92be
WF
11738 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11739 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11740 spec->sense_updated = 1;
11741 }
ebc7a406
TI
11742 /* unmute internal speaker only if both HPs are unplugged and
11743 * master switch is on
11744 */
11745 if (spec->jack_present)
11746 mute = HDA_AMP_MUTE;
11747 else
834be88d 11748 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11749 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11750 HDA_AMP_MUTE, mute);
834be88d
TI
11751}
11752
11753/* unsolicited event for HP jack sensing */
11754static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11755 unsigned int res)
11756{
11757 if ((res >> 26) != ALC_HP_EVENT)
11758 return;
11759 alc262_fujitsu_automute(codec, 1);
11760}
11761
ebc7a406
TI
11762static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11763{
11764 alc262_fujitsu_automute(codec, 1);
11765}
11766
834be88d 11767/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11768static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11769 .ops = &snd_hda_bind_vol,
11770 .values = {
11771 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11772 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11773 0
11774 },
11775};
834be88d 11776
0e31daf7
J
11777/* mute/unmute internal speaker according to the hp jack and mute state */
11778static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11779{
11780 struct alc_spec *spec = codec->spec;
11781 unsigned int mute;
11782
11783 if (force || !spec->sense_updated) {
864f92be 11784 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11785 spec->sense_updated = 1;
11786 }
11787 if (spec->jack_present) {
11788 /* mute internal speaker */
11789 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11790 HDA_AMP_MUTE, HDA_AMP_MUTE);
11791 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11792 HDA_AMP_MUTE, HDA_AMP_MUTE);
11793 } else {
11794 /* unmute internal speaker if necessary */
11795 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11796 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11797 HDA_AMP_MUTE, mute);
11798 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11799 HDA_AMP_MUTE, mute);
11800 }
11801}
11802
11803/* unsolicited event for HP jack sensing */
11804static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11805 unsigned int res)
11806{
11807 if ((res >> 26) != ALC_HP_EVENT)
11808 return;
11809 alc262_lenovo_3000_automute(codec, 1);
11810}
11811
8de56b7d
TI
11812static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11813 int dir, int idx, long *valp)
11814{
11815 int i, change = 0;
11816
11817 for (i = 0; i < 2; i++, valp++)
11818 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11819 HDA_AMP_MUTE,
11820 *valp ? 0 : HDA_AMP_MUTE);
11821 return change;
11822}
11823
834be88d
TI
11824/* bind hp and internal speaker mute (with plug check) */
11825static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11826 struct snd_ctl_elem_value *ucontrol)
11827{
11828 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11829 long *valp = ucontrol->value.integer.value;
11830 int change;
11831
8de56b7d
TI
11832 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11833 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11834 if (change)
11835 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11836 return change;
11837}
11838
11839static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11840 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11841 {
11842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11843 .name = "Master Playback Switch",
5e26dfd0 11844 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11845 .info = snd_hda_mixer_amp_switch_info,
11846 .get = snd_hda_mixer_amp_switch_get,
11847 .put = alc262_fujitsu_master_sw_put,
11848 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11849 },
5b0cb1d8
JK
11850 {
11851 .iface = NID_MAPPING,
11852 .name = "Master Playback Switch",
11853 .private_value = 0x1b,
11854 },
834be88d
TI
11855 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11856 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11857 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11858 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11859 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11860 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11861 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11862 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11863 { } /* end */
11864};
11865
0e31daf7
J
11866/* bind hp and internal speaker mute (with plug check) */
11867static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11868 struct snd_ctl_elem_value *ucontrol)
11869{
11870 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11871 long *valp = ucontrol->value.integer.value;
11872 int change;
11873
8de56b7d 11874 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11875 if (change)
11876 alc262_lenovo_3000_automute(codec, 0);
11877 return change;
11878}
11879
11880static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11881 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11882 {
11883 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11884 .name = "Master Playback Switch",
5e26dfd0 11885 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11886 .info = snd_hda_mixer_amp_switch_info,
11887 .get = snd_hda_mixer_amp_switch_get,
11888 .put = alc262_lenovo_3000_master_sw_put,
11889 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11890 },
11891 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11892 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11893 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11894 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11895 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11896 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11897 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11898 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11899 { } /* end */
11900};
11901
9f99a638
HM
11902static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11903 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11904 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11905 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11906 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11907 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11908 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11909 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11910 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11911 { } /* end */
11912};
11913
304dcaac
TI
11914/* additional init verbs for Benq laptops */
11915static struct hda_verb alc262_EAPD_verbs[] = {
11916 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11917 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11918 {}
11919};
11920
83c34218
KY
11921static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11922 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11923 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11924
11925 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11926 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11927 {}
11928};
11929
f651b50b
TD
11930/* Samsung Q1 Ultra Vista model setup */
11931static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11932 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11933 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11936 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11937 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11938 { } /* end */
11939};
11940
11941static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11942 /* output mixer */
11943 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11944 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11946 /* speaker */
11947 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11948 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11949 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11950 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11951 /* HP */
f651b50b 11952 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11953 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11954 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11955 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11956 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11957 /* internal mic */
11958 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11959 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11960 /* ADC, choose mic */
11961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11962 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11963 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11964 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11965 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11966 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11967 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11968 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11969 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11970 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11971 {}
11972};
11973
f651b50b
TD
11974/* mute/unmute internal speaker according to the hp jack and mute state */
11975static void alc262_ultra_automute(struct hda_codec *codec)
11976{
11977 struct alc_spec *spec = codec->spec;
11978 unsigned int mute;
f651b50b 11979
bb9f76cd
TI
11980 mute = 0;
11981 /* auto-mute only when HP is used as HP */
11982 if (!spec->cur_mux[0]) {
864f92be 11983 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11984 if (spec->jack_present)
11985 mute = HDA_AMP_MUTE;
f651b50b 11986 }
bb9f76cd
TI
11987 /* mute/unmute internal speaker */
11988 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11989 HDA_AMP_MUTE, mute);
11990 /* mute/unmute HP */
11991 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11992 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11993}
11994
11995/* unsolicited event for HP jack sensing */
11996static void alc262_ultra_unsol_event(struct hda_codec *codec,
11997 unsigned int res)
11998{
11999 if ((res >> 26) != ALC880_HP_EVENT)
12000 return;
12001 alc262_ultra_automute(codec);
12002}
12003
bb9f76cd
TI
12004static struct hda_input_mux alc262_ultra_capture_source = {
12005 .num_items = 2,
12006 .items = {
12007 { "Mic", 0x1 },
12008 { "Headphone", 0x7 },
12009 },
12010};
12011
12012static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12013 struct snd_ctl_elem_value *ucontrol)
12014{
12015 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12016 struct alc_spec *spec = codec->spec;
12017 int ret;
12018
54cbc9ab 12019 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12020 if (!ret)
12021 return 0;
12022 /* reprogram the HP pin as mic or HP according to the input source */
12023 snd_hda_codec_write_cache(codec, 0x15, 0,
12024 AC_VERB_SET_PIN_WIDGET_CONTROL,
12025 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12026 alc262_ultra_automute(codec); /* mute/unmute HP */
12027 return ret;
12028}
12029
12030static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12031 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12032 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12033 {
12034 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12035 .name = "Capture Source",
54cbc9ab
TI
12036 .info = alc_mux_enum_info,
12037 .get = alc_mux_enum_get,
bb9f76cd
TI
12038 .put = alc262_ultra_mux_enum_put,
12039 },
5b0cb1d8
JK
12040 {
12041 .iface = NID_MAPPING,
12042 .name = "Capture Source",
12043 .private_value = 0x15,
12044 },
bb9f76cd
TI
12045 { } /* end */
12046};
12047
c3fc1f50
TI
12048/* We use two mixers depending on the output pin; 0x16 is a mono output
12049 * and thus it's bound with a different mixer.
12050 * This function returns which mixer amp should be used.
12051 */
12052static int alc262_check_volbit(hda_nid_t nid)
12053{
12054 if (!nid)
12055 return 0;
12056 else if (nid == 0x16)
12057 return 2;
12058 else
12059 return 1;
12060}
12061
12062static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12063 const char *pfx, int *vbits, int idx)
c3fc1f50 12064{
c3fc1f50
TI
12065 unsigned long val;
12066 int vbit;
12067
12068 vbit = alc262_check_volbit(nid);
12069 if (!vbit)
12070 return 0;
12071 if (*vbits & vbit) /* a volume control for this mixer already there */
12072 return 0;
12073 *vbits |= vbit;
c3fc1f50
TI
12074 if (vbit == 2)
12075 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12076 else
12077 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12078 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12079}
12080
12081static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12082 const char *pfx, int idx)
c3fc1f50 12083{
c3fc1f50
TI
12084 unsigned long val;
12085
12086 if (!nid)
12087 return 0;
c3fc1f50
TI
12088 if (nid == 0x16)
12089 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12090 else
12091 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12092 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12093}
12094
df694daa 12095/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12096static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12097 const struct auto_pin_cfg *cfg)
df694daa 12098{
c3fc1f50
TI
12099 const char *pfx;
12100 int vbits;
033688a5 12101 int i, err;
df694daa
KY
12102
12103 spec->multiout.num_dacs = 1; /* only use one dac */
12104 spec->multiout.dac_nids = spec->private_dac_nids;
12105 spec->multiout.dac_nids[0] = 2;
12106
bcb2f0f5
TI
12107 pfx = alc_get_line_out_pfx(cfg, true);
12108 if (!pfx)
c3fc1f50 12109 pfx = "Front";
033688a5
TI
12110 for (i = 0; i < 2; i++) {
12111 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12112 if (err < 0)
12113 return err;
12114 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12115 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12116 "Speaker", i);
12117 if (err < 0)
12118 return err;
12119 }
12120 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12121 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12122 "Headphone", i);
12123 if (err < 0)
12124 return err;
12125 }
12126 }
df694daa 12127
c3fc1f50
TI
12128 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12129 alc262_check_volbit(cfg->speaker_pins[0]) |
12130 alc262_check_volbit(cfg->hp_pins[0]);
12131 if (vbits == 1 || vbits == 2)
12132 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12133 vbits = 0;
033688a5
TI
12134 for (i = 0; i < 2; i++) {
12135 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12136 &vbits, i);
12137 if (err < 0)
12138 return err;
12139 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12140 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12141 "Speaker", &vbits, i);
12142 if (err < 0)
12143 return err;
12144 }
12145 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12146 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12147 "Headphone", &vbits, i);
12148 if (err < 0)
12149 return err;
12150 }
12151 }
f12ab1e0 12152 return 0;
df694daa
KY
12153}
12154
05f5f477 12155#define alc262_auto_create_input_ctls \
eaa9b3a7 12156 alc882_auto_create_input_ctls
df694daa
KY
12157
12158/*
12159 * generic initialization of ADC, input mixers and output mixers
12160 */
12161static struct hda_verb alc262_volume_init_verbs[] = {
12162 /*
12163 * Unmute ADC0-2 and set the default input to mic-in
12164 */
12165 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12167 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12168 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12169 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12170 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12171
cb53c626 12172 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12173 * mixer widget
f12ab1e0
TI
12174 * Note: PASD motherboards uses the Line In 2 as the input for
12175 * front panel mic (mic 2)
df694daa
KY
12176 */
12177 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12178 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12179 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12180 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12181 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12182 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12183
12184 /*
12185 * Set up output mixers (0x0c - 0x0f)
12186 */
12187 /* set vol=0 to output mixers */
12188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12189 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12190 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12191
df694daa
KY
12192 /* set up input amps for analog loopback */
12193 /* Amp Indices: DAC = 0, mixer = 1 */
12194 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12196 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12197 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12198 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12199 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12200
12201 /* FIXME: use matrix-type input source selection */
12202 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12203 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12205 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12208 /* Input mixer2 */
12209 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12211 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12213 /* Input mixer3 */
12214 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12217 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12218
12219 { }
12220};
12221
9c7f852e
TI
12222static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12223 /*
12224 * Unmute ADC0-2 and set the default input to mic-in
12225 */
12226 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12228 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12229 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12230 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12231 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12232
cb53c626 12233 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12234 * mixer widget
f12ab1e0
TI
12235 * Note: PASD motherboards uses the Line In 2 as the input for
12236 * front panel mic (mic 2)
9c7f852e
TI
12237 */
12238 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12239 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12246
9c7f852e
TI
12247 /*
12248 * Set up output mixers (0x0c - 0x0e)
12249 */
12250 /* set vol=0 to output mixers */
12251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12252 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12253 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12254
12255 /* set up input amps for analog loopback */
12256 /* Amp Indices: DAC = 0, mixer = 1 */
12257 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12258 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12259 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12260 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12261 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12262 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12263
ce875f07 12264 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12265 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12266 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12267
12268 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12269 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12270
12271 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12272 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12273
12274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12275 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12276 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12277 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12278 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12279
0e4835c1 12280 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12281 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12282 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12283 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12284 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12285 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12286
12287
12288 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12289 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12290 /* Input mixer1: only unmute Mic */
9c7f852e 12291 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12292 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12293 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12294 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12296 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12300 /* Input mixer2 */
12301 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12302 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12303 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12310 /* Input mixer3 */
12311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12318 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12319 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12320
ce875f07
TI
12321 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12322
9c7f852e
TI
12323 { }
12324};
12325
cd7509a4
KY
12326static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12327 /*
12328 * Unmute ADC0-2 and set the default input to mic-in
12329 */
12330 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12332 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12333 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12334 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12335 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12336
cb53c626 12337 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12338 * mixer widget
12339 * Note: PASD motherboards uses the Line In 2 as the input for front
12340 * panel mic (mic 2)
12341 */
12342 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12343 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12344 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12345 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12346 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12347 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12348 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12349 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12350 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12351 /*
12352 * Set up output mixers (0x0c - 0x0e)
12353 */
12354 /* set vol=0 to output mixers */
12355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12356 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12357 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12358
12359 /* set up input amps for analog loopback */
12360 /* Amp Indices: DAC = 0, mixer = 1 */
12361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12363 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12365 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12366 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12367
12368
12369 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12370 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12371 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12372 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12373 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12374 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12375 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12376
12377 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12378 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12379
12380 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12381 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12382
12383 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12384 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12385 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12386 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12387 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12388 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12389
12390 /* FIXME: use matrix-type input source selection */
12391 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12392 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12393 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12394 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12395 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12396 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12397 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12398 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12399 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12400 /* Input mixer2 */
12401 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12402 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12403 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12404 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12405 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12406 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12407 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12408 /* Input mixer3 */
12409 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12410 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12411 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12412 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12413 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12414 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12415 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12416
ce875f07
TI
12417 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12418
cd7509a4
KY
12419 { }
12420};
12421
9f99a638
HM
12422static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12423
12424 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12425 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12426 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12427
12428 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12429 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12431 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12432
12433 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12434 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12435 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12436 {}
12437};
12438
18675e42
TI
12439/*
12440 * Pin config fixes
12441 */
12442enum {
12443 PINFIX_FSC_H270,
12444};
12445
12446static const struct alc_fixup alc262_fixups[] = {
12447 [PINFIX_FSC_H270] = {
12448 .pins = (const struct alc_pincfg[]) {
12449 { 0x14, 0x99130110 }, /* speaker */
12450 { 0x15, 0x0221142f }, /* front HP */
12451 { 0x1b, 0x0121141f }, /* rear HP */
12452 { }
12453 }
12454 },
12455 [PINFIX_PB_M5210] = {
12456 .verbs = (const struct hda_verb[]) {
12457 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
12458 {}
12459 }
12460 },
12461};
12462
12463static struct snd_pci_quirk alc262_fixup_tbl[] = {
12464 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12465 {}
12466};
12467
9f99a638 12468
cb53c626
TI
12469#ifdef CONFIG_SND_HDA_POWER_SAVE
12470#define alc262_loopbacks alc880_loopbacks
12471#endif
12472
def319f9 12473/* pcm configuration: identical with ALC880 */
df694daa
KY
12474#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12475#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12476#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12477#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12478
12479/*
12480 * BIOS auto configuration
12481 */
12482static int alc262_parse_auto_config(struct hda_codec *codec)
12483{
12484 struct alc_spec *spec = codec->spec;
12485 int err;
12486 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12487
f12ab1e0
TI
12488 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12489 alc262_ignore);
12490 if (err < 0)
df694daa 12491 return err;
e64f14f4 12492 if (!spec->autocfg.line_outs) {
0852d7a6 12493 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12494 spec->multiout.max_channels = 2;
12495 spec->no_analog = 1;
12496 goto dig_only;
12497 }
df694daa 12498 return 0; /* can't find valid BIOS pin config */
e64f14f4 12499 }
f12ab1e0
TI
12500 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12501 if (err < 0)
12502 return err;
05f5f477 12503 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12504 if (err < 0)
df694daa
KY
12505 return err;
12506
12507 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12508
e64f14f4 12509 dig_only:
757899ac 12510 alc_auto_parse_digital(codec);
df694daa 12511
603c4019 12512 if (spec->kctls.list)
d88897ea 12513 add_mixer(spec, spec->kctls.list);
df694daa 12514
d88897ea 12515 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12516 spec->num_mux_defs = 1;
61b9b9b1 12517 spec->input_mux = &spec->private_imux[0];
df694daa 12518
776e184e
TI
12519 err = alc_auto_add_mic_boost(codec);
12520 if (err < 0)
12521 return err;
12522
6227cdce 12523 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12524
df694daa
KY
12525 return 1;
12526}
12527
12528#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12529#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12530#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12531#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12532
12533
12534/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12535static void alc262_auto_init(struct hda_codec *codec)
df694daa 12536{
f6c7e546 12537 struct alc_spec *spec = codec->spec;
df694daa
KY
12538 alc262_auto_init_multi_out(codec);
12539 alc262_auto_init_hp_out(codec);
12540 alc262_auto_init_analog_input(codec);
f511b01c 12541 alc262_auto_init_input_src(codec);
757899ac 12542 alc_auto_init_digital(codec);
f6c7e546 12543 if (spec->unsol_event)
7fb0d78f 12544 alc_inithook(codec);
df694daa
KY
12545}
12546
12547/*
12548 * configuration and preset
12549 */
f5fcc13c
TI
12550static const char *alc262_models[ALC262_MODEL_LAST] = {
12551 [ALC262_BASIC] = "basic",
12552 [ALC262_HIPPO] = "hippo",
12553 [ALC262_HIPPO_1] = "hippo_1",
12554 [ALC262_FUJITSU] = "fujitsu",
12555 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12556 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12557 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12558 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12559 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12560 [ALC262_BENQ_T31] = "benq-t31",
12561 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12562 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12563 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12564 [ALC262_ULTRA] = "ultra",
0e31daf7 12565 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12566 [ALC262_NEC] = "nec",
ba340e82 12567 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12568 [ALC262_AUTO] = "auto",
12569};
12570
12571static struct snd_pci_quirk alc262_cfg_tbl[] = {
12572 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12573 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12574 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12575 ALC262_HP_BPC),
12576 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12577 ALC262_HP_BPC),
53eff7e1
TI
12578 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12579 ALC262_HP_BPC),
cd7509a4 12580 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12581 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12582 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12583 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12584 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12585 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12586 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12587 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12588 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12589 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12590 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12591 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12592 ALC262_HP_TC_T5735),
8c427226 12593 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12594 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12595 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12596 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12597 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12598 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12599 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12600 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12601#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12602 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12603 ALC262_SONY_ASSAMD),
c5b5165c 12604#endif
36ca6e13 12605 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12606 ALC262_TOSHIBA_RX1),
80ffe869 12607 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12608 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12609 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12610 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12611 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12612 ALC262_ULTRA),
3e420e78 12613 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12614 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12615 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12616 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12617 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12618 {}
12619};
12620
12621static struct alc_config_preset alc262_presets[] = {
12622 [ALC262_BASIC] = {
12623 .mixers = { alc262_base_mixer },
12624 .init_verbs = { alc262_init_verbs },
12625 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12626 .dac_nids = alc262_dac_nids,
12627 .hp_nid = 0x03,
12628 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12629 .channel_mode = alc262_modes,
a3bcba38 12630 .input_mux = &alc262_capture_source,
df694daa 12631 },
ccc656ce 12632 [ALC262_HIPPO] = {
42171c17 12633 .mixers = { alc262_hippo_mixer },
6732bd0d 12634 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12635 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12636 .dac_nids = alc262_dac_nids,
12637 .hp_nid = 0x03,
12638 .dig_out_nid = ALC262_DIGOUT_NID,
12639 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12640 .channel_mode = alc262_modes,
12641 .input_mux = &alc262_capture_source,
12642 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12643 .setup = alc262_hippo_setup,
12644 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12645 },
12646 [ALC262_HIPPO_1] = {
12647 .mixers = { alc262_hippo1_mixer },
12648 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12649 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12650 .dac_nids = alc262_dac_nids,
12651 .hp_nid = 0x02,
12652 .dig_out_nid = ALC262_DIGOUT_NID,
12653 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12654 .channel_mode = alc262_modes,
12655 .input_mux = &alc262_capture_source,
42171c17 12656 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12657 .setup = alc262_hippo1_setup,
12658 .init_hook = alc262_hippo_automute,
ccc656ce 12659 },
834be88d
TI
12660 [ALC262_FUJITSU] = {
12661 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12662 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12663 alc262_fujitsu_unsol_verbs },
834be88d
TI
12664 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12665 .dac_nids = alc262_dac_nids,
12666 .hp_nid = 0x03,
12667 .dig_out_nid = ALC262_DIGOUT_NID,
12668 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12669 .channel_mode = alc262_modes,
12670 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12671 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12672 .init_hook = alc262_fujitsu_init_hook,
834be88d 12673 },
9c7f852e
TI
12674 [ALC262_HP_BPC] = {
12675 .mixers = { alc262_HP_BPC_mixer },
12676 .init_verbs = { alc262_HP_BPC_init_verbs },
12677 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12678 .dac_nids = alc262_dac_nids,
12679 .hp_nid = 0x03,
12680 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12681 .channel_mode = alc262_modes,
12682 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12683 .unsol_event = alc262_hp_bpc_unsol_event,
12684 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12685 },
cd7509a4
KY
12686 [ALC262_HP_BPC_D7000_WF] = {
12687 .mixers = { alc262_HP_BPC_WildWest_mixer },
12688 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12689 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12690 .dac_nids = alc262_dac_nids,
12691 .hp_nid = 0x03,
12692 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12693 .channel_mode = alc262_modes,
accbe498 12694 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12695 .unsol_event = alc262_hp_wildwest_unsol_event,
12696 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12697 },
cd7509a4
KY
12698 [ALC262_HP_BPC_D7000_WL] = {
12699 .mixers = { alc262_HP_BPC_WildWest_mixer,
12700 alc262_HP_BPC_WildWest_option_mixer },
12701 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12702 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12703 .dac_nids = alc262_dac_nids,
12704 .hp_nid = 0x03,
12705 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12706 .channel_mode = alc262_modes,
accbe498 12707 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12708 .unsol_event = alc262_hp_wildwest_unsol_event,
12709 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12710 },
66d2a9d6
KY
12711 [ALC262_HP_TC_T5735] = {
12712 .mixers = { alc262_hp_t5735_mixer },
12713 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12714 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12715 .dac_nids = alc262_dac_nids,
12716 .hp_nid = 0x03,
12717 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12718 .channel_mode = alc262_modes,
12719 .input_mux = &alc262_capture_source,
dc99be47 12720 .unsol_event = alc_sku_unsol_event,
4f5d1706 12721 .setup = alc262_hp_t5735_setup,
dc99be47 12722 .init_hook = alc_inithook,
8c427226
KY
12723 },
12724 [ALC262_HP_RP5700] = {
12725 .mixers = { alc262_hp_rp5700_mixer },
12726 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12727 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12728 .dac_nids = alc262_dac_nids,
12729 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12730 .channel_mode = alc262_modes,
12731 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12732 },
304dcaac
TI
12733 [ALC262_BENQ_ED8] = {
12734 .mixers = { alc262_base_mixer },
12735 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12736 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12737 .dac_nids = alc262_dac_nids,
12738 .hp_nid = 0x03,
12739 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12740 .channel_mode = alc262_modes,
12741 .input_mux = &alc262_capture_source,
f12ab1e0 12742 },
272a527c
KY
12743 [ALC262_SONY_ASSAMD] = {
12744 .mixers = { alc262_sony_mixer },
12745 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12746 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12747 .dac_nids = alc262_dac_nids,
12748 .hp_nid = 0x02,
12749 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12750 .channel_mode = alc262_modes,
12751 .input_mux = &alc262_capture_source,
12752 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12753 .setup = alc262_hippo_setup,
12754 .init_hook = alc262_hippo_automute,
83c34218
KY
12755 },
12756 [ALC262_BENQ_T31] = {
12757 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12758 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12759 alc_hp15_unsol_verbs },
83c34218
KY
12760 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12761 .dac_nids = alc262_dac_nids,
12762 .hp_nid = 0x03,
12763 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12764 .channel_mode = alc262_modes,
12765 .input_mux = &alc262_capture_source,
12766 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12767 .setup = alc262_hippo_setup,
12768 .init_hook = alc262_hippo_automute,
ea1fb29a 12769 },
f651b50b 12770 [ALC262_ULTRA] = {
f9e336f6
TI
12771 .mixers = { alc262_ultra_mixer },
12772 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12773 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12774 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12775 .dac_nids = alc262_dac_nids,
f651b50b
TD
12776 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12777 .channel_mode = alc262_modes,
12778 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12779 .adc_nids = alc262_adc_nids, /* ADC0 */
12780 .capsrc_nids = alc262_capsrc_nids,
12781 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12782 .unsol_event = alc262_ultra_unsol_event,
12783 .init_hook = alc262_ultra_automute,
12784 },
0e31daf7
J
12785 [ALC262_LENOVO_3000] = {
12786 .mixers = { alc262_lenovo_3000_mixer },
12787 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12788 alc262_lenovo_3000_unsol_verbs,
12789 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12790 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12791 .dac_nids = alc262_dac_nids,
12792 .hp_nid = 0x03,
12793 .dig_out_nid = ALC262_DIGOUT_NID,
12794 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12795 .channel_mode = alc262_modes,
12796 .input_mux = &alc262_fujitsu_capture_source,
12797 .unsol_event = alc262_lenovo_3000_unsol_event,
12798 },
e8f9ae2a
PT
12799 [ALC262_NEC] = {
12800 .mixers = { alc262_nec_mixer },
12801 .init_verbs = { alc262_nec_verbs },
12802 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12803 .dac_nids = alc262_dac_nids,
12804 .hp_nid = 0x03,
12805 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12806 .channel_mode = alc262_modes,
12807 .input_mux = &alc262_capture_source,
12808 },
4e555fe5
KY
12809 [ALC262_TOSHIBA_S06] = {
12810 .mixers = { alc262_toshiba_s06_mixer },
12811 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12812 alc262_eapd_verbs },
12813 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12814 .capsrc_nids = alc262_dmic_capsrc_nids,
12815 .dac_nids = alc262_dac_nids,
12816 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12817 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12818 .dig_out_nid = ALC262_DIGOUT_NID,
12819 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12820 .channel_mode = alc262_modes,
4f5d1706
TI
12821 .unsol_event = alc_sku_unsol_event,
12822 .setup = alc262_toshiba_s06_setup,
12823 .init_hook = alc_inithook,
4e555fe5 12824 },
9f99a638
HM
12825 [ALC262_TOSHIBA_RX1] = {
12826 .mixers = { alc262_toshiba_rx1_mixer },
12827 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12828 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12829 .dac_nids = alc262_dac_nids,
12830 .hp_nid = 0x03,
12831 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12832 .channel_mode = alc262_modes,
12833 .input_mux = &alc262_capture_source,
12834 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12835 .setup = alc262_hippo_setup,
12836 .init_hook = alc262_hippo_automute,
9f99a638 12837 },
ba340e82
TV
12838 [ALC262_TYAN] = {
12839 .mixers = { alc262_tyan_mixer },
12840 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12841 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12842 .dac_nids = alc262_dac_nids,
12843 .hp_nid = 0x02,
12844 .dig_out_nid = ALC262_DIGOUT_NID,
12845 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12846 .channel_mode = alc262_modes,
12847 .input_mux = &alc262_capture_source,
a9fd4f3f 12848 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12849 .setup = alc262_tyan_setup,
12850 .init_hook = alc_automute_amp,
ba340e82 12851 },
df694daa
KY
12852};
12853
12854static int patch_alc262(struct hda_codec *codec)
12855{
12856 struct alc_spec *spec;
12857 int board_config;
12858 int err;
12859
dc041e0b 12860 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12861 if (spec == NULL)
12862 return -ENOMEM;
12863
12864 codec->spec = spec;
12865#if 0
f12ab1e0
TI
12866 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12867 * under-run
12868 */
df694daa
KY
12869 {
12870 int tmp;
12871 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12872 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12873 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12874 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12875 }
12876#endif
da00c244 12877 alc_auto_parse_customize_define(codec);
df694daa 12878
2c3bf9ab
TI
12879 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12880
f5fcc13c
TI
12881 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12882 alc262_models,
12883 alc262_cfg_tbl);
cd7509a4 12884
f5fcc13c 12885 if (board_config < 0) {
9a11f1aa
TI
12886 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12887 codec->chip_name);
df694daa
KY
12888 board_config = ALC262_AUTO;
12889 }
12890
18675e42
TI
12891 if (board_config == ALC262_AUTO)
12892 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1);
12893
df694daa
KY
12894 if (board_config == ALC262_AUTO) {
12895 /* automatic parse from the BIOS config */
12896 err = alc262_parse_auto_config(codec);
12897 if (err < 0) {
12898 alc_free(codec);
12899 return err;
f12ab1e0 12900 } else if (!err) {
9c7f852e
TI
12901 printk(KERN_INFO
12902 "hda_codec: Cannot set up configuration "
12903 "from BIOS. Using base mode...\n");
df694daa
KY
12904 board_config = ALC262_BASIC;
12905 }
12906 }
12907
dc1eae25 12908 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12909 err = snd_hda_attach_beep_device(codec, 0x1);
12910 if (err < 0) {
12911 alc_free(codec);
12912 return err;
12913 }
680cd536
KK
12914 }
12915
df694daa 12916 if (board_config != ALC262_AUTO)
e9c364c0 12917 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12918
df694daa
KY
12919 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12920 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12921
df694daa
KY
12922 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12923 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12924
f12ab1e0 12925 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12926 int i;
12927 /* check whether the digital-mic has to be supported */
12928 for (i = 0; i < spec->input_mux->num_items; i++) {
12929 if (spec->input_mux->items[i].index >= 9)
12930 break;
12931 }
12932 if (i < spec->input_mux->num_items) {
12933 /* use only ADC0 */
12934 spec->adc_nids = alc262_dmic_adc_nids;
12935 spec->num_adc_nids = 1;
12936 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12937 } else {
8c927b4a
TI
12938 /* all analog inputs */
12939 /* check whether NID 0x07 is valid */
12940 unsigned int wcap = get_wcaps(codec, 0x07);
12941
12942 /* get type */
a22d543a 12943 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12944 if (wcap != AC_WID_AUD_IN) {
12945 spec->adc_nids = alc262_adc_nids_alt;
12946 spec->num_adc_nids =
12947 ARRAY_SIZE(alc262_adc_nids_alt);
12948 spec->capsrc_nids = alc262_capsrc_nids_alt;
12949 } else {
12950 spec->adc_nids = alc262_adc_nids;
12951 spec->num_adc_nids =
12952 ARRAY_SIZE(alc262_adc_nids);
12953 spec->capsrc_nids = alc262_capsrc_nids;
12954 }
df694daa
KY
12955 }
12956 }
e64f14f4 12957 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12958 set_capture_mixer(codec);
dc1eae25 12959 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12960 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12961
18675e42
TI
12962 if (board_config == ALC262_AUTO)
12963 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0);
12964
2134ea4f
TI
12965 spec->vmaster_nid = 0x0c;
12966
df694daa
KY
12967 codec->patch_ops = alc_patch_ops;
12968 if (board_config == ALC262_AUTO)
ae6b813a 12969 spec->init_hook = alc262_auto_init;
bf1b0225
KY
12970
12971 alc_init_jacks(codec);
cb53c626
TI
12972#ifdef CONFIG_SND_HDA_POWER_SAVE
12973 if (!spec->loopback.amplist)
12974 spec->loopback.amplist = alc262_loopbacks;
12975#endif
ea1fb29a 12976
df694daa
KY
12977 return 0;
12978}
12979
a361d84b
KY
12980/*
12981 * ALC268 channel source setting (2 channel)
12982 */
12983#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12984#define alc268_modes alc260_modes
ea1fb29a 12985
a361d84b
KY
12986static hda_nid_t alc268_dac_nids[2] = {
12987 /* front, hp */
12988 0x02, 0x03
12989};
12990
12991static hda_nid_t alc268_adc_nids[2] = {
12992 /* ADC0-1 */
12993 0x08, 0x07
12994};
12995
12996static hda_nid_t alc268_adc_nids_alt[1] = {
12997 /* ADC0 */
12998 0x08
12999};
13000
e1406348
TI
13001static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13002
a361d84b
KY
13003static struct snd_kcontrol_new alc268_base_mixer[] = {
13004 /* output mixer control */
13005 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13006 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13007 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13008 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13009 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13010 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13011 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13012 { }
13013};
13014
42171c17
TI
13015static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13016 /* output mixer control */
13017 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13018 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13019 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13020 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13021 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13022 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13023 { }
13024};
13025
aef9d318
TI
13026/* bind Beep switches of both NID 0x0f and 0x10 */
13027static struct hda_bind_ctls alc268_bind_beep_sw = {
13028 .ops = &snd_hda_bind_sw,
13029 .values = {
13030 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13031 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13032 0
13033 },
13034};
13035
13036static struct snd_kcontrol_new alc268_beep_mixer[] = {
13037 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13038 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13039 { }
13040};
13041
d1a991a6
KY
13042static struct hda_verb alc268_eapd_verbs[] = {
13043 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13044 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13045 { }
13046};
13047
d273809e 13048/* Toshiba specific */
d273809e
TI
13049static struct hda_verb alc268_toshiba_verbs[] = {
13050 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13051 { } /* end */
13052};
13053
13054/* Acer specific */
889c4395 13055/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13056static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13057 .ops = &snd_hda_bind_vol,
13058 .values = {
13059 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13060 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13061 0
13062 },
13063};
13064
889c4395
TI
13065/* mute/unmute internal speaker according to the hp jack and mute state */
13066static void alc268_acer_automute(struct hda_codec *codec, int force)
13067{
13068 struct alc_spec *spec = codec->spec;
13069 unsigned int mute;
13070
13071 if (force || !spec->sense_updated) {
864f92be 13072 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
13073 spec->sense_updated = 1;
13074 }
13075 if (spec->jack_present)
13076 mute = HDA_AMP_MUTE; /* mute internal speaker */
13077 else /* unmute internal speaker if necessary */
13078 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13079 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13080 HDA_AMP_MUTE, mute);
13081}
13082
13083
13084/* bind hp and internal speaker mute (with plug check) */
13085static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13086 struct snd_ctl_elem_value *ucontrol)
13087{
13088 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13089 long *valp = ucontrol->value.integer.value;
13090 int change;
13091
8de56b7d 13092 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13093 if (change)
13094 alc268_acer_automute(codec, 0);
13095 return change;
13096}
d273809e 13097
8ef355da
KY
13098static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13099 /* output mixer control */
13100 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13101 {
13102 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13103 .name = "Master Playback Switch",
5e26dfd0 13104 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13105 .info = snd_hda_mixer_amp_switch_info,
13106 .get = snd_hda_mixer_amp_switch_get,
13107 .put = alc268_acer_master_sw_put,
13108 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13109 },
13110 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13111 { }
13112};
13113
d273809e
TI
13114static struct snd_kcontrol_new alc268_acer_mixer[] = {
13115 /* output mixer control */
13116 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13117 {
13118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13119 .name = "Master Playback Switch",
5e26dfd0 13120 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13121 .info = snd_hda_mixer_amp_switch_info,
13122 .get = snd_hda_mixer_amp_switch_get,
13123 .put = alc268_acer_master_sw_put,
13124 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13125 },
5f99f86a
DH
13126 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13127 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13128 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13129 { }
13130};
13131
c238b4f4
TI
13132static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13133 /* output mixer control */
13134 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13135 {
13136 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13137 .name = "Master Playback Switch",
5e26dfd0 13138 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13139 .info = snd_hda_mixer_amp_switch_info,
13140 .get = snd_hda_mixer_amp_switch_get,
13141 .put = alc268_acer_master_sw_put,
13142 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13143 },
5f99f86a
DH
13144 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13145 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13146 { }
13147};
13148
8ef355da
KY
13149static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13150 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13151 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13152 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13153 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13154 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13155 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13156 { }
13157};
13158
d273809e 13159static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13160 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13161 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13162 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13163 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13164 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13165 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13166 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13167 { }
13168};
13169
13170/* unsolicited event for HP jack sensing */
42171c17 13171#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13172#define alc268_toshiba_setup alc262_hippo_setup
13173#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13174
13175static void alc268_acer_unsol_event(struct hda_codec *codec,
13176 unsigned int res)
13177{
889c4395 13178 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13179 return;
13180 alc268_acer_automute(codec, 1);
13181}
13182
889c4395
TI
13183static void alc268_acer_init_hook(struct hda_codec *codec)
13184{
13185 alc268_acer_automute(codec, 1);
13186}
13187
8ef355da
KY
13188/* toggle speaker-output according to the hp-jack state */
13189static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13190{
13191 unsigned int present;
13192 unsigned char bits;
13193
864f92be 13194 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13195 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13196 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13197 HDA_AMP_MUTE, bits);
8ef355da 13198 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13199 HDA_AMP_MUTE, bits);
8ef355da
KY
13200}
13201
8ef355da
KY
13202static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13203 unsigned int res)
13204{
4f5d1706
TI
13205 switch (res >> 26) {
13206 case ALC880_HP_EVENT:
8ef355da 13207 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13208 break;
13209 case ALC880_MIC_EVENT:
13210 alc_mic_automute(codec);
13211 break;
13212 }
13213}
13214
13215static void alc268_acer_lc_setup(struct hda_codec *codec)
13216{
13217 struct alc_spec *spec = codec->spec;
13218 spec->ext_mic.pin = 0x18;
13219 spec->ext_mic.mux_idx = 0;
13220 spec->int_mic.pin = 0x12;
13221 spec->int_mic.mux_idx = 6;
13222 spec->auto_mic = 1;
8ef355da
KY
13223}
13224
13225static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13226{
13227 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13228 alc_mic_automute(codec);
8ef355da
KY
13229}
13230
3866f0b0
TI
13231static struct snd_kcontrol_new alc268_dell_mixer[] = {
13232 /* output mixer control */
13233 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13234 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13235 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13236 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13237 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13238 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13239 { }
13240};
13241
13242static struct hda_verb alc268_dell_verbs[] = {
13243 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13244 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13245 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13246 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13247 { }
13248};
13249
13250/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13251static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13252{
a9fd4f3f 13253 struct alc_spec *spec = codec->spec;
3866f0b0 13254
a9fd4f3f
TI
13255 spec->autocfg.hp_pins[0] = 0x15;
13256 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13257 spec->ext_mic.pin = 0x18;
13258 spec->ext_mic.mux_idx = 0;
13259 spec->int_mic.pin = 0x19;
13260 spec->int_mic.mux_idx = 1;
13261 spec->auto_mic = 1;
3866f0b0
TI
13262}
13263
eb5a6621
HRK
13264static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13265 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13266 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13267 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13268 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13269 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13270 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13271 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13272 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13273 { }
13274};
13275
13276static struct hda_verb alc267_quanta_il1_verbs[] = {
13277 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13278 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13279 { }
13280};
13281
4f5d1706 13282static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13283{
a9fd4f3f 13284 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13285 spec->autocfg.hp_pins[0] = 0x15;
13286 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13287 spec->ext_mic.pin = 0x18;
13288 spec->ext_mic.mux_idx = 0;
13289 spec->int_mic.pin = 0x19;
13290 spec->int_mic.mux_idx = 1;
13291 spec->auto_mic = 1;
eb5a6621
HRK
13292}
13293
a361d84b
KY
13294/*
13295 * generic initialization of ADC, input mixers and output mixers
13296 */
13297static struct hda_verb alc268_base_init_verbs[] = {
13298 /* Unmute DAC0-1 and set vol = 0 */
13299 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13300 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13301
13302 /*
13303 * Set up output mixers (0x0c - 0x0e)
13304 */
13305 /* set vol=0 to output mixers */
13306 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13307 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13308
13309 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13310 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13311
13312 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13313 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13314 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13315 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13316 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13317 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13318 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13319 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13320
13321 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13322 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13323 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13324 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13325 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13326
13327 /* set PCBEEP vol = 0, mute connections */
13328 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13329 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13330 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13331
a9b3aa8a 13332 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13333
a9b3aa8a
JZ
13334 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13335 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13336 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13337 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13338
a361d84b
KY
13339 { }
13340};
13341
13342/*
13343 * generic initialization of ADC, input mixers and output mixers
13344 */
13345static struct hda_verb alc268_volume_init_verbs[] = {
13346 /* set output DAC */
4cfb91c6
TI
13347 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13348 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13349
13350 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13351 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13352 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13353 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13354 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13355
a361d84b 13356 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13357 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13358 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13359
13360 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13361 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13362
aef9d318
TI
13363 /* set PCBEEP vol = 0, mute connections */
13364 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13365 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13366 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13367
13368 { }
13369};
13370
fdbc6626
TI
13371static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13372 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13373 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13374 { } /* end */
13375};
13376
a361d84b
KY
13377static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13378 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13379 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13380 _DEFINE_CAPSRC(1),
a361d84b
KY
13381 { } /* end */
13382};
13383
13384static struct snd_kcontrol_new alc268_capture_mixer[] = {
13385 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13386 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13387 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13388 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13389 _DEFINE_CAPSRC(2),
a361d84b
KY
13390 { } /* end */
13391};
13392
13393static struct hda_input_mux alc268_capture_source = {
13394 .num_items = 4,
13395 .items = {
13396 { "Mic", 0x0 },
13397 { "Front Mic", 0x1 },
13398 { "Line", 0x2 },
13399 { "CD", 0x3 },
13400 },
13401};
13402
0ccb541c 13403static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13404 .num_items = 3,
13405 .items = {
13406 { "Mic", 0x0 },
13407 { "Internal Mic", 0x1 },
13408 { "Line", 0x2 },
13409 },
13410};
13411
13412static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13413 .num_items = 3,
13414 .items = {
13415 { "Mic", 0x0 },
13416 { "Internal Mic", 0x6 },
13417 { "Line", 0x2 },
13418 },
13419};
13420
86c53bd2
JW
13421#ifdef CONFIG_SND_DEBUG
13422static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13423 /* Volume widgets */
13424 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13425 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13426 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13427 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13428 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13429 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13430 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13431 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13432 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13433 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13434 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13435 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13436 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13437 /* The below appears problematic on some hardwares */
13438 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13439 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13440 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13441 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13442 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13443
13444 /* Modes for retasking pin widgets */
13445 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13446 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13447 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13448 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13449
13450 /* Controls for GPIO pins, assuming they are configured as outputs */
13451 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13452 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13453 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13454 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13455
13456 /* Switches to allow the digital SPDIF output pin to be enabled.
13457 * The ALC268 does not have an SPDIF input.
13458 */
13459 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13460
13461 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13462 * this output to turn on an external amplifier.
13463 */
13464 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13465 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13466
13467 { } /* end */
13468};
13469#endif
13470
a361d84b
KY
13471/* create input playback/capture controls for the given pin */
13472static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13473 const char *ctlname, int idx)
13474{
3f3b7c1a 13475 hda_nid_t dac;
a361d84b
KY
13476 int err;
13477
3f3b7c1a
TI
13478 switch (nid) {
13479 case 0x14:
13480 case 0x16:
13481 dac = 0x02;
13482 break;
13483 case 0x15:
b08b1637
TI
13484 case 0x1a: /* ALC259/269 only */
13485 case 0x1b: /* ALC259/269 only */
531d8791 13486 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13487 dac = 0x03;
13488 break;
13489 default:
c7a9434d
TI
13490 snd_printd(KERN_WARNING "hda_codec: "
13491 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13492 return 0;
13493 }
13494 if (spec->multiout.dac_nids[0] != dac &&
13495 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13496 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13497 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13498 HDA_OUTPUT));
13499 if (err < 0)
13500 return err;
3f3b7c1a
TI
13501 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13502 }
13503
3f3b7c1a 13504 if (nid != 0x16)
0afe5f89 13505 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13506 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13507 else /* mono */
0afe5f89 13508 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13509 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13510 if (err < 0)
13511 return err;
13512 return 0;
13513}
13514
13515/* add playback controls from the parsed DAC table */
13516static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13517 const struct auto_pin_cfg *cfg)
13518{
13519 hda_nid_t nid;
13520 int err;
13521
a361d84b 13522 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13523
13524 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13525 if (nid) {
13526 const char *name;
13527 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13528 name = "Speaker";
13529 else
13530 name = "Front";
13531 err = alc268_new_analog_output(spec, nid, name, 0);
13532 if (err < 0)
13533 return err;
13534 }
a361d84b
KY
13535
13536 nid = cfg->speaker_pins[0];
13537 if (nid == 0x1d) {
0afe5f89 13538 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13539 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13540 if (err < 0)
13541 return err;
7bfb9c03 13542 } else if (nid) {
3f3b7c1a
TI
13543 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13544 if (err < 0)
13545 return err;
a361d84b
KY
13546 }
13547 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13548 if (nid) {
13549 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13550 if (err < 0)
13551 return err;
13552 }
a361d84b
KY
13553
13554 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13555 if (nid == 0x16) {
0afe5f89 13556 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13557 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13558 if (err < 0)
13559 return err;
13560 }
ea1fb29a 13561 return 0;
a361d84b
KY
13562}
13563
13564/* create playback/capture controls for input pins */
05f5f477 13565static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13566 const struct auto_pin_cfg *cfg)
13567{
05f5f477 13568 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13569}
13570
e9af4f36
TI
13571static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13572 hda_nid_t nid, int pin_type)
13573{
13574 int idx;
13575
13576 alc_set_pin_output(codec, nid, pin_type);
13577 if (nid == 0x14 || nid == 0x16)
13578 idx = 0;
13579 else
13580 idx = 1;
13581 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13582}
13583
13584static void alc268_auto_init_multi_out(struct hda_codec *codec)
13585{
13586 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13587 int i;
13588
13589 for (i = 0; i < spec->autocfg.line_outs; i++) {
13590 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13591 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13592 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13593 }
13594}
13595
13596static void alc268_auto_init_hp_out(struct hda_codec *codec)
13597{
13598 struct alc_spec *spec = codec->spec;
13599 hda_nid_t pin;
e1ca7b4e 13600 int i;
e9af4f36 13601
e1ca7b4e
TI
13602 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13603 pin = spec->autocfg.hp_pins[i];
e9af4f36 13604 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13605 }
13606 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13607 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13608 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13609 }
13610 if (spec->autocfg.mono_out_pin)
13611 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13612 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13613}
13614
a361d84b
KY
13615static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13616{
13617 struct alc_spec *spec = codec->spec;
13618 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13619 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13620 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13621 unsigned int dac_vol1, dac_vol2;
13622
e9af4f36 13623 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13624 snd_hda_codec_write(codec, speaker_nid, 0,
13625 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13626 /* mute mixer inputs from 0x1d */
a361d84b
KY
13627 snd_hda_codec_write(codec, 0x0f, 0,
13628 AC_VERB_SET_AMP_GAIN_MUTE,
13629 AMP_IN_UNMUTE(1));
13630 snd_hda_codec_write(codec, 0x10, 0,
13631 AC_VERB_SET_AMP_GAIN_MUTE,
13632 AMP_IN_UNMUTE(1));
13633 } else {
e9af4f36 13634 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13635 snd_hda_codec_write(codec, 0x0f, 0,
13636 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13637 snd_hda_codec_write(codec, 0x10, 0,
13638 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13639 }
13640
13641 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13642 if (line_nid == 0x14)
a361d84b
KY
13643 dac_vol2 = AMP_OUT_ZERO;
13644 else if (line_nid == 0x15)
13645 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13646 if (hp_nid == 0x14)
a361d84b
KY
13647 dac_vol2 = AMP_OUT_ZERO;
13648 else if (hp_nid == 0x15)
13649 dac_vol1 = AMP_OUT_ZERO;
13650 if (line_nid != 0x16 || hp_nid != 0x16 ||
13651 spec->autocfg.line_out_pins[1] != 0x16 ||
13652 spec->autocfg.line_out_pins[2] != 0x16)
13653 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13654
13655 snd_hda_codec_write(codec, 0x02, 0,
13656 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13657 snd_hda_codec_write(codec, 0x03, 0,
13658 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13659}
13660
def319f9 13661/* pcm configuration: identical with ALC880 */
a361d84b
KY
13662#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13663#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13664#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13665#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13666
13667/*
13668 * BIOS auto configuration
13669 */
13670static int alc268_parse_auto_config(struct hda_codec *codec)
13671{
13672 struct alc_spec *spec = codec->spec;
13673 int err;
13674 static hda_nid_t alc268_ignore[] = { 0 };
13675
13676 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13677 alc268_ignore);
13678 if (err < 0)
13679 return err;
7e0e44d4
TI
13680 if (!spec->autocfg.line_outs) {
13681 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13682 spec->multiout.max_channels = 2;
13683 spec->no_analog = 1;
13684 goto dig_only;
13685 }
a361d84b 13686 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13687 }
a361d84b
KY
13688 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13689 if (err < 0)
13690 return err;
05f5f477 13691 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13692 if (err < 0)
13693 return err;
13694
13695 spec->multiout.max_channels = 2;
13696
7e0e44d4 13697 dig_only:
a361d84b 13698 /* digital only support output */
757899ac 13699 alc_auto_parse_digital(codec);
603c4019 13700 if (spec->kctls.list)
d88897ea 13701 add_mixer(spec, spec->kctls.list);
a361d84b 13702
892981ff 13703 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13704 add_mixer(spec, alc268_beep_mixer);
aef9d318 13705
d88897ea 13706 add_verb(spec, alc268_volume_init_verbs);
5908589f 13707 spec->num_mux_defs = 2;
61b9b9b1 13708 spec->input_mux = &spec->private_imux[0];
a361d84b 13709
776e184e
TI
13710 err = alc_auto_add_mic_boost(codec);
13711 if (err < 0)
13712 return err;
13713
6227cdce 13714 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13715
a361d84b
KY
13716 return 1;
13717}
13718
a361d84b
KY
13719#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13720
13721/* init callback for auto-configuration model -- overriding the default init */
13722static void alc268_auto_init(struct hda_codec *codec)
13723{
f6c7e546 13724 struct alc_spec *spec = codec->spec;
a361d84b
KY
13725 alc268_auto_init_multi_out(codec);
13726 alc268_auto_init_hp_out(codec);
13727 alc268_auto_init_mono_speaker_out(codec);
13728 alc268_auto_init_analog_input(codec);
757899ac 13729 alc_auto_init_digital(codec);
f6c7e546 13730 if (spec->unsol_event)
7fb0d78f 13731 alc_inithook(codec);
a361d84b
KY
13732}
13733
13734/*
13735 * configuration and preset
13736 */
13737static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13738 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13739 [ALC268_3ST] = "3stack",
983f8ae4 13740 [ALC268_TOSHIBA] = "toshiba",
d273809e 13741 [ALC268_ACER] = "acer",
c238b4f4 13742 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13743 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13744 [ALC268_DELL] = "dell",
f12462c5 13745 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13746#ifdef CONFIG_SND_DEBUG
13747 [ALC268_TEST] = "test",
13748#endif
a361d84b
KY
13749 [ALC268_AUTO] = "auto",
13750};
13751
13752static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13753 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13754 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13755 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13756 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13757 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13758 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13759 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13760 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13761 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13762 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13763 /* almost compatible with toshiba but with optional digital outs;
13764 * auto-probing seems working fine
13765 */
8871e5b9 13766 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13767 ALC268_AUTO),
a361d84b 13768 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13769 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13770 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13771 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13772 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13773 {}
13774};
13775
3abf2f36
TI
13776/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13777static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13778 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13779 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13780 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13781 ALC268_TOSHIBA),
13782 {}
13783};
13784
a361d84b 13785static struct alc_config_preset alc268_presets[] = {
eb5a6621 13786 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13787 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13788 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13789 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13790 alc267_quanta_il1_verbs },
13791 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13792 .dac_nids = alc268_dac_nids,
13793 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13794 .adc_nids = alc268_adc_nids_alt,
13795 .hp_nid = 0x03,
13796 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13797 .channel_mode = alc268_modes,
4f5d1706
TI
13798 .unsol_event = alc_sku_unsol_event,
13799 .setup = alc267_quanta_il1_setup,
13800 .init_hook = alc_inithook,
eb5a6621 13801 },
a361d84b 13802 [ALC268_3ST] = {
aef9d318
TI
13803 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13804 alc268_beep_mixer },
a361d84b
KY
13805 .init_verbs = { alc268_base_init_verbs },
13806 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13807 .dac_nids = alc268_dac_nids,
13808 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13809 .adc_nids = alc268_adc_nids_alt,
e1406348 13810 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13811 .hp_nid = 0x03,
13812 .dig_out_nid = ALC268_DIGOUT_NID,
13813 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13814 .channel_mode = alc268_modes,
13815 .input_mux = &alc268_capture_source,
13816 },
d1a991a6 13817 [ALC268_TOSHIBA] = {
42171c17 13818 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13819 alc268_beep_mixer },
d273809e
TI
13820 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13821 alc268_toshiba_verbs },
d1a991a6
KY
13822 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13823 .dac_nids = alc268_dac_nids,
13824 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13825 .adc_nids = alc268_adc_nids_alt,
e1406348 13826 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13827 .hp_nid = 0x03,
13828 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13829 .channel_mode = alc268_modes,
13830 .input_mux = &alc268_capture_source,
d273809e 13831 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13832 .setup = alc268_toshiba_setup,
13833 .init_hook = alc268_toshiba_automute,
d273809e
TI
13834 },
13835 [ALC268_ACER] = {
432fd133 13836 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13837 alc268_beep_mixer },
d273809e
TI
13838 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13839 alc268_acer_verbs },
13840 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13841 .dac_nids = alc268_dac_nids,
13842 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13843 .adc_nids = alc268_adc_nids_alt,
e1406348 13844 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13845 .hp_nid = 0x02,
13846 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13847 .channel_mode = alc268_modes,
0ccb541c 13848 .input_mux = &alc268_acer_capture_source,
d273809e 13849 .unsol_event = alc268_acer_unsol_event,
889c4395 13850 .init_hook = alc268_acer_init_hook,
d1a991a6 13851 },
c238b4f4
TI
13852 [ALC268_ACER_DMIC] = {
13853 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13854 alc268_beep_mixer },
13855 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13856 alc268_acer_verbs },
13857 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13858 .dac_nids = alc268_dac_nids,
13859 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13860 .adc_nids = alc268_adc_nids_alt,
13861 .capsrc_nids = alc268_capsrc_nids,
13862 .hp_nid = 0x02,
13863 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13864 .channel_mode = alc268_modes,
13865 .input_mux = &alc268_acer_dmic_capture_source,
13866 .unsol_event = alc268_acer_unsol_event,
13867 .init_hook = alc268_acer_init_hook,
13868 },
8ef355da
KY
13869 [ALC268_ACER_ASPIRE_ONE] = {
13870 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13871 alc268_beep_mixer,
fdbc6626 13872 alc268_capture_nosrc_mixer },
8ef355da
KY
13873 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13874 alc268_acer_aspire_one_verbs },
13875 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13876 .dac_nids = alc268_dac_nids,
13877 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13878 .adc_nids = alc268_adc_nids_alt,
13879 .capsrc_nids = alc268_capsrc_nids,
13880 .hp_nid = 0x03,
13881 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13882 .channel_mode = alc268_modes,
8ef355da 13883 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13884 .setup = alc268_acer_lc_setup,
8ef355da
KY
13885 .init_hook = alc268_acer_lc_init_hook,
13886 },
3866f0b0 13887 [ALC268_DELL] = {
fdbc6626
TI
13888 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13889 alc268_capture_nosrc_mixer },
3866f0b0
TI
13890 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13891 alc268_dell_verbs },
13892 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13893 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13894 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13895 .adc_nids = alc268_adc_nids_alt,
13896 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13897 .hp_nid = 0x02,
13898 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13899 .channel_mode = alc268_modes,
a9fd4f3f 13900 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13901 .setup = alc268_dell_setup,
13902 .init_hook = alc_inithook,
3866f0b0 13903 },
f12462c5 13904 [ALC268_ZEPTO] = {
aef9d318
TI
13905 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13906 alc268_beep_mixer },
f12462c5
MT
13907 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13908 alc268_toshiba_verbs },
13909 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13910 .dac_nids = alc268_dac_nids,
13911 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13912 .adc_nids = alc268_adc_nids_alt,
e1406348 13913 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13914 .hp_nid = 0x03,
13915 .dig_out_nid = ALC268_DIGOUT_NID,
13916 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13917 .channel_mode = alc268_modes,
13918 .input_mux = &alc268_capture_source,
4f5d1706
TI
13919 .setup = alc268_toshiba_setup,
13920 .init_hook = alc268_toshiba_automute,
f12462c5 13921 },
86c53bd2
JW
13922#ifdef CONFIG_SND_DEBUG
13923 [ALC268_TEST] = {
13924 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13925 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13926 alc268_volume_init_verbs },
13927 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13928 .dac_nids = alc268_dac_nids,
13929 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13930 .adc_nids = alc268_adc_nids_alt,
e1406348 13931 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13932 .hp_nid = 0x03,
13933 .dig_out_nid = ALC268_DIGOUT_NID,
13934 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13935 .channel_mode = alc268_modes,
13936 .input_mux = &alc268_capture_source,
13937 },
13938#endif
a361d84b
KY
13939};
13940
13941static int patch_alc268(struct hda_codec *codec)
13942{
13943 struct alc_spec *spec;
13944 int board_config;
22971e3a 13945 int i, has_beep, err;
a361d84b 13946
ef86f581 13947 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13948 if (spec == NULL)
13949 return -ENOMEM;
13950
13951 codec->spec = spec;
13952
13953 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13954 alc268_models,
13955 alc268_cfg_tbl);
13956
3abf2f36
TI
13957 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13958 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13959 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13960
a361d84b 13961 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13962 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13963 codec->chip_name);
a361d84b
KY
13964 board_config = ALC268_AUTO;
13965 }
13966
13967 if (board_config == ALC268_AUTO) {
13968 /* automatic parse from the BIOS config */
13969 err = alc268_parse_auto_config(codec);
13970 if (err < 0) {
13971 alc_free(codec);
13972 return err;
13973 } else if (!err) {
13974 printk(KERN_INFO
13975 "hda_codec: Cannot set up configuration "
13976 "from BIOS. Using base mode...\n");
13977 board_config = ALC268_3ST;
13978 }
13979 }
13980
13981 if (board_config != ALC268_AUTO)
e9c364c0 13982 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13983
a361d84b
KY
13984 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13985 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13986 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13987
a361d84b
KY
13988 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13989
22971e3a
TI
13990 has_beep = 0;
13991 for (i = 0; i < spec->num_mixers; i++) {
13992 if (spec->mixers[i] == alc268_beep_mixer) {
13993 has_beep = 1;
13994 break;
13995 }
13996 }
13997
13998 if (has_beep) {
13999 err = snd_hda_attach_beep_device(codec, 0x1);
14000 if (err < 0) {
14001 alc_free(codec);
14002 return err;
14003 }
14004 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14005 /* override the amp caps for beep generator */
14006 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14007 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14008 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14009 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14010 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14011 }
aef9d318 14012
7e0e44d4 14013 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14014 /* check whether NID 0x07 is valid */
14015 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 14016 int i;
3866f0b0 14017
defb5ab2 14018 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14019 /* get type */
a22d543a 14020 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14021 if (spec->auto_mic ||
14022 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14023 spec->adc_nids = alc268_adc_nids_alt;
14024 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14025 if (spec->auto_mic)
14026 fixup_automic_adc(codec);
fdbc6626
TI
14027 if (spec->auto_mic || spec->input_mux->num_items == 1)
14028 add_mixer(spec, alc268_capture_nosrc_mixer);
14029 else
14030 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14031 } else {
14032 spec->adc_nids = alc268_adc_nids;
14033 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14034 add_mixer(spec, alc268_capture_mixer);
a361d84b 14035 }
85860c06
TI
14036 /* set default input source */
14037 for (i = 0; i < spec->num_adc_nids; i++)
14038 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14039 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
14040 i < spec->num_mux_defs ?
14041 spec->input_mux[i].items[0].index :
85860c06 14042 spec->input_mux->items[0].index);
a361d84b 14043 }
2134ea4f
TI
14044
14045 spec->vmaster_nid = 0x02;
14046
a361d84b
KY
14047 codec->patch_ops = alc_patch_ops;
14048 if (board_config == ALC268_AUTO)
14049 spec->init_hook = alc268_auto_init;
ea1fb29a 14050
bf1b0225
KY
14051 alc_init_jacks(codec);
14052
a361d84b
KY
14053 return 0;
14054}
14055
f6a92248
KY
14056/*
14057 * ALC269 channel source setting (2 channel)
14058 */
14059#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14060
14061#define alc269_dac_nids alc260_dac_nids
14062
14063static hda_nid_t alc269_adc_nids[1] = {
14064 /* ADC1 */
f53281e6
KY
14065 0x08,
14066};
14067
e01bf509
TI
14068static hda_nid_t alc269_capsrc_nids[1] = {
14069 0x23,
14070};
14071
84898e87
KY
14072static hda_nid_t alc269vb_adc_nids[1] = {
14073 /* ADC1 */
14074 0x09,
14075};
14076
14077static hda_nid_t alc269vb_capsrc_nids[1] = {
14078 0x22,
14079};
14080
6694635d
TI
14081static hda_nid_t alc269_adc_candidates[] = {
14082 0x08, 0x09, 0x07,
14083};
e01bf509 14084
f6a92248
KY
14085#define alc269_modes alc260_modes
14086#define alc269_capture_source alc880_lg_lw_capture_source
14087
14088static struct snd_kcontrol_new alc269_base_mixer[] = {
14089 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14090 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14091 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14092 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14094 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14095 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14096 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14097 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14098 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14100 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14101 { } /* end */
14102};
14103
60db6b53
KY
14104static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14105 /* output mixer control */
14106 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14107 {
14108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14109 .name = "Master Playback Switch",
5e26dfd0 14110 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14111 .info = snd_hda_mixer_amp_switch_info,
14112 .get = snd_hda_mixer_amp_switch_get,
14113 .put = alc268_acer_master_sw_put,
14114 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14115 },
14116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14117 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14118 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14119 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14120 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14121 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14122 { }
14123};
14124
64154835
TV
14125static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14126 /* output mixer control */
14127 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14128 {
14129 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14130 .name = "Master Playback Switch",
5e26dfd0 14131 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14132 .info = snd_hda_mixer_amp_switch_info,
14133 .get = snd_hda_mixer_amp_switch_get,
14134 .put = alc268_acer_master_sw_put,
14135 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14136 },
14137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14138 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14139 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14140 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14141 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14142 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14143 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14144 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14145 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14146 { }
14147};
14148
84898e87 14149static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14150 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14151 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14152 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14153 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14154 { } /* end */
14155};
14156
84898e87
KY
14157static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14158 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14159 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14160 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14161 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14162 { } /* end */
14163};
14164
fe3eb0a7
KY
14165static struct snd_kcontrol_new alc269_asus_mixer[] = {
14166 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14167 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14168 { } /* end */
14169};
14170
f53281e6 14171/* capture mixer elements */
84898e87
KY
14172static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14173 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14174 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14175 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14176 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14177 { } /* end */
14178};
14179
14180static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14181 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14182 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14183 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14184 { } /* end */
14185};
14186
84898e87
KY
14187static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14188 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14189 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14190 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14191 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14192 { } /* end */
14193};
14194
14195static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14196 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14197 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14198 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14199 { } /* end */
14200};
14201
26f5df26 14202/* FSC amilo */
84898e87 14203#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14204
60db6b53
KY
14205static struct hda_verb alc269_quanta_fl1_verbs[] = {
14206 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14207 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14209 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14210 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14211 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14212 { }
14213};
f6a92248 14214
64154835
TV
14215static struct hda_verb alc269_lifebook_verbs[] = {
14216 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14217 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14218 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14220 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14221 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14222 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14223 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14224 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14225 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14226 { }
14227};
14228
60db6b53
KY
14229/* toggle speaker-output according to the hp-jack state */
14230static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14231{
14232 unsigned int present;
14233 unsigned char bits;
f6a92248 14234
864f92be 14235 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14236 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14237 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14238 HDA_AMP_MUTE, bits);
60db6b53 14239 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14240 HDA_AMP_MUTE, bits);
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, 0x680);
f6a92248 14246
60db6b53
KY
14247 snd_hda_codec_write(codec, 0x20, 0,
14248 AC_VERB_SET_COEF_INDEX, 0x0c);
14249 snd_hda_codec_write(codec, 0x20, 0,
14250 AC_VERB_SET_PROC_COEF, 0x480);
14251}
f6a92248 14252
64154835
TV
14253/* toggle speaker-output according to the hp-jacks state */
14254static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14255{
14256 unsigned int present;
14257 unsigned char bits;
14258
14259 /* Check laptop headphone socket */
864f92be 14260 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14261
14262 /* Check port replicator headphone socket */
864f92be 14263 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14264
5dbd5ec6 14265 bits = present ? HDA_AMP_MUTE : 0;
64154835 14266 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14267 HDA_AMP_MUTE, bits);
64154835 14268 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14269 HDA_AMP_MUTE, bits);
64154835
TV
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, 0x680);
14275
14276 snd_hda_codec_write(codec, 0x20, 0,
14277 AC_VERB_SET_COEF_INDEX, 0x0c);
14278 snd_hda_codec_write(codec, 0x20, 0,
14279 AC_VERB_SET_PROC_COEF, 0x480);
14280}
14281
64154835
TV
14282static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14283{
14284 unsigned int present_laptop;
14285 unsigned int present_dock;
14286
864f92be
WF
14287 present_laptop = snd_hda_jack_detect(codec, 0x18);
14288 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14289
14290 /* Laptop mic port overrides dock mic port, design decision */
14291 if (present_dock)
14292 snd_hda_codec_write(codec, 0x23, 0,
14293 AC_VERB_SET_CONNECT_SEL, 0x3);
14294 if (present_laptop)
14295 snd_hda_codec_write(codec, 0x23, 0,
14296 AC_VERB_SET_CONNECT_SEL, 0x0);
14297 if (!present_dock && !present_laptop)
14298 snd_hda_codec_write(codec, 0x23, 0,
14299 AC_VERB_SET_CONNECT_SEL, 0x1);
14300}
14301
60db6b53
KY
14302static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14303 unsigned int res)
14304{
4f5d1706
TI
14305 switch (res >> 26) {
14306 case ALC880_HP_EVENT:
60db6b53 14307 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14308 break;
14309 case ALC880_MIC_EVENT:
14310 alc_mic_automute(codec);
14311 break;
14312 }
60db6b53 14313}
f6a92248 14314
64154835
TV
14315static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14316 unsigned int res)
14317{
14318 if ((res >> 26) == ALC880_HP_EVENT)
14319 alc269_lifebook_speaker_automute(codec);
14320 if ((res >> 26) == ALC880_MIC_EVENT)
14321 alc269_lifebook_mic_autoswitch(codec);
14322}
14323
4f5d1706
TI
14324static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14325{
14326 struct alc_spec *spec = codec->spec;
20645d70
TI
14327 spec->autocfg.hp_pins[0] = 0x15;
14328 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14329 spec->ext_mic.pin = 0x18;
14330 spec->ext_mic.mux_idx = 0;
14331 spec->int_mic.pin = 0x19;
14332 spec->int_mic.mux_idx = 1;
14333 spec->auto_mic = 1;
14334}
14335
60db6b53
KY
14336static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14337{
14338 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14339 alc_mic_automute(codec);
60db6b53 14340}
f6a92248 14341
64154835
TV
14342static void alc269_lifebook_init_hook(struct hda_codec *codec)
14343{
14344 alc269_lifebook_speaker_automute(codec);
14345 alc269_lifebook_mic_autoswitch(codec);
14346}
14347
84898e87 14348static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14349 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14350 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14351 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14352 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14353 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14354 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14355 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14356 {}
14357};
14358
84898e87 14359static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14360 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14361 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14362 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14363 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14364 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14365 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14366 {}
14367};
14368
84898e87
KY
14369static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14370 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14371 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14372 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14373 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14374 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14375 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14376 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14377 {}
14378};
14379
14380static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14381 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14382 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14383 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14384 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14385 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14386 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14387 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14388 {}
14389};
14390
fe3eb0a7
KY
14391static struct hda_verb alc271_acer_dmic_verbs[] = {
14392 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14393 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14394 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14395 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14396 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14397 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14398 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14399 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14400 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14401 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14402 { }
14403};
14404
f53281e6
KY
14405/* toggle speaker-output according to the hp-jack state */
14406static void alc269_speaker_automute(struct hda_codec *codec)
14407{
ebb83eeb
KY
14408 struct alc_spec *spec = codec->spec;
14409 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14410 unsigned int present;
60db6b53 14411 unsigned char bits;
f53281e6 14412
ebb83eeb 14413 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14414 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14415 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14416 HDA_AMP_MUTE, bits);
f53281e6 14417 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14418 HDA_AMP_MUTE, bits);
bf1b0225 14419 alc_report_jack(codec, nid);
f53281e6
KY
14420}
14421
f53281e6 14422/* unsolicited event for HP jack sensing */
84898e87 14423static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14424 unsigned int res)
f53281e6 14425{
4f5d1706
TI
14426 switch (res >> 26) {
14427 case ALC880_HP_EVENT:
f53281e6 14428 alc269_speaker_automute(codec);
4f5d1706
TI
14429 break;
14430 case ALC880_MIC_EVENT:
14431 alc_mic_automute(codec);
14432 break;
14433 }
f53281e6
KY
14434}
14435
226b1ec8 14436static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14437{
4f5d1706 14438 struct alc_spec *spec = codec->spec;
20645d70
TI
14439 spec->autocfg.hp_pins[0] = 0x15;
14440 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14441 spec->ext_mic.pin = 0x18;
14442 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14443 spec->int_mic.pin = 0x19;
14444 spec->int_mic.mux_idx = 1;
4f5d1706 14445 spec->auto_mic = 1;
f53281e6
KY
14446}
14447
226b1ec8 14448static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14449{
14450 struct alc_spec *spec = codec->spec;
20645d70
TI
14451 spec->autocfg.hp_pins[0] = 0x15;
14452 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14453 spec->ext_mic.pin = 0x18;
14454 spec->ext_mic.mux_idx = 0;
14455 spec->int_mic.pin = 0x12;
226b1ec8 14456 spec->int_mic.mux_idx = 5;
84898e87
KY
14457 spec->auto_mic = 1;
14458}
14459
226b1ec8 14460static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14461{
4f5d1706 14462 struct alc_spec *spec = codec->spec;
226b1ec8 14463 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14464 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14465 spec->ext_mic.pin = 0x18;
14466 spec->ext_mic.mux_idx = 0;
14467 spec->int_mic.pin = 0x19;
14468 spec->int_mic.mux_idx = 1;
14469 spec->auto_mic = 1;
f53281e6
KY
14470}
14471
226b1ec8
KY
14472static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14473{
14474 struct alc_spec *spec = codec->spec;
14475 spec->autocfg.hp_pins[0] = 0x21;
14476 spec->autocfg.speaker_pins[0] = 0x14;
14477 spec->ext_mic.pin = 0x18;
14478 spec->ext_mic.mux_idx = 0;
14479 spec->int_mic.pin = 0x12;
14480 spec->int_mic.mux_idx = 6;
14481 spec->auto_mic = 1;
14482}
14483
84898e87 14484static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14485{
14486 alc269_speaker_automute(codec);
4f5d1706 14487 alc_mic_automute(codec);
f53281e6
KY
14488}
14489
60db6b53
KY
14490/*
14491 * generic initialization of ADC, input mixers and output mixers
14492 */
14493static struct hda_verb alc269_init_verbs[] = {
14494 /*
14495 * Unmute ADC0 and set the default input to mic-in
14496 */
84898e87 14497 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14498
14499 /*
84898e87 14500 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14501 */
14502 /* set vol=0 to output mixers */
14503 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14504 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14505
14506 /* set up input amps for analog loopback */
14507 /* Amp Indices: DAC = 0, mixer = 1 */
14508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14510 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14511 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14512 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14514
14515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14516 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14517 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14518 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14519 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14520 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14521 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14522
14523 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14524 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14525
84898e87
KY
14526 /* FIXME: use Mux-type input source selection */
14527 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14528 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14529 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14530
84898e87
KY
14531 /* set EAPD */
14532 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14533 { }
14534};
14535
14536static struct hda_verb alc269vb_init_verbs[] = {
14537 /*
14538 * Unmute ADC0 and set the default input to mic-in
14539 */
14540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14541
14542 /*
14543 * Set up output mixers (0x02 - 0x03)
14544 */
14545 /* set vol=0 to output mixers */
14546 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14547 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14548
14549 /* set up input amps for analog loopback */
14550 /* Amp Indices: DAC = 0, mixer = 1 */
14551 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14552 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14553 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14554 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14555 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14556 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14557
14558 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14559 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14560 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14561 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14562 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14563 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14564 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14565
14566 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14567 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14568
14569 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14570 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14571 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14572 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14573
14574 /* set EAPD */
14575 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14576 { }
14577};
14578
9d0b71b1
TI
14579#define alc269_auto_create_multi_out_ctls \
14580 alc268_auto_create_multi_out_ctls
05f5f477
TI
14581#define alc269_auto_create_input_ctls \
14582 alc268_auto_create_input_ctls
f6a92248
KY
14583
14584#ifdef CONFIG_SND_HDA_POWER_SAVE
14585#define alc269_loopbacks alc880_loopbacks
14586#endif
14587
def319f9 14588/* pcm configuration: identical with ALC880 */
f6a92248
KY
14589#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14590#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14591#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14592#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14593
f03d3115
TI
14594static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14595 .substreams = 1,
14596 .channels_min = 2,
14597 .channels_max = 8,
14598 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14599 /* NID is set in alc_build_pcms */
14600 .ops = {
14601 .open = alc880_playback_pcm_open,
14602 .prepare = alc880_playback_pcm_prepare,
14603 .cleanup = alc880_playback_pcm_cleanup
14604 },
14605};
14606
14607static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14608 .substreams = 1,
14609 .channels_min = 2,
14610 .channels_max = 2,
14611 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14612 /* NID is set in alc_build_pcms */
14613};
14614
ad35879a
TI
14615#ifdef CONFIG_SND_HDA_POWER_SAVE
14616static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14617{
14618 switch (codec->subsystem_id) {
14619 case 0x103c1586:
14620 return 1;
14621 }
14622 return 0;
14623}
14624
14625static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14626{
14627 /* update mute-LED according to the speaker mute state */
14628 if (nid == 0x01 || nid == 0x14) {
14629 int pinval;
14630 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14631 HDA_AMP_MUTE)
14632 pinval = 0x24;
14633 else
14634 pinval = 0x20;
14635 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14636 snd_hda_codec_update_cache(codec, 0x19, 0,
14637 AC_VERB_SET_PIN_WIDGET_CONTROL,
14638 pinval);
ad35879a
TI
14639 }
14640 return alc_check_power_status(codec, nid);
14641}
14642#endif /* CONFIG_SND_HDA_POWER_SAVE */
14643
840b64c0
TI
14644static int alc275_setup_dual_adc(struct hda_codec *codec)
14645{
14646 struct alc_spec *spec = codec->spec;
14647
14648 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14649 return 0;
14650 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14651 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14652 if (spec->ext_mic.pin <= 0x12) {
14653 spec->private_adc_nids[0] = 0x08;
14654 spec->private_adc_nids[1] = 0x11;
14655 spec->private_capsrc_nids[0] = 0x23;
14656 spec->private_capsrc_nids[1] = 0x22;
14657 } else {
14658 spec->private_adc_nids[0] = 0x11;
14659 spec->private_adc_nids[1] = 0x08;
14660 spec->private_capsrc_nids[0] = 0x22;
14661 spec->private_capsrc_nids[1] = 0x23;
14662 }
14663 spec->adc_nids = spec->private_adc_nids;
14664 spec->capsrc_nids = spec->private_capsrc_nids;
14665 spec->num_adc_nids = 2;
14666 spec->dual_adc_switch = 1;
14667 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14668 spec->adc_nids[0], spec->adc_nids[1]);
14669 return 1;
14670 }
14671 return 0;
14672}
14673
d433a678
TI
14674/* different alc269-variants */
14675enum {
14676 ALC269_TYPE_NORMAL,
48c88e82 14677 ALC269_TYPE_ALC258,
d433a678 14678 ALC269_TYPE_ALC259,
48c88e82
KY
14679 ALC269_TYPE_ALC269VB,
14680 ALC269_TYPE_ALC270,
d433a678
TI
14681 ALC269_TYPE_ALC271X,
14682};
14683
f6a92248
KY
14684/*
14685 * BIOS auto configuration
14686 */
14687static int alc269_parse_auto_config(struct hda_codec *codec)
14688{
14689 struct alc_spec *spec = codec->spec;
cfb9fb55 14690 int err;
f6a92248
KY
14691 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14692
14693 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14694 alc269_ignore);
14695 if (err < 0)
14696 return err;
14697
14698 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14699 if (err < 0)
14700 return err;
f3550d1b
TI
14701 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14702 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14703 else
14704 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14705 0x22, 0);
f6a92248
KY
14706 if (err < 0)
14707 return err;
14708
14709 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14710
757899ac 14711 alc_auto_parse_digital(codec);
f6a92248 14712
603c4019 14713 if (spec->kctls.list)
d88897ea 14714 add_mixer(spec, spec->kctls.list);
f6a92248 14715
d433a678 14716 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14717 add_verb(spec, alc269vb_init_verbs);
6227cdce 14718 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14719 } else {
14720 add_verb(spec, alc269_init_verbs);
6227cdce 14721 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14722 }
14723
f6a92248 14724 spec->num_mux_defs = 1;
61b9b9b1 14725 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14726
14727 if (!alc275_setup_dual_adc(codec))
14728 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14729 sizeof(alc269_adc_candidates));
6694635d 14730
e01bf509 14731 /* set default input source */
840b64c0 14732 if (!spec->dual_adc_switch)
748cce43
TI
14733 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14734 spec->input_mux->items[0].index);
f6a92248
KY
14735
14736 err = alc_auto_add_mic_boost(codec);
14737 if (err < 0)
14738 return err;
14739
7e0e44d4 14740 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14741 set_capture_mixer(codec);
f53281e6 14742
f6a92248
KY
14743 return 1;
14744}
14745
e9af4f36
TI
14746#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14747#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14748#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14749
14750
14751/* init callback for auto-configuration model -- overriding the default init */
14752static void alc269_auto_init(struct hda_codec *codec)
14753{
f6c7e546 14754 struct alc_spec *spec = codec->spec;
f6a92248
KY
14755 alc269_auto_init_multi_out(codec);
14756 alc269_auto_init_hp_out(codec);
14757 alc269_auto_init_analog_input(codec);
757899ac 14758 alc_auto_init_digital(codec);
f6c7e546 14759 if (spec->unsol_event)
7fb0d78f 14760 alc_inithook(codec);
f6a92248
KY
14761}
14762
0ec33d1f
TI
14763#ifdef SND_HDA_NEEDS_RESUME
14764static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14765{
14766 int val = alc_read_coef_idx(codec, 0x04);
14767 if (power_up)
14768 val |= 1 << 11;
14769 else
14770 val &= ~(1 << 11);
14771 alc_write_coef_idx(codec, 0x04, val);
14772}
14773
977ddd6b
KY
14774#ifdef CONFIG_SND_HDA_POWER_SAVE
14775static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14776{
14777 struct alc_spec *spec = codec->spec;
977ddd6b 14778
0ec33d1f
TI
14779 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14780 alc269_toggle_power_output(codec, 0);
977ddd6b 14781 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14782 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14783 msleep(150);
14784 }
14785
14786 alc_shutup(codec);
14787 if (spec && spec->power_hook)
14788 spec->power_hook(codec);
14789 return 0;
14790}
0ec33d1f
TI
14791#endif /* CONFIG_SND_HDA_POWER_SAVE */
14792
977ddd6b
KY
14793static int alc269_resume(struct hda_codec *codec)
14794{
977ddd6b 14795 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14796 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14797 msleep(150);
14798 }
14799
14800 codec->patch_ops.init(codec);
14801
14802 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14803 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14804 msleep(200);
14805 }
14806
0ec33d1f
TI
14807 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14808 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14809
14810 snd_hda_codec_resume_amp(codec);
14811 snd_hda_codec_resume_cache(codec);
9e5341b9 14812 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14813 return 0;
14814}
0ec33d1f 14815#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14816
ff818c24
TI
14817enum {
14818 ALC269_FIXUP_SONY_VAIO,
2785591a 14819 ALC275_FIX_SONY_VAIO_GPIO2,
145a902b 14820 ALC269_FIXUP_DELL_M101Z,
022c92be 14821 ALC269_FIXUP_SKU_IGNORE,
ac612407 14822 ALC269_FIXUP_ASUS_G73JW,
ff818c24
TI
14823};
14824
ff818c24
TI
14825static const struct alc_fixup alc269_fixups[] = {
14826 [ALC269_FIXUP_SONY_VAIO] = {
73413b12
TI
14827 .verbs = (const struct hda_verb[]) {
14828 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14829 {}
14830 }
ff818c24 14831 },
2785591a
KY
14832 [ALC275_FIX_SONY_VAIO_GPIO2] = {
14833 .verbs = (const struct hda_verb[]) {
14834 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14835 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14836 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14837 { }
14838 }
14839 },
145a902b
DH
14840 [ALC269_FIXUP_DELL_M101Z] = {
14841 .verbs = (const struct hda_verb[]) {
14842 /* Enables internal speaker */
14843 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14844 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14845 {}
14846 }
14847 },
022c92be 14848 [ALC269_FIXUP_SKU_IGNORE] = {
fe67b240
DH
14849 .sku = ALC_FIXUP_SKU_IGNORE,
14850 },
ac612407
DH
14851 [ALC269_FIXUP_ASUS_G73JW] = {
14852 .pins = (const struct alc_pincfg[]) {
14853 { 0x17, 0x99130111 }, /* subwoofer */
14854 { }
14855 }
14856 },
ff818c24
TI
14857};
14858
14859static struct snd_pci_quirk alc269_fixup_tbl[] = {
2785591a
KY
14860 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
14861 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
14862 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
abdd8f51 14863 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14864 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
022c92be
DH
14865 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14866 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ac612407 14867 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
ff818c24
TI
14868 {}
14869};
14870
14871
f6a92248
KY
14872/*
14873 * configuration and preset
14874 */
14875static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14876 [ALC269_BASIC] = "basic",
2922c9af 14877 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14878 [ALC269_AMIC] = "laptop-amic",
14879 [ALC269_DMIC] = "laptop-dmic",
64154835 14880 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14881 [ALC269_LIFEBOOK] = "lifebook",
14882 [ALC269_AUTO] = "auto",
f6a92248
KY
14883};
14884
14885static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14886 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14887 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14888 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14889 ALC269_AMIC),
14890 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14891 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14892 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14893 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14894 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14895 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14896 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14897 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14898 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14899 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14900 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14901 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14902 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14903 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14904 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14905 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14906 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14907 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14908 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14909 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14910 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14911 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14912 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14913 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14914 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14915 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14916 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14917 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14918 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14919 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14920 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14921 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14922 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14923 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14924 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14925 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14926 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14927 ALC269_DMIC),
60db6b53 14928 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14929 ALC269_DMIC),
14930 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14931 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14932 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14933 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14934 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14935 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14936 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14937 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14938 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14939 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14940 {}
14941};
14942
14943static struct alc_config_preset alc269_presets[] = {
14944 [ALC269_BASIC] = {
f9e336f6 14945 .mixers = { alc269_base_mixer },
f6a92248
KY
14946 .init_verbs = { alc269_init_verbs },
14947 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14948 .dac_nids = alc269_dac_nids,
14949 .hp_nid = 0x03,
14950 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14951 .channel_mode = alc269_modes,
14952 .input_mux = &alc269_capture_source,
14953 },
60db6b53
KY
14954 [ALC269_QUANTA_FL1] = {
14955 .mixers = { alc269_quanta_fl1_mixer },
14956 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14957 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14958 .dac_nids = alc269_dac_nids,
14959 .hp_nid = 0x03,
14960 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14961 .channel_mode = alc269_modes,
14962 .input_mux = &alc269_capture_source,
14963 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14964 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14965 .init_hook = alc269_quanta_fl1_init_hook,
14966 },
84898e87
KY
14967 [ALC269_AMIC] = {
14968 .mixers = { alc269_laptop_mixer },
14969 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14970 .init_verbs = { alc269_init_verbs,
84898e87 14971 alc269_laptop_amic_init_verbs },
f53281e6
KY
14972 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14973 .dac_nids = alc269_dac_nids,
14974 .hp_nid = 0x03,
14975 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14976 .channel_mode = alc269_modes,
84898e87
KY
14977 .unsol_event = alc269_laptop_unsol_event,
14978 .setup = alc269_laptop_amic_setup,
14979 .init_hook = alc269_laptop_inithook,
f53281e6 14980 },
84898e87
KY
14981 [ALC269_DMIC] = {
14982 .mixers = { alc269_laptop_mixer },
14983 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14984 .init_verbs = { alc269_init_verbs,
84898e87
KY
14985 alc269_laptop_dmic_init_verbs },
14986 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14987 .dac_nids = alc269_dac_nids,
14988 .hp_nid = 0x03,
14989 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14990 .channel_mode = alc269_modes,
14991 .unsol_event = alc269_laptop_unsol_event,
14992 .setup = alc269_laptop_dmic_setup,
14993 .init_hook = alc269_laptop_inithook,
14994 },
14995 [ALC269VB_AMIC] = {
14996 .mixers = { alc269vb_laptop_mixer },
14997 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14998 .init_verbs = { alc269vb_init_verbs,
14999 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15000 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15001 .dac_nids = alc269_dac_nids,
15002 .hp_nid = 0x03,
15003 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15004 .channel_mode = alc269_modes,
84898e87 15005 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 15006 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
15007 .init_hook = alc269_laptop_inithook,
15008 },
15009 [ALC269VB_DMIC] = {
15010 .mixers = { alc269vb_laptop_mixer },
15011 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15012 .init_verbs = { alc269vb_init_verbs,
15013 alc269vb_laptop_dmic_init_verbs },
15014 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15015 .dac_nids = alc269_dac_nids,
15016 .hp_nid = 0x03,
15017 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15018 .channel_mode = alc269_modes,
15019 .unsol_event = alc269_laptop_unsol_event,
15020 .setup = alc269vb_laptop_dmic_setup,
15021 .init_hook = alc269_laptop_inithook,
f53281e6 15022 },
26f5df26 15023 [ALC269_FUJITSU] = {
45bdd1c1 15024 .mixers = { alc269_fujitsu_mixer },
84898e87 15025 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15026 .init_verbs = { alc269_init_verbs,
84898e87 15027 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15028 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15029 .dac_nids = alc269_dac_nids,
15030 .hp_nid = 0x03,
15031 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15032 .channel_mode = alc269_modes,
84898e87
KY
15033 .unsol_event = alc269_laptop_unsol_event,
15034 .setup = alc269_laptop_dmic_setup,
15035 .init_hook = alc269_laptop_inithook,
26f5df26 15036 },
64154835
TV
15037 [ALC269_LIFEBOOK] = {
15038 .mixers = { alc269_lifebook_mixer },
15039 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15040 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15041 .dac_nids = alc269_dac_nids,
15042 .hp_nid = 0x03,
15043 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15044 .channel_mode = alc269_modes,
15045 .input_mux = &alc269_capture_source,
15046 .unsol_event = alc269_lifebook_unsol_event,
15047 .init_hook = alc269_lifebook_init_hook,
15048 },
fe3eb0a7
KY
15049 [ALC271_ACER] = {
15050 .mixers = { alc269_asus_mixer },
15051 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15052 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15053 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15054 .dac_nids = alc269_dac_nids,
15055 .adc_nids = alc262_dmic_adc_nids,
15056 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15057 .capsrc_nids = alc262_dmic_capsrc_nids,
15058 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15059 .channel_mode = alc269_modes,
15060 .input_mux = &alc269_capture_source,
15061 .dig_out_nid = ALC880_DIGOUT_NID,
15062 .unsol_event = alc_sku_unsol_event,
15063 .setup = alc269vb_laptop_dmic_setup,
15064 .init_hook = alc_inithook,
15065 },
f6a92248
KY
15066};
15067
977ddd6b
KY
15068static int alc269_fill_coef(struct hda_codec *codec)
15069{
15070 int val;
15071
15072 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15073 alc_write_coef_idx(codec, 0xf, 0x960b);
15074 alc_write_coef_idx(codec, 0xe, 0x8817);
15075 }
15076
15077 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15078 alc_write_coef_idx(codec, 0xf, 0x960b);
15079 alc_write_coef_idx(codec, 0xe, 0x8814);
15080 }
15081
15082 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15083 val = alc_read_coef_idx(codec, 0x04);
15084 /* Power up output pin */
15085 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15086 }
15087
15088 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15089 val = alc_read_coef_idx(codec, 0xd);
15090 if ((val & 0x0c00) >> 10 != 0x1) {
15091 /* Capless ramp up clock control */
15092 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15093 }
15094 val = alc_read_coef_idx(codec, 0x17);
15095 if ((val & 0x01c0) >> 6 != 0x4) {
15096 /* Class D power on reset */
15097 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15098 }
15099 }
15100 return 0;
15101}
15102
f6a92248
KY
15103static int patch_alc269(struct hda_codec *codec)
15104{
15105 struct alc_spec *spec;
48c88e82 15106 int board_config, coef;
f6a92248
KY
15107 int err;
15108
15109 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15110 if (spec == NULL)
15111 return -ENOMEM;
15112
15113 codec->spec = spec;
15114
da00c244
KY
15115 alc_auto_parse_customize_define(codec);
15116
c793bec5
KY
15117 if (codec->vendor_id == 0x10ec0269) {
15118 coef = alc_read_coef_idx(codec, 0);
15119 if ((coef & 0x00f0) == 0x0010) {
15120 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15121 spec->cdefine.platform_type == 1) {
15122 alc_codec_rename(codec, "ALC271X");
15123 spec->codec_variant = ALC269_TYPE_ALC271X;
15124 } else if ((coef & 0xf000) == 0x1000) {
15125 spec->codec_variant = ALC269_TYPE_ALC270;
15126 } else if ((coef & 0xf000) == 0x2000) {
15127 alc_codec_rename(codec, "ALC259");
15128 spec->codec_variant = ALC269_TYPE_ALC259;
15129 } else if ((coef & 0xf000) == 0x3000) {
15130 alc_codec_rename(codec, "ALC258");
15131 spec->codec_variant = ALC269_TYPE_ALC258;
15132 } else {
15133 alc_codec_rename(codec, "ALC269VB");
15134 spec->codec_variant = ALC269_TYPE_ALC269VB;
15135 }
15136 } else
15137 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15138 alc269_fill_coef(codec);
15139 }
977ddd6b 15140
f6a92248
KY
15141 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15142 alc269_models,
15143 alc269_cfg_tbl);
15144
15145 if (board_config < 0) {
9a11f1aa
TI
15146 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15147 codec->chip_name);
f6a92248
KY
15148 board_config = ALC269_AUTO;
15149 }
15150
ff818c24
TI
15151 if (board_config == ALC269_AUTO)
15152 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
15153
f6a92248
KY
15154 if (board_config == ALC269_AUTO) {
15155 /* automatic parse from the BIOS config */
15156 err = alc269_parse_auto_config(codec);
15157 if (err < 0) {
15158 alc_free(codec);
15159 return err;
15160 } else if (!err) {
15161 printk(KERN_INFO
15162 "hda_codec: Cannot set up configuration "
15163 "from BIOS. Using base mode...\n");
15164 board_config = ALC269_BASIC;
15165 }
15166 }
15167
dc1eae25 15168 if (has_cdefine_beep(codec)) {
8af2591d
TI
15169 err = snd_hda_attach_beep_device(codec, 0x1);
15170 if (err < 0) {
15171 alc_free(codec);
15172 return err;
15173 }
680cd536
KK
15174 }
15175
f6a92248 15176 if (board_config != ALC269_AUTO)
e9c364c0 15177 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15178
84898e87 15179 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15180 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15181 * fix the sample rate of analog I/O to 44.1kHz
15182 */
15183 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15184 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15185 } else if (spec->dual_adc_switch) {
15186 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15187 /* switch ADC dynamically */
15188 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15189 } else {
15190 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15191 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15192 }
f6a92248
KY
15193 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15194 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15195
6694635d 15196 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15197 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15198 spec->adc_nids = alc269_adc_nids;
15199 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15200 spec->capsrc_nids = alc269_capsrc_nids;
15201 } else {
15202 spec->adc_nids = alc269vb_adc_nids;
15203 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15204 spec->capsrc_nids = alc269vb_capsrc_nids;
15205 }
84898e87
KY
15206 }
15207
f9e336f6 15208 if (!spec->cap_mixer)
b59bdf3b 15209 set_capture_mixer(codec);
dc1eae25 15210 if (has_cdefine_beep(codec))
da00c244 15211 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15212
ff818c24
TI
15213 if (board_config == ALC269_AUTO)
15214 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
15215
100d5eb3
TI
15216 spec->vmaster_nid = 0x02;
15217
f6a92248 15218 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15219#ifdef CONFIG_SND_HDA_POWER_SAVE
15220 codec->patch_ops.suspend = alc269_suspend;
15221#endif
15222#ifdef SND_HDA_NEEDS_RESUME
15223 codec->patch_ops.resume = alc269_resume;
15224#endif
f6a92248
KY
15225 if (board_config == ALC269_AUTO)
15226 spec->init_hook = alc269_auto_init;
bf1b0225
KY
15227
15228 alc_init_jacks(codec);
f6a92248
KY
15229#ifdef CONFIG_SND_HDA_POWER_SAVE
15230 if (!spec->loopback.amplist)
15231 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15232 if (alc269_mic2_for_mute_led(codec))
15233 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15234#endif
15235
15236 return 0;
15237}
15238
df694daa
KY
15239/*
15240 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15241 */
15242
15243/*
15244 * set the path ways for 2 channel output
15245 * need to set the codec line out and mic 1 pin widgets to inputs
15246 */
15247static struct hda_verb alc861_threestack_ch2_init[] = {
15248 /* set pin widget 1Ah (line in) for input */
15249 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15250 /* set pin widget 18h (mic1/2) for input, for mic also enable
15251 * the vref
15252 */
df694daa
KY
15253 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15254
9c7f852e
TI
15255 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15256#if 0
15257 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15258 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15259#endif
df694daa
KY
15260 { } /* end */
15261};
15262/*
15263 * 6ch mode
15264 * need to set the codec line out and mic 1 pin widgets to outputs
15265 */
15266static struct hda_verb alc861_threestack_ch6_init[] = {
15267 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15268 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15269 /* set pin widget 18h (mic1) for output (CLFE)*/
15270 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15271
15272 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15273 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15274
9c7f852e
TI
15275 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15276#if 0
15277 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15278 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15279#endif
df694daa
KY
15280 { } /* end */
15281};
15282
15283static struct hda_channel_mode alc861_threestack_modes[2] = {
15284 { 2, alc861_threestack_ch2_init },
15285 { 6, alc861_threestack_ch6_init },
15286};
22309c3e
TI
15287/* Set mic1 as input and unmute the mixer */
15288static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15289 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15290 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15291 { } /* end */
15292};
15293/* Set mic1 as output and mute mixer */
15294static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15295 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15296 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15297 { } /* end */
15298};
15299
15300static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15301 { 2, alc861_uniwill_m31_ch2_init },
15302 { 4, alc861_uniwill_m31_ch4_init },
15303};
df694daa 15304
7cdbff94
MD
15305/* Set mic1 and line-in as input and unmute the mixer */
15306static struct hda_verb alc861_asus_ch2_init[] = {
15307 /* set pin widget 1Ah (line in) for input */
15308 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15309 /* set pin widget 18h (mic1/2) for input, for mic also enable
15310 * the vref
15311 */
7cdbff94
MD
15312 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15313
15314 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15315#if 0
15316 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15317 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15318#endif
15319 { } /* end */
15320};
15321/* Set mic1 nad line-in as output and mute mixer */
15322static struct hda_verb alc861_asus_ch6_init[] = {
15323 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15324 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15325 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15326 /* set pin widget 18h (mic1) for output (CLFE)*/
15327 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15328 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15329 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15330 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15331
15332 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15333#if 0
15334 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15335 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15336#endif
15337 { } /* end */
15338};
15339
15340static struct hda_channel_mode alc861_asus_modes[2] = {
15341 { 2, alc861_asus_ch2_init },
15342 { 6, alc861_asus_ch6_init },
15343};
15344
df694daa
KY
15345/* patch-ALC861 */
15346
15347static struct snd_kcontrol_new alc861_base_mixer[] = {
15348 /* output mixer control */
15349 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15350 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15351 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15352 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15353 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15354
15355 /*Input mixer control */
15356 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15357 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15358 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15359 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15360 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15361 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15362 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15363 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15364 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15366
df694daa
KY
15367 { } /* end */
15368};
15369
15370static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15371 /* output mixer control */
15372 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15373 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15374 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15375 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15376 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15377
15378 /* Input mixer control */
15379 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15380 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15381 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15382 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15383 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15384 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15385 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15386 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15387 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15388 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15389
df694daa
KY
15390 {
15391 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15392 .name = "Channel Mode",
15393 .info = alc_ch_mode_info,
15394 .get = alc_ch_mode_get,
15395 .put = alc_ch_mode_put,
15396 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15397 },
15398 { } /* end */
a53d1aec
TD
15399};
15400
d1d985f0 15401static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15402 /* output mixer control */
15403 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15405 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15406
a53d1aec 15407 { } /* end */
f12ab1e0 15408};
a53d1aec 15409
22309c3e
TI
15410static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15411 /* output mixer control */
15412 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15413 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15414 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15415 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15416 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15417
15418 /* Input mixer control */
15419 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15420 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15421 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15422 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15423 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15424 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15426 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15427 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15428 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15429
22309c3e
TI
15430 {
15431 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15432 .name = "Channel Mode",
15433 .info = alc_ch_mode_info,
15434 .get = alc_ch_mode_get,
15435 .put = alc_ch_mode_put,
15436 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15437 },
15438 { } /* end */
f12ab1e0 15439};
7cdbff94
MD
15440
15441static struct snd_kcontrol_new alc861_asus_mixer[] = {
15442 /* output mixer control */
15443 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15444 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15445 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15446 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15447 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15448
15449 /* Input mixer control */
15450 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15451 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15452 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15453 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15454 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15455 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15457 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15458 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15459 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15460
7cdbff94
MD
15461 {
15462 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15463 .name = "Channel Mode",
15464 .info = alc_ch_mode_info,
15465 .get = alc_ch_mode_get,
15466 .put = alc_ch_mode_put,
15467 .private_value = ARRAY_SIZE(alc861_asus_modes),
15468 },
15469 { }
56bb0cab
TI
15470};
15471
15472/* additional mixer */
d1d985f0 15473static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15474 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15475 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15476 { }
15477};
7cdbff94 15478
df694daa
KY
15479/*
15480 * generic initialization of ADC, input mixers and output mixers
15481 */
15482static struct hda_verb alc861_base_init_verbs[] = {
15483 /*
15484 * Unmute ADC0 and set the default input to mic-in
15485 */
15486 /* port-A for surround (rear panel) */
15487 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15488 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15489 /* port-B for mic-in (rear panel) with vref */
15490 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15491 /* port-C for line-in (rear panel) */
15492 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15493 /* port-D for Front */
15494 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15495 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15496 /* port-E for HP out (front panel) */
15497 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15498 /* route front PCM to HP */
9dece1d7 15499 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15500 /* port-F for mic-in (front panel) with vref */
15501 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15502 /* port-G for CLFE (rear panel) */
15503 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15504 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15505 /* port-H for side (rear panel) */
15506 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15507 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15508 /* CD-in */
15509 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15510 /* route front mic to ADC1*/
15511 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15512 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15513
df694daa
KY
15514 /* Unmute DAC0~3 & spdif out*/
15515 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15516 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15517 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15518 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15519 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15520
df694daa
KY
15521 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15522 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15523 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15524 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15525 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15526
df694daa
KY
15527 /* Unmute Stereo Mixer 15 */
15528 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15529 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15530 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15531 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15532
15533 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15534 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15535 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15536 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15537 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15538 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15539 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15540 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15541 /* hp used DAC 3 (Front) */
15542 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15543 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15544
15545 { }
15546};
15547
15548static struct hda_verb alc861_threestack_init_verbs[] = {
15549 /*
15550 * Unmute ADC0 and set the default input to mic-in
15551 */
15552 /* port-A for surround (rear panel) */
15553 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15554 /* port-B for mic-in (rear panel) with vref */
15555 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15556 /* port-C for line-in (rear panel) */
15557 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15558 /* port-D for Front */
15559 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15560 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15561 /* port-E for HP out (front panel) */
15562 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15563 /* route front PCM to HP */
9dece1d7 15564 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15565 /* port-F for mic-in (front panel) with vref */
15566 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15567 /* port-G for CLFE (rear panel) */
15568 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15569 /* port-H for side (rear panel) */
15570 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15571 /* CD-in */
15572 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15573 /* route front mic to ADC1*/
15574 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15575 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15576 /* Unmute DAC0~3 & spdif out*/
15577 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15578 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15579 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15580 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15581 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15582
df694daa
KY
15583 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15584 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15585 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15586 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15587 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15588
df694daa
KY
15589 /* Unmute Stereo Mixer 15 */
15590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15591 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15593 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15594
15595 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15596 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15597 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15598 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15599 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15600 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15601 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15602 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15603 /* hp used DAC 3 (Front) */
15604 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15605 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15606 { }
15607};
22309c3e
TI
15608
15609static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15610 /*
15611 * Unmute ADC0 and set the default input to mic-in
15612 */
15613 /* port-A for surround (rear panel) */
15614 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15615 /* port-B for mic-in (rear panel) with vref */
15616 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15617 /* port-C for line-in (rear panel) */
15618 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15619 /* port-D for Front */
15620 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15621 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15622 /* port-E for HP out (front panel) */
f12ab1e0
TI
15623 /* this has to be set to VREF80 */
15624 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15625 /* route front PCM to HP */
9dece1d7 15626 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15627 /* port-F for mic-in (front panel) with vref */
15628 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15629 /* port-G for CLFE (rear panel) */
15630 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15631 /* port-H for side (rear panel) */
15632 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15633 /* CD-in */
15634 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15635 /* route front mic to ADC1*/
15636 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15637 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15638 /* Unmute DAC0~3 & spdif out*/
15639 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15640 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15641 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15642 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15643 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15644
22309c3e
TI
15645 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15646 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15647 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15648 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15649 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15650
22309c3e
TI
15651 /* Unmute Stereo Mixer 15 */
15652 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15654 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15655 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15656
15657 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15658 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15659 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15660 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15661 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15662 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15663 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15664 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15665 /* hp used DAC 3 (Front) */
15666 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15667 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15668 { }
15669};
15670
7cdbff94
MD
15671static struct hda_verb alc861_asus_init_verbs[] = {
15672 /*
15673 * Unmute ADC0 and set the default input to mic-in
15674 */
f12ab1e0
TI
15675 /* port-A for surround (rear panel)
15676 * according to codec#0 this is the HP jack
15677 */
7cdbff94
MD
15678 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15679 /* route front PCM to HP */
15680 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15681 /* port-B for mic-in (rear panel) with vref */
15682 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15683 /* port-C for line-in (rear panel) */
15684 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15685 /* port-D for Front */
15686 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15687 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15688 /* port-E for HP out (front panel) */
f12ab1e0
TI
15689 /* this has to be set to VREF80 */
15690 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15691 /* route front PCM to HP */
9dece1d7 15692 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15693 /* port-F for mic-in (front panel) with vref */
15694 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15695 /* port-G for CLFE (rear panel) */
15696 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15697 /* port-H for side (rear panel) */
15698 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15699 /* CD-in */
15700 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15701 /* route front mic to ADC1*/
15702 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15703 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15704 /* Unmute DAC0~3 & spdif out*/
15705 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15706 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15707 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15708 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15709 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15710 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15711 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15712 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15713 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15714 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15715
7cdbff94
MD
15716 /* Unmute Stereo Mixer 15 */
15717 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15718 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15719 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15720 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15721
15722 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15723 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15724 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15725 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15726 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15727 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15728 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15730 /* hp used DAC 3 (Front) */
15731 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15733 { }
15734};
15735
56bb0cab
TI
15736/* additional init verbs for ASUS laptops */
15737static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15738 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15739 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15740 { }
15741};
7cdbff94 15742
df694daa
KY
15743/*
15744 * generic initialization of ADC, input mixers and output mixers
15745 */
15746static struct hda_verb alc861_auto_init_verbs[] = {
15747 /*
15748 * Unmute ADC0 and set the default input to mic-in
15749 */
f12ab1e0 15750 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15752
df694daa
KY
15753 /* Unmute DAC0~3 & spdif out*/
15754 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15755 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15756 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15757 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15758 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15759
df694daa
KY
15760 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15761 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15762 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15763 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15764 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15765
df694daa
KY
15766 /* Unmute Stereo Mixer 15 */
15767 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15768 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15769 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15770 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15771
1c20930a
TI
15772 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15773 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15774 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15775 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15777 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15779 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15780
15781 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15782 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15783 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15784 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15785 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15786 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15787 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15788 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15789
f12ab1e0 15790 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15791
15792 { }
15793};
15794
a53d1aec
TD
15795static struct hda_verb alc861_toshiba_init_verbs[] = {
15796 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15797
a53d1aec
TD
15798 { }
15799};
15800
15801/* toggle speaker-output according to the hp-jack state */
15802static void alc861_toshiba_automute(struct hda_codec *codec)
15803{
864f92be 15804 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15805
47fd830a
TI
15806 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15807 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15808 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15809 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15810}
15811
15812static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15813 unsigned int res)
15814{
a53d1aec
TD
15815 if ((res >> 26) == ALC880_HP_EVENT)
15816 alc861_toshiba_automute(codec);
15817}
15818
def319f9 15819/* pcm configuration: identical with ALC880 */
df694daa
KY
15820#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15821#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15822#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15823#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15824
15825
15826#define ALC861_DIGOUT_NID 0x07
15827
15828static struct hda_channel_mode alc861_8ch_modes[1] = {
15829 { 8, NULL }
15830};
15831
15832static hda_nid_t alc861_dac_nids[4] = {
15833 /* front, surround, clfe, side */
15834 0x03, 0x06, 0x05, 0x04
15835};
15836
9c7f852e
TI
15837static hda_nid_t alc660_dac_nids[3] = {
15838 /* front, clfe, surround */
15839 0x03, 0x05, 0x06
15840};
15841
df694daa
KY
15842static hda_nid_t alc861_adc_nids[1] = {
15843 /* ADC0-2 */
15844 0x08,
15845};
15846
15847static struct hda_input_mux alc861_capture_source = {
15848 .num_items = 5,
15849 .items = {
15850 { "Mic", 0x0 },
15851 { "Front Mic", 0x3 },
15852 { "Line", 0x1 },
15853 { "CD", 0x4 },
15854 { "Mixer", 0x5 },
15855 },
15856};
15857
1c20930a
TI
15858static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15859{
15860 struct alc_spec *spec = codec->spec;
15861 hda_nid_t mix, srcs[5];
15862 int i, j, num;
15863
15864 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15865 return 0;
15866 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15867 if (num < 0)
15868 return 0;
15869 for (i = 0; i < num; i++) {
15870 unsigned int type;
a22d543a 15871 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15872 if (type != AC_WID_AUD_OUT)
15873 continue;
15874 for (j = 0; j < spec->multiout.num_dacs; j++)
15875 if (spec->multiout.dac_nids[j] == srcs[i])
15876 break;
15877 if (j >= spec->multiout.num_dacs)
15878 return srcs[i];
15879 }
15880 return 0;
15881}
15882
df694daa 15883/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15884static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15885 const struct auto_pin_cfg *cfg)
df694daa 15886{
1c20930a 15887 struct alc_spec *spec = codec->spec;
df694daa 15888 int i;
1c20930a 15889 hda_nid_t nid, dac;
df694daa
KY
15890
15891 spec->multiout.dac_nids = spec->private_dac_nids;
15892 for (i = 0; i < cfg->line_outs; i++) {
15893 nid = cfg->line_out_pins[i];
1c20930a
TI
15894 dac = alc861_look_for_dac(codec, nid);
15895 if (!dac)
15896 continue;
15897 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15898 }
df694daa
KY
15899 return 0;
15900}
15901
bcb2f0f5
TI
15902static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15903 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15904{
bcb2f0f5 15905 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15906 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15907}
15908
bcb2f0f5
TI
15909#define alc861_create_out_sw(codec, pfx, nid, chs) \
15910 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15911
df694daa 15912/* add playback controls from the parsed DAC table */
1c20930a 15913static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15914 const struct auto_pin_cfg *cfg)
15915{
1c20930a 15916 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15917 static const char *chname[4] = {
15918 "Front", "Surround", NULL /*CLFE*/, "Side"
15919 };
bcb2f0f5 15920 const char *pfx = alc_get_line_out_pfx(cfg, true);
df694daa 15921 hda_nid_t nid;
1c20930a
TI
15922 int i, err;
15923
df694daa
KY
15924 for (i = 0; i < cfg->line_outs; i++) {
15925 nid = spec->multiout.dac_nids[i];
f12ab1e0 15926 if (!nid)
df694daa 15927 continue;
bcb2f0f5 15928 if (!pfx && i == 2) {
df694daa 15929 /* Center/LFE */
1c20930a 15930 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15931 if (err < 0)
df694daa 15932 return err;
1c20930a 15933 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15934 if (err < 0)
df694daa
KY
15935 return err;
15936 } else {
bcb2f0f5
TI
15937 const char *name = pfx;
15938 if (!name)
15939 name = chname[i];
15940 err = __alc861_create_out_sw(codec, name, nid, i, 3);
f12ab1e0 15941 if (err < 0)
df694daa
KY
15942 return err;
15943 }
15944 }
15945 return 0;
15946}
15947
1c20930a 15948static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15949{
1c20930a 15950 struct alc_spec *spec = codec->spec;
df694daa
KY
15951 int err;
15952 hda_nid_t nid;
15953
f12ab1e0 15954 if (!pin)
df694daa
KY
15955 return 0;
15956
15957 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15958 nid = alc861_look_for_dac(codec, pin);
15959 if (nid) {
15960 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15961 if (err < 0)
15962 return err;
15963 spec->multiout.hp_nid = nid;
15964 }
df694daa
KY
15965 }
15966 return 0;
15967}
15968
15969/* create playback/capture controls for input pins */
05f5f477 15970static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15971 const struct auto_pin_cfg *cfg)
df694daa 15972{
05f5f477 15973 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15974}
15975
f12ab1e0
TI
15976static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15977 hda_nid_t nid,
1c20930a 15978 int pin_type, hda_nid_t dac)
df694daa 15979{
1c20930a
TI
15980 hda_nid_t mix, srcs[5];
15981 int i, num;
15982
564c5bea
JL
15983 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15984 pin_type);
1c20930a 15985 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15986 AMP_OUT_UNMUTE);
1c20930a
TI
15987 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15988 return;
15989 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15990 if (num < 0)
15991 return;
15992 for (i = 0; i < num; i++) {
15993 unsigned int mute;
15994 if (srcs[i] == dac || srcs[i] == 0x15)
15995 mute = AMP_IN_UNMUTE(i);
15996 else
15997 mute = AMP_IN_MUTE(i);
15998 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15999 mute);
16000 }
df694daa
KY
16001}
16002
16003static void alc861_auto_init_multi_out(struct hda_codec *codec)
16004{
16005 struct alc_spec *spec = codec->spec;
16006 int i;
16007
16008 for (i = 0; i < spec->autocfg.line_outs; i++) {
16009 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16010 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16011 if (nid)
baba8ee9 16012 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16013 spec->multiout.dac_nids[i]);
df694daa
KY
16014 }
16015}
16016
16017static void alc861_auto_init_hp_out(struct hda_codec *codec)
16018{
16019 struct alc_spec *spec = codec->spec;
df694daa 16020
15870f05
TI
16021 if (spec->autocfg.hp_outs)
16022 alc861_auto_set_output_and_unmute(codec,
16023 spec->autocfg.hp_pins[0],
16024 PIN_HP,
1c20930a 16025 spec->multiout.hp_nid);
15870f05
TI
16026 if (spec->autocfg.speaker_outs)
16027 alc861_auto_set_output_and_unmute(codec,
16028 spec->autocfg.speaker_pins[0],
16029 PIN_OUT,
1c20930a 16030 spec->multiout.dac_nids[0]);
df694daa
KY
16031}
16032
16033static void alc861_auto_init_analog_input(struct hda_codec *codec)
16034{
16035 struct alc_spec *spec = codec->spec;
66ceeb6b 16036 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16037 int i;
16038
66ceeb6b
TI
16039 for (i = 0; i < cfg->num_inputs; i++) {
16040 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16041 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16042 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16043 }
16044}
16045
16046/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16047/* return 1 if successful, 0 if the proper config is not found,
16048 * or a negative error code
16049 */
df694daa
KY
16050static int alc861_parse_auto_config(struct hda_codec *codec)
16051{
16052 struct alc_spec *spec = codec->spec;
16053 int err;
16054 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16055
f12ab1e0
TI
16056 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16057 alc861_ignore);
16058 if (err < 0)
df694daa 16059 return err;
f12ab1e0 16060 if (!spec->autocfg.line_outs)
df694daa
KY
16061 return 0; /* can't find valid BIOS pin config */
16062
1c20930a 16063 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
16064 if (err < 0)
16065 return err;
1c20930a 16066 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16067 if (err < 0)
16068 return err;
1c20930a 16069 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16070 if (err < 0)
16071 return err;
05f5f477 16072 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16073 if (err < 0)
df694daa
KY
16074 return err;
16075
16076 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16077
757899ac 16078 alc_auto_parse_digital(codec);
df694daa 16079
603c4019 16080 if (spec->kctls.list)
d88897ea 16081 add_mixer(spec, spec->kctls.list);
df694daa 16082
d88897ea 16083 add_verb(spec, alc861_auto_init_verbs);
df694daa 16084
a1e8d2da 16085 spec->num_mux_defs = 1;
61b9b9b1 16086 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16087
16088 spec->adc_nids = alc861_adc_nids;
16089 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16090 set_capture_mixer(codec);
df694daa 16091
6227cdce 16092 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16093
df694daa
KY
16094 return 1;
16095}
16096
ae6b813a
TI
16097/* additional initialization for auto-configuration model */
16098static void alc861_auto_init(struct hda_codec *codec)
df694daa 16099{
f6c7e546 16100 struct alc_spec *spec = codec->spec;
df694daa
KY
16101 alc861_auto_init_multi_out(codec);
16102 alc861_auto_init_hp_out(codec);
16103 alc861_auto_init_analog_input(codec);
757899ac 16104 alc_auto_init_digital(codec);
f6c7e546 16105 if (spec->unsol_event)
7fb0d78f 16106 alc_inithook(codec);
df694daa
KY
16107}
16108
cb53c626
TI
16109#ifdef CONFIG_SND_HDA_POWER_SAVE
16110static struct hda_amp_list alc861_loopbacks[] = {
16111 { 0x15, HDA_INPUT, 0 },
16112 { 0x15, HDA_INPUT, 1 },
16113 { 0x15, HDA_INPUT, 2 },
16114 { 0x15, HDA_INPUT, 3 },
16115 { } /* end */
16116};
16117#endif
16118
df694daa
KY
16119
16120/*
16121 * configuration and preset
16122 */
f5fcc13c
TI
16123static const char *alc861_models[ALC861_MODEL_LAST] = {
16124 [ALC861_3ST] = "3stack",
16125 [ALC660_3ST] = "3stack-660",
16126 [ALC861_3ST_DIG] = "3stack-dig",
16127 [ALC861_6ST_DIG] = "6stack-dig",
16128 [ALC861_UNIWILL_M31] = "uniwill-m31",
16129 [ALC861_TOSHIBA] = "toshiba",
16130 [ALC861_ASUS] = "asus",
16131 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16132 [ALC861_AUTO] = "auto",
16133};
16134
16135static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16136 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16137 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16138 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16139 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16140 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16141 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16142 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16143 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16144 * Any other models that need this preset?
16145 */
16146 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16147 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16148 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16149 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16150 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16151 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16152 /* FIXME: the below seems conflict */
16153 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16154 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16155 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16156 {}
16157};
16158
16159static struct alc_config_preset alc861_presets[] = {
16160 [ALC861_3ST] = {
16161 .mixers = { alc861_3ST_mixer },
16162 .init_verbs = { alc861_threestack_init_verbs },
16163 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16164 .dac_nids = alc861_dac_nids,
16165 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16166 .channel_mode = alc861_threestack_modes,
4e195a7b 16167 .need_dac_fix = 1,
df694daa
KY
16168 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16169 .adc_nids = alc861_adc_nids,
16170 .input_mux = &alc861_capture_source,
16171 },
16172 [ALC861_3ST_DIG] = {
16173 .mixers = { alc861_base_mixer },
16174 .init_verbs = { alc861_threestack_init_verbs },
16175 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16176 .dac_nids = alc861_dac_nids,
16177 .dig_out_nid = ALC861_DIGOUT_NID,
16178 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16179 .channel_mode = alc861_threestack_modes,
4e195a7b 16180 .need_dac_fix = 1,
df694daa
KY
16181 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16182 .adc_nids = alc861_adc_nids,
16183 .input_mux = &alc861_capture_source,
16184 },
16185 [ALC861_6ST_DIG] = {
16186 .mixers = { alc861_base_mixer },
16187 .init_verbs = { alc861_base_init_verbs },
16188 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16189 .dac_nids = alc861_dac_nids,
16190 .dig_out_nid = ALC861_DIGOUT_NID,
16191 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16192 .channel_mode = alc861_8ch_modes,
16193 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16194 .adc_nids = alc861_adc_nids,
16195 .input_mux = &alc861_capture_source,
16196 },
9c7f852e
TI
16197 [ALC660_3ST] = {
16198 .mixers = { alc861_3ST_mixer },
16199 .init_verbs = { alc861_threestack_init_verbs },
16200 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16201 .dac_nids = alc660_dac_nids,
16202 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16203 .channel_mode = alc861_threestack_modes,
4e195a7b 16204 .need_dac_fix = 1,
9c7f852e
TI
16205 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16206 .adc_nids = alc861_adc_nids,
16207 .input_mux = &alc861_capture_source,
16208 },
22309c3e
TI
16209 [ALC861_UNIWILL_M31] = {
16210 .mixers = { alc861_uniwill_m31_mixer },
16211 .init_verbs = { alc861_uniwill_m31_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_uniwill_m31_modes),
16216 .channel_mode = alc861_uniwill_m31_modes,
16217 .need_dac_fix = 1,
16218 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16219 .adc_nids = alc861_adc_nids,
16220 .input_mux = &alc861_capture_source,
16221 },
a53d1aec
TD
16222 [ALC861_TOSHIBA] = {
16223 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16224 .init_verbs = { alc861_base_init_verbs,
16225 alc861_toshiba_init_verbs },
a53d1aec
TD
16226 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16227 .dac_nids = alc861_dac_nids,
16228 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16229 .channel_mode = alc883_3ST_2ch_modes,
16230 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16231 .adc_nids = alc861_adc_nids,
16232 .input_mux = &alc861_capture_source,
16233 .unsol_event = alc861_toshiba_unsol_event,
16234 .init_hook = alc861_toshiba_automute,
16235 },
7cdbff94
MD
16236 [ALC861_ASUS] = {
16237 .mixers = { alc861_asus_mixer },
16238 .init_verbs = { alc861_asus_init_verbs },
16239 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16240 .dac_nids = alc861_dac_nids,
16241 .dig_out_nid = ALC861_DIGOUT_NID,
16242 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16243 .channel_mode = alc861_asus_modes,
16244 .need_dac_fix = 1,
16245 .hp_nid = 0x06,
16246 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16247 .adc_nids = alc861_adc_nids,
16248 .input_mux = &alc861_capture_source,
16249 },
56bb0cab
TI
16250 [ALC861_ASUS_LAPTOP] = {
16251 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16252 .init_verbs = { alc861_asus_init_verbs,
16253 alc861_asus_laptop_init_verbs },
16254 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16255 .dac_nids = alc861_dac_nids,
16256 .dig_out_nid = ALC861_DIGOUT_NID,
16257 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16258 .channel_mode = alc883_3ST_2ch_modes,
16259 .need_dac_fix = 1,
16260 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16261 .adc_nids = alc861_adc_nids,
16262 .input_mux = &alc861_capture_source,
16263 },
16264};
df694daa 16265
cfc9b06f
TI
16266/* Pin config fixes */
16267enum {
16268 PINFIX_FSC_AMILO_PI1505,
16269};
16270
cfc9b06f
TI
16271static const struct alc_fixup alc861_fixups[] = {
16272 [PINFIX_FSC_AMILO_PI1505] = {
73413b12
TI
16273 .pins = (const struct alc_pincfg[]) {
16274 { 0x0b, 0x0221101f }, /* HP */
16275 { 0x0f, 0x90170310 }, /* speaker */
16276 { }
16277 }
cfc9b06f
TI
16278 },
16279};
16280
16281static struct snd_pci_quirk alc861_fixup_tbl[] = {
16282 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16283 {}
16284};
df694daa
KY
16285
16286static int patch_alc861(struct hda_codec *codec)
16287{
16288 struct alc_spec *spec;
16289 int board_config;
16290 int err;
16291
dc041e0b 16292 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16293 if (spec == NULL)
16294 return -ENOMEM;
16295
f12ab1e0 16296 codec->spec = spec;
df694daa 16297
f5fcc13c
TI
16298 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16299 alc861_models,
16300 alc861_cfg_tbl);
9c7f852e 16301
f5fcc13c 16302 if (board_config < 0) {
9a11f1aa
TI
16303 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16304 codec->chip_name);
df694daa
KY
16305 board_config = ALC861_AUTO;
16306 }
16307
7fa90e87
TI
16308 if (board_config == ALC861_AUTO)
16309 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 16310
df694daa
KY
16311 if (board_config == ALC861_AUTO) {
16312 /* automatic parse from the BIOS config */
16313 err = alc861_parse_auto_config(codec);
16314 if (err < 0) {
16315 alc_free(codec);
16316 return err;
f12ab1e0 16317 } else if (!err) {
9c7f852e
TI
16318 printk(KERN_INFO
16319 "hda_codec: Cannot set up configuration "
16320 "from BIOS. Using base mode...\n");
df694daa
KY
16321 board_config = ALC861_3ST_DIG;
16322 }
16323 }
16324
680cd536
KK
16325 err = snd_hda_attach_beep_device(codec, 0x23);
16326 if (err < 0) {
16327 alc_free(codec);
16328 return err;
16329 }
16330
df694daa 16331 if (board_config != ALC861_AUTO)
e9c364c0 16332 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16333
df694daa
KY
16334 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16335 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16336
df694daa
KY
16337 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16338 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16339
c7a8eb10
TI
16340 if (!spec->cap_mixer)
16341 set_capture_mixer(codec);
45bdd1c1
TI
16342 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16343
2134ea4f
TI
16344 spec->vmaster_nid = 0x03;
16345
7fa90e87
TI
16346 if (board_config == ALC861_AUTO)
16347 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
16348
df694daa 16349 codec->patch_ops = alc_patch_ops;
c97259df 16350 if (board_config == ALC861_AUTO) {
ae6b813a 16351 spec->init_hook = alc861_auto_init;
c97259df
DC
16352#ifdef CONFIG_SND_HDA_POWER_SAVE
16353 spec->power_hook = alc_power_eapd;
16354#endif
16355 }
cb53c626
TI
16356#ifdef CONFIG_SND_HDA_POWER_SAVE
16357 if (!spec->loopback.amplist)
16358 spec->loopback.amplist = alc861_loopbacks;
16359#endif
ea1fb29a 16360
1da177e4
LT
16361 return 0;
16362}
16363
f32610ed
JS
16364/*
16365 * ALC861-VD support
16366 *
16367 * Based on ALC882
16368 *
16369 * In addition, an independent DAC
16370 */
16371#define ALC861VD_DIGOUT_NID 0x06
16372
16373static hda_nid_t alc861vd_dac_nids[4] = {
16374 /* front, surr, clfe, side surr */
16375 0x02, 0x03, 0x04, 0x05
16376};
16377
16378/* dac_nids for ALC660vd are in a different order - according to
16379 * Realtek's driver.
def319f9 16380 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16381 * of ALC660vd codecs, but for now there is only 3stack mixer
16382 * - and it is the same as in 861vd.
16383 * adc_nids in ALC660vd are (is) the same as in 861vd
16384 */
16385static hda_nid_t alc660vd_dac_nids[3] = {
16386 /* front, rear, clfe, rear_surr */
16387 0x02, 0x04, 0x03
16388};
16389
16390static hda_nid_t alc861vd_adc_nids[1] = {
16391 /* ADC0 */
16392 0x09,
16393};
16394
e1406348
TI
16395static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16396
f32610ed
JS
16397/* input MUX */
16398/* FIXME: should be a matrix-type input source selection */
16399static struct hda_input_mux alc861vd_capture_source = {
16400 .num_items = 4,
16401 .items = {
16402 { "Mic", 0x0 },
16403 { "Front Mic", 0x1 },
16404 { "Line", 0x2 },
16405 { "CD", 0x4 },
16406 },
16407};
16408
272a527c 16409static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16410 .num_items = 2,
272a527c 16411 .items = {
8607f7c4 16412 { "Mic", 0x0 },
28c4edb7 16413 { "Internal Mic", 0x1 },
272a527c
KY
16414 },
16415};
16416
d1a991a6
KY
16417static struct hda_input_mux alc861vd_hp_capture_source = {
16418 .num_items = 2,
16419 .items = {
16420 { "Front Mic", 0x0 },
16421 { "ATAPI Mic", 0x1 },
16422 },
16423};
16424
f32610ed
JS
16425/*
16426 * 2ch mode
16427 */
16428static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16429 { 2, NULL }
16430};
16431
16432/*
16433 * 6ch mode
16434 */
16435static struct hda_verb alc861vd_6stack_ch6_init[] = {
16436 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16437 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16438 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16439 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16440 { } /* end */
16441};
16442
16443/*
16444 * 8ch mode
16445 */
16446static struct hda_verb alc861vd_6stack_ch8_init[] = {
16447 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16448 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16449 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16450 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16451 { } /* end */
16452};
16453
16454static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16455 { 6, alc861vd_6stack_ch6_init },
16456 { 8, alc861vd_6stack_ch8_init },
16457};
16458
16459static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16460 {
16461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16462 .name = "Channel Mode",
16463 .info = alc_ch_mode_info,
16464 .get = alc_ch_mode_get,
16465 .put = alc_ch_mode_put,
16466 },
16467 { } /* end */
16468};
16469
f32610ed
JS
16470/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16471 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16472 */
16473static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16474 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16475 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16476
16477 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16478 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16479
16480 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16481 HDA_OUTPUT),
16482 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16483 HDA_OUTPUT),
16484 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16485 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16486
16487 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16488 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16489
16490 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16491
5f99f86a 16492 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16494 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16495
5f99f86a 16496 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16497 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16498 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16499
16500 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16501 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16502
16503 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16504 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16505
f32610ed
JS
16506 { } /* end */
16507};
16508
16509static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16510 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16511 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16512
16513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16514
5f99f86a 16515 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16516 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16517 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16518
5f99f86a 16519 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16520 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16521 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16522
16523 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16524 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16525
16526 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16527 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16528
f32610ed
JS
16529 { } /* end */
16530};
16531
bdd148a3
KY
16532static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16533 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16534 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16535 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
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),
bdd148a3
KY
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),
bdd148a3
KY
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("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16548 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16549
16550 { } /* end */
16551};
16552
b419f346 16553/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16554 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16555 */
16556static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16557 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16558 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16559 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16560 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16561 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16562 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16563 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16564 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16565 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16566 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16567 { } /* end */
16568};
16569
d1a991a6
KY
16570/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16571 * Front Mic=0x18, ATAPI Mic = 0x19,
16572 */
16573static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16574 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16575 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16576 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16577 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16578 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16579 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16580 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16581 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16582
d1a991a6
KY
16583 { } /* end */
16584};
16585
f32610ed
JS
16586/*
16587 * generic initialization of ADC, input mixers and output mixers
16588 */
16589static struct hda_verb alc861vd_volume_init_verbs[] = {
16590 /*
16591 * Unmute ADC0 and set the default input to mic-in
16592 */
16593 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16594 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16595
16596 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16597 * the analog-loopback mixer widget
16598 */
16599 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16605
16606 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16610 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16611
16612 /*
16613 * Set up output mixers (0x02 - 0x05)
16614 */
16615 /* set vol=0 to output mixers */
16616 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16617 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16618 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16619 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16620
16621 /* set up input amps for analog loopback */
16622 /* Amp Indices: DAC = 0, mixer = 1 */
16623 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16624 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16625 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16626 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16627 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16628 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16629 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16630 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16631
16632 { }
16633};
16634
16635/*
16636 * 3-stack pin configuration:
16637 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16638 */
16639static struct hda_verb alc861vd_3stack_init_verbs[] = {
16640 /*
16641 * Set pin mode and muting
16642 */
16643 /* set front pin widgets 0x14 for output */
16644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16646 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16647
16648 /* Mic (rear) pin: input vref at 80% */
16649 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16650 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16651 /* Front Mic pin: input vref at 80% */
16652 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16653 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16654 /* Line In pin: input */
16655 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16656 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16657 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16658 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16659 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16660 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16661 /* CD pin widget for input */
16662 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16663
16664 { }
16665};
16666
16667/*
16668 * 6-stack pin configuration:
16669 */
16670static struct hda_verb alc861vd_6stack_init_verbs[] = {
16671 /*
16672 * Set pin mode and muting
16673 */
16674 /* set front pin widgets 0x14 for output */
16675 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16676 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16677 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16678
16679 /* Rear Pin: output 1 (0x0d) */
16680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16682 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16683 /* CLFE Pin: output 2 (0x0e) */
16684 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16685 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16686 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16687 /* Side Pin: output 3 (0x0f) */
16688 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16689 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16690 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16691
16692 /* Mic (rear) pin: input vref at 80% */
16693 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16694 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16695 /* Front Mic pin: input vref at 80% */
16696 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16697 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16698 /* Line In pin: input */
16699 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16700 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16701 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16702 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16703 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16704 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16705 /* CD pin widget for input */
16706 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16707
16708 { }
16709};
16710
bdd148a3
KY
16711static struct hda_verb alc861vd_eapd_verbs[] = {
16712 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16713 { }
16714};
16715
f9423e7a
KY
16716static struct hda_verb alc660vd_eapd_verbs[] = {
16717 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16718 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16719 { }
16720};
16721
bdd148a3
KY
16722static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16726 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16727 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16728 {}
16729};
16730
4f5d1706 16731static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16732{
a9fd4f3f 16733 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16734 spec->autocfg.hp_pins[0] = 0x1b;
16735 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16736}
16737
16738static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16739{
a9fd4f3f 16740 alc_automute_amp(codec);
eeb43387 16741 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16742}
16743
16744static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16745 unsigned int res)
16746{
16747 switch (res >> 26) {
bdd148a3 16748 case ALC880_MIC_EVENT:
eeb43387 16749 alc88x_simple_mic_automute(codec);
bdd148a3 16750 break;
a9fd4f3f
TI
16751 default:
16752 alc_automute_amp_unsol_event(codec, res);
16753 break;
bdd148a3
KY
16754 }
16755}
16756
272a527c
KY
16757static struct hda_verb alc861vd_dallas_verbs[] = {
16758 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16759 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16760 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16761 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16762
16763 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16765 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16766 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16767 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16768 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16769 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16770 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16771
272a527c
KY
16772 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16773 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16774 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16775 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16776 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16777 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16778 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16779 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16780
16781 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16782 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16783 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16784 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16785 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16786 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16787 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16788 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16789
16790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16791 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16792 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16793 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16794
16795 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16796 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16797 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16798
16799 { } /* end */
16800};
16801
16802/* toggle speaker-output according to the hp-jack state */
4f5d1706 16803static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16804{
a9fd4f3f 16805 struct alc_spec *spec = codec->spec;
272a527c 16806
a9fd4f3f
TI
16807 spec->autocfg.hp_pins[0] = 0x15;
16808 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16809}
16810
cb53c626
TI
16811#ifdef CONFIG_SND_HDA_POWER_SAVE
16812#define alc861vd_loopbacks alc880_loopbacks
16813#endif
16814
def319f9 16815/* pcm configuration: identical with ALC880 */
f32610ed
JS
16816#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16817#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16818#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16819#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16820
16821/*
16822 * configuration and preset
16823 */
16824static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16825 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16826 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16827 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16828 [ALC861VD_3ST] = "3stack",
16829 [ALC861VD_3ST_DIG] = "3stack-digout",
16830 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16831 [ALC861VD_LENOVO] = "lenovo",
272a527c 16832 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16833 [ALC861VD_HP] = "hp",
f32610ed
JS
16834 [ALC861VD_AUTO] = "auto",
16835};
16836
16837static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16838 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16839 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16840 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16841 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16842 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16843 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16844 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16845 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16846 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16847 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16848 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16849 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16850 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16851 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16852 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16853 {}
16854};
16855
16856static struct alc_config_preset alc861vd_presets[] = {
16857 [ALC660VD_3ST] = {
16858 .mixers = { alc861vd_3st_mixer },
16859 .init_verbs = { alc861vd_volume_init_verbs,
16860 alc861vd_3stack_init_verbs },
16861 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16862 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16863 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16864 .channel_mode = alc861vd_3stack_2ch_modes,
16865 .input_mux = &alc861vd_capture_source,
16866 },
6963f84c
MC
16867 [ALC660VD_3ST_DIG] = {
16868 .mixers = { alc861vd_3st_mixer },
16869 .init_verbs = { alc861vd_volume_init_verbs,
16870 alc861vd_3stack_init_verbs },
16871 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16872 .dac_nids = alc660vd_dac_nids,
16873 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16874 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16875 .channel_mode = alc861vd_3stack_2ch_modes,
16876 .input_mux = &alc861vd_capture_source,
16877 },
f32610ed
JS
16878 [ALC861VD_3ST] = {
16879 .mixers = { alc861vd_3st_mixer },
16880 .init_verbs = { alc861vd_volume_init_verbs,
16881 alc861vd_3stack_init_verbs },
16882 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16883 .dac_nids = alc861vd_dac_nids,
16884 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16885 .channel_mode = alc861vd_3stack_2ch_modes,
16886 .input_mux = &alc861vd_capture_source,
16887 },
16888 [ALC861VD_3ST_DIG] = {
16889 .mixers = { alc861vd_3st_mixer },
16890 .init_verbs = { alc861vd_volume_init_verbs,
16891 alc861vd_3stack_init_verbs },
16892 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16893 .dac_nids = alc861vd_dac_nids,
16894 .dig_out_nid = ALC861VD_DIGOUT_NID,
16895 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16896 .channel_mode = alc861vd_3stack_2ch_modes,
16897 .input_mux = &alc861vd_capture_source,
16898 },
16899 [ALC861VD_6ST_DIG] = {
16900 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16901 .init_verbs = { alc861vd_volume_init_verbs,
16902 alc861vd_6stack_init_verbs },
16903 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16904 .dac_nids = alc861vd_dac_nids,
16905 .dig_out_nid = ALC861VD_DIGOUT_NID,
16906 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16907 .channel_mode = alc861vd_6stack_modes,
16908 .input_mux = &alc861vd_capture_source,
16909 },
bdd148a3
KY
16910 [ALC861VD_LENOVO] = {
16911 .mixers = { alc861vd_lenovo_mixer },
16912 .init_verbs = { alc861vd_volume_init_verbs,
16913 alc861vd_3stack_init_verbs,
16914 alc861vd_eapd_verbs,
16915 alc861vd_lenovo_unsol_verbs },
16916 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16917 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16918 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16919 .channel_mode = alc861vd_3stack_2ch_modes,
16920 .input_mux = &alc861vd_capture_source,
16921 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16922 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16923 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16924 },
272a527c
KY
16925 [ALC861VD_DALLAS] = {
16926 .mixers = { alc861vd_dallas_mixer },
16927 .init_verbs = { alc861vd_dallas_verbs },
16928 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16929 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16930 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16931 .channel_mode = alc861vd_3stack_2ch_modes,
16932 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16933 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16934 .setup = alc861vd_dallas_setup,
16935 .init_hook = alc_automute_amp,
d1a991a6
KY
16936 },
16937 [ALC861VD_HP] = {
16938 .mixers = { alc861vd_hp_mixer },
16939 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16940 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16941 .dac_nids = alc861vd_dac_nids,
d1a991a6 16942 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16943 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16944 .channel_mode = alc861vd_3stack_2ch_modes,
16945 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16946 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16947 .setup = alc861vd_dallas_setup,
16948 .init_hook = alc_automute_amp,
ea1fb29a 16949 },
13c94744
TI
16950 [ALC660VD_ASUS_V1S] = {
16951 .mixers = { alc861vd_lenovo_mixer },
16952 .init_verbs = { alc861vd_volume_init_verbs,
16953 alc861vd_3stack_init_verbs,
16954 alc861vd_eapd_verbs,
16955 alc861vd_lenovo_unsol_verbs },
16956 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16957 .dac_nids = alc660vd_dac_nids,
16958 .dig_out_nid = ALC861VD_DIGOUT_NID,
16959 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16960 .channel_mode = alc861vd_3stack_2ch_modes,
16961 .input_mux = &alc861vd_capture_source,
16962 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16963 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16964 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16965 },
f32610ed
JS
16966};
16967
16968/*
16969 * BIOS auto configuration
16970 */
05f5f477
TI
16971static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16972 const struct auto_pin_cfg *cfg)
16973{
7167594a 16974 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
16975}
16976
16977
f32610ed
JS
16978static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16979 hda_nid_t nid, int pin_type, int dac_idx)
16980{
f6c7e546 16981 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16982}
16983
16984static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16985{
16986 struct alc_spec *spec = codec->spec;
16987 int i;
16988
16989 for (i = 0; i <= HDA_SIDE; i++) {
16990 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16991 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16992 if (nid)
16993 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16994 pin_type, i);
f32610ed
JS
16995 }
16996}
16997
16998
16999static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17000{
17001 struct alc_spec *spec = codec->spec;
17002 hda_nid_t pin;
17003
17004 pin = spec->autocfg.hp_pins[0];
def319f9 17005 if (pin) /* connect to front and use dac 0 */
f32610ed 17006 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17007 pin = spec->autocfg.speaker_pins[0];
17008 if (pin)
17009 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17010}
17011
f32610ed
JS
17012#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17013
17014static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17015{
17016 struct alc_spec *spec = codec->spec;
66ceeb6b 17017 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17018 int i;
17019
66ceeb6b
TI
17020 for (i = 0; i < cfg->num_inputs; i++) {
17021 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17022 if (alc_is_input_pin(codec, nid)) {
30ea098f 17023 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17024 if (nid != ALC861VD_PIN_CD_NID &&
17025 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17026 snd_hda_codec_write(codec, nid, 0,
17027 AC_VERB_SET_AMP_GAIN_MUTE,
17028 AMP_OUT_MUTE);
17029 }
17030 }
17031}
17032
f511b01c
TI
17033#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17034
f32610ed
JS
17035#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17036#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17037
17038/* add playback controls from the parsed DAC table */
17039/* Based on ALC880 version. But ALC861VD has separate,
17040 * different NIDs for mute/unmute switch and volume control */
17041static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17042 const struct auto_pin_cfg *cfg)
17043{
f32610ed 17044 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
bcb2f0f5 17045 const char *pfx = alc_get_line_out_pfx(cfg, true);
f32610ed
JS
17046 hda_nid_t nid_v, nid_s;
17047 int i, err;
17048
17049 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 17050 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17051 continue;
17052 nid_v = alc861vd_idx_to_mixer_vol(
17053 alc880_dac_to_idx(
17054 spec->multiout.dac_nids[i]));
17055 nid_s = alc861vd_idx_to_mixer_switch(
17056 alc880_dac_to_idx(
17057 spec->multiout.dac_nids[i]));
17058
bcb2f0f5 17059 if (!pfx && i == 2) {
f32610ed 17060 /* Center/LFE */
0afe5f89
TI
17061 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17062 "Center",
f12ab1e0
TI
17063 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17064 HDA_OUTPUT));
17065 if (err < 0)
f32610ed 17066 return err;
0afe5f89
TI
17067 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17068 "LFE",
f12ab1e0
TI
17069 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17070 HDA_OUTPUT));
17071 if (err < 0)
f32610ed 17072 return err;
0afe5f89
TI
17073 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17074 "Center",
f12ab1e0
TI
17075 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17076 HDA_INPUT));
17077 if (err < 0)
f32610ed 17078 return err;
0afe5f89
TI
17079 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17080 "LFE",
f12ab1e0
TI
17081 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17082 HDA_INPUT));
17083 if (err < 0)
f32610ed
JS
17084 return err;
17085 } else {
bcb2f0f5
TI
17086 const char *name = pfx;
17087 if (!name)
17088 name = chname[i];
17089 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17090 name, i,
f12ab1e0
TI
17091 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17092 HDA_OUTPUT));
17093 if (err < 0)
f32610ed 17094 return err;
bcb2f0f5
TI
17095 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17096 name, i,
bdd148a3 17097 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17098 HDA_INPUT));
17099 if (err < 0)
f32610ed
JS
17100 return err;
17101 }
17102 }
17103 return 0;
17104}
17105
17106/* add playback controls for speaker and HP outputs */
17107/* Based on ALC880 version. But ALC861VD has separate,
17108 * different NIDs for mute/unmute switch and volume control */
17109static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17110 hda_nid_t pin, const char *pfx)
17111{
17112 hda_nid_t nid_v, nid_s;
17113 int err;
f32610ed 17114
f12ab1e0 17115 if (!pin)
f32610ed
JS
17116 return 0;
17117
17118 if (alc880_is_fixed_pin(pin)) {
17119 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17120 /* specify the DAC as the extra output */
f12ab1e0 17121 if (!spec->multiout.hp_nid)
f32610ed
JS
17122 spec->multiout.hp_nid = nid_v;
17123 else
17124 spec->multiout.extra_out_nid[0] = nid_v;
17125 /* control HP volume/switch on the output mixer amp */
17126 nid_v = alc861vd_idx_to_mixer_vol(
17127 alc880_fixed_pin_idx(pin));
17128 nid_s = alc861vd_idx_to_mixer_switch(
17129 alc880_fixed_pin_idx(pin));
17130
0afe5f89 17131 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17132 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17133 if (err < 0)
f32610ed 17134 return err;
0afe5f89 17135 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17136 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17137 if (err < 0)
f32610ed
JS
17138 return err;
17139 } else if (alc880_is_multi_pin(pin)) {
17140 /* set manual connection */
17141 /* we have only a switch on HP-out PIN */
0afe5f89 17142 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17143 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17144 if (err < 0)
f32610ed
JS
17145 return err;
17146 }
17147 return 0;
17148}
17149
17150/* parse the BIOS configuration and set up the alc_spec
17151 * return 1 if successful, 0 if the proper config is not found,
17152 * or a negative error code
17153 * Based on ALC880 version - had to change it to override
17154 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17155static int alc861vd_parse_auto_config(struct hda_codec *codec)
17156{
17157 struct alc_spec *spec = codec->spec;
17158 int err;
17159 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17160
f12ab1e0
TI
17161 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17162 alc861vd_ignore);
17163 if (err < 0)
f32610ed 17164 return err;
f12ab1e0 17165 if (!spec->autocfg.line_outs)
f32610ed
JS
17166 return 0; /* can't find valid BIOS pin config */
17167
f12ab1e0
TI
17168 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17169 if (err < 0)
17170 return err;
17171 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17172 if (err < 0)
17173 return err;
17174 err = alc861vd_auto_create_extra_out(spec,
17175 spec->autocfg.speaker_pins[0],
17176 "Speaker");
17177 if (err < 0)
17178 return err;
17179 err = alc861vd_auto_create_extra_out(spec,
17180 spec->autocfg.hp_pins[0],
17181 "Headphone");
17182 if (err < 0)
17183 return err;
05f5f477 17184 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17185 if (err < 0)
f32610ed
JS
17186 return err;
17187
17188 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17189
757899ac 17190 alc_auto_parse_digital(codec);
f32610ed 17191
603c4019 17192 if (spec->kctls.list)
d88897ea 17193 add_mixer(spec, spec->kctls.list);
f32610ed 17194
d88897ea 17195 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17196
17197 spec->num_mux_defs = 1;
61b9b9b1 17198 spec->input_mux = &spec->private_imux[0];
f32610ed 17199
776e184e
TI
17200 err = alc_auto_add_mic_boost(codec);
17201 if (err < 0)
17202 return err;
17203
6227cdce 17204 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17205
f32610ed
JS
17206 return 1;
17207}
17208
17209/* additional initialization for auto-configuration model */
17210static void alc861vd_auto_init(struct hda_codec *codec)
17211{
f6c7e546 17212 struct alc_spec *spec = codec->spec;
f32610ed
JS
17213 alc861vd_auto_init_multi_out(codec);
17214 alc861vd_auto_init_hp_out(codec);
17215 alc861vd_auto_init_analog_input(codec);
f511b01c 17216 alc861vd_auto_init_input_src(codec);
757899ac 17217 alc_auto_init_digital(codec);
f6c7e546 17218 if (spec->unsol_event)
7fb0d78f 17219 alc_inithook(codec);
f32610ed
JS
17220}
17221
f8f25ba3
TI
17222enum {
17223 ALC660VD_FIX_ASUS_GPIO1
17224};
17225
17226/* reset GPIO1 */
f8f25ba3
TI
17227static const struct alc_fixup alc861vd_fixups[] = {
17228 [ALC660VD_FIX_ASUS_GPIO1] = {
73413b12
TI
17229 .verbs = (const struct hda_verb[]) {
17230 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17231 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17232 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17233 { }
17234 }
f8f25ba3
TI
17235 },
17236};
17237
17238static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17239 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17240 {}
17241};
17242
f32610ed
JS
17243static int patch_alc861vd(struct hda_codec *codec)
17244{
17245 struct alc_spec *spec;
17246 int err, board_config;
17247
17248 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17249 if (spec == NULL)
17250 return -ENOMEM;
17251
17252 codec->spec = spec;
17253
17254 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17255 alc861vd_models,
17256 alc861vd_cfg_tbl);
17257
17258 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17259 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17260 codec->chip_name);
f32610ed
JS
17261 board_config = ALC861VD_AUTO;
17262 }
17263
7fa90e87
TI
17264 if (board_config == ALC861VD_AUTO)
17265 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 17266
f32610ed
JS
17267 if (board_config == ALC861VD_AUTO) {
17268 /* automatic parse from the BIOS config */
17269 err = alc861vd_parse_auto_config(codec);
17270 if (err < 0) {
17271 alc_free(codec);
17272 return err;
f12ab1e0 17273 } else if (!err) {
f32610ed
JS
17274 printk(KERN_INFO
17275 "hda_codec: Cannot set up configuration "
17276 "from BIOS. Using base mode...\n");
17277 board_config = ALC861VD_3ST;
17278 }
17279 }
17280
680cd536
KK
17281 err = snd_hda_attach_beep_device(codec, 0x23);
17282 if (err < 0) {
17283 alc_free(codec);
17284 return err;
17285 }
17286
f32610ed 17287 if (board_config != ALC861VD_AUTO)
e9c364c0 17288 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17289
2f893286 17290 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17291 /* always turn on EAPD */
d88897ea 17292 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17293 }
17294
f32610ed
JS
17295 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17296 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17297
f32610ed
JS
17298 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17299 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17300
dd704698
TI
17301 if (!spec->adc_nids) {
17302 spec->adc_nids = alc861vd_adc_nids;
17303 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17304 }
17305 if (!spec->capsrc_nids)
17306 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17307
b59bdf3b 17308 set_capture_mixer(codec);
45bdd1c1 17309 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17310
2134ea4f
TI
17311 spec->vmaster_nid = 0x02;
17312
7fa90e87
TI
17313 if (board_config == ALC861VD_AUTO)
17314 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
17315
f32610ed
JS
17316 codec->patch_ops = alc_patch_ops;
17317
17318 if (board_config == ALC861VD_AUTO)
17319 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17320#ifdef CONFIG_SND_HDA_POWER_SAVE
17321 if (!spec->loopback.amplist)
17322 spec->loopback.amplist = alc861vd_loopbacks;
17323#endif
f32610ed
JS
17324
17325 return 0;
17326}
17327
bc9f98a9
KY
17328/*
17329 * ALC662 support
17330 *
17331 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17332 * configuration. Each pin widget can choose any input DACs and a mixer.
17333 * Each ADC is connected from a mixer of all inputs. This makes possible
17334 * 6-channel independent captures.
17335 *
17336 * In addition, an independent DAC for the multi-playback (not used in this
17337 * driver yet).
17338 */
17339#define ALC662_DIGOUT_NID 0x06
17340#define ALC662_DIGIN_NID 0x0a
17341
17342static hda_nid_t alc662_dac_nids[4] = {
17343 /* front, rear, clfe, rear_surr */
17344 0x02, 0x03, 0x04
17345};
17346
622e84cd
KY
17347static hda_nid_t alc272_dac_nids[2] = {
17348 0x02, 0x03
17349};
17350
b59bdf3b 17351static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17352 /* ADC1-2 */
b59bdf3b 17353 0x09, 0x08
bc9f98a9 17354};
e1406348 17355
622e84cd
KY
17356static hda_nid_t alc272_adc_nids[1] = {
17357 /* ADC1-2 */
17358 0x08,
17359};
17360
b59bdf3b 17361static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17362static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17363
e1406348 17364
bc9f98a9
KY
17365/* input MUX */
17366/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17367static struct hda_input_mux alc662_capture_source = {
17368 .num_items = 4,
17369 .items = {
17370 { "Mic", 0x0 },
17371 { "Front Mic", 0x1 },
17372 { "Line", 0x2 },
17373 { "CD", 0x4 },
17374 },
17375};
17376
17377static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17378 .num_items = 2,
17379 .items = {
17380 { "Mic", 0x1 },
17381 { "Line", 0x2 },
17382 },
17383};
291702f0 17384
6dda9f4a
KY
17385static struct hda_input_mux alc663_capture_source = {
17386 .num_items = 3,
17387 .items = {
17388 { "Mic", 0x0 },
17389 { "Front Mic", 0x1 },
17390 { "Line", 0x2 },
17391 },
17392};
17393
4f5d1706 17394#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17395static struct hda_input_mux alc272_nc10_capture_source = {
17396 .num_items = 16,
17397 .items = {
17398 { "Autoselect Mic", 0x0 },
17399 { "Internal Mic", 0x1 },
17400 { "In-0x02", 0x2 },
17401 { "In-0x03", 0x3 },
17402 { "In-0x04", 0x4 },
17403 { "In-0x05", 0x5 },
17404 { "In-0x06", 0x6 },
17405 { "In-0x07", 0x7 },
17406 { "In-0x08", 0x8 },
17407 { "In-0x09", 0x9 },
17408 { "In-0x0a", 0x0a },
17409 { "In-0x0b", 0x0b },
17410 { "In-0x0c", 0x0c },
17411 { "In-0x0d", 0x0d },
17412 { "In-0x0e", 0x0e },
17413 { "In-0x0f", 0x0f },
17414 },
17415};
17416#endif
17417
bc9f98a9
KY
17418/*
17419 * 2ch mode
17420 */
17421static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17422 { 2, NULL }
17423};
17424
17425/*
17426 * 2ch mode
17427 */
17428static struct hda_verb alc662_3ST_ch2_init[] = {
17429 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17430 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17431 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17432 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17433 { } /* end */
17434};
17435
17436/*
17437 * 6ch mode
17438 */
17439static struct hda_verb alc662_3ST_ch6_init[] = {
17440 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17441 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17442 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17443 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17444 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17445 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17446 { } /* end */
17447};
17448
17449static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17450 { 2, alc662_3ST_ch2_init },
17451 { 6, alc662_3ST_ch6_init },
17452};
17453
17454/*
17455 * 2ch mode
17456 */
17457static struct hda_verb alc662_sixstack_ch6_init[] = {
17458 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17459 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17460 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17461 { } /* end */
17462};
17463
17464/*
17465 * 6ch mode
17466 */
17467static struct hda_verb alc662_sixstack_ch8_init[] = {
17468 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17469 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17470 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17471 { } /* end */
17472};
17473
17474static struct hda_channel_mode alc662_5stack_modes[2] = {
17475 { 2, alc662_sixstack_ch6_init },
17476 { 6, alc662_sixstack_ch8_init },
17477};
17478
17479/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17480 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17481 */
17482
17483static struct snd_kcontrol_new alc662_base_mixer[] = {
17484 /* output mixer control */
17485 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17486 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17487 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17488 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17489 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17490 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17491 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17492 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17493 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17494
17495 /*Input mixer control */
17496 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17497 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17498 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17499 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17500 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17501 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17502 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17503 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17504 { } /* end */
17505};
17506
17507static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17508 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17509 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17510 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17511 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17512 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17513 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17514 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17515 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17516 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17517 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17518 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17519 { } /* end */
17520};
17521
17522static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17523 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17524 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17525 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17526 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17527 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17528 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17529 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17530 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17531 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17532 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17533 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17534 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17535 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17536 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17537 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17538 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17539 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17540 { } /* end */
17541};
17542
17543static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17544 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17545 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17546 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17547 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17548 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17549 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17550 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17551 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17552 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17553 { } /* end */
17554};
17555
291702f0 17556static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17557 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17558 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17559
5f99f86a 17560 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17561 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17562 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17563
5f99f86a 17564 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17565 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17566 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17567 { } /* end */
17568};
17569
8c427226 17570static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17571 ALC262_HIPPO_MASTER_SWITCH,
17572 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17573 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17574 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17575 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17576 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17577 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17578 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17579 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17580 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17581 { } /* end */
17582};
17583
f1d4e28b
KY
17584static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17585 .ops = &snd_hda_bind_vol,
17586 .values = {
17587 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17588 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17589 0
17590 },
17591};
17592
17593static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17594 .ops = &snd_hda_bind_sw,
17595 .values = {
17596 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17597 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17598 0
17599 },
17600};
17601
6dda9f4a 17602static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17603 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17604 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17605 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17606 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17607 { } /* end */
17608};
17609
17610static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17611 .ops = &snd_hda_bind_sw,
17612 .values = {
17613 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17614 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17615 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17616 0
17617 },
17618};
17619
17620static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17621 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17622 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17624 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17625 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17626 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17627
17628 { } /* end */
17629};
17630
17631static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17632 .ops = &snd_hda_bind_sw,
17633 .values = {
17634 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17635 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17636 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17637 0
17638 },
17639};
17640
17641static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17642 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17643 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17644 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17645 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17646 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17647 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17648 { } /* end */
17649};
17650
17651static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17652 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17653 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17654 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17657 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17658 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17659 { } /* end */
17660};
17661
17662static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17663 .ops = &snd_hda_bind_vol,
17664 .values = {
17665 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17666 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17667 0
17668 },
17669};
17670
17671static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17672 .ops = &snd_hda_bind_sw,
17673 .values = {
17674 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17675 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17676 0
17677 },
17678};
17679
17680static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17681 HDA_BIND_VOL("Master Playback Volume",
17682 &alc663_asus_two_bind_master_vol),
17683 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17686 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17687 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17688 { } /* end */
17689};
17690
17691static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17692 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17693 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17694 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17695 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17696 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17697 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17698 { } /* end */
17699};
17700
17701static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17702 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17703 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17704 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17705 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17706 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17707
17708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17710 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17711 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17712 { } /* end */
17713};
17714
17715static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17716 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17717 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17718 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17719
17720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17722 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17723 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17724 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17725 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17726 { } /* end */
17727};
17728
ebb83eeb
KY
17729static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17730 .ops = &snd_hda_bind_sw,
17731 .values = {
17732 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17733 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17734 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17735 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17736 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17737 0
17738 },
17739};
17740
17741static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17742 .ops = &snd_hda_bind_sw,
17743 .values = {
17744 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17745 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17746 0
17747 },
17748};
17749
17750static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17751 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17752 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17753 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17754 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17755 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17756 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17757 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17759 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17760 { } /* end */
17761};
17762
17763static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17764 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17765 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17766 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17767 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17768 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17771 { } /* end */
17772};
17773
17774
bc9f98a9
KY
17775static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17776 {
17777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17778 .name = "Channel Mode",
17779 .info = alc_ch_mode_info,
17780 .get = alc_ch_mode_get,
17781 .put = alc_ch_mode_put,
17782 },
17783 { } /* end */
17784};
17785
17786static struct hda_verb alc662_init_verbs[] = {
17787 /* ADC: mute amp left and right */
17788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17789 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17790
b60dd394
KY
17791 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17792 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17793 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17794 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17795 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17796 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17797
17798 /* Front Pin: output 0 (0x0c) */
17799 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17800 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17801
17802 /* Rear Pin: output 1 (0x0d) */
17803 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17804 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17805
17806 /* CLFE Pin: output 2 (0x0e) */
17807 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17808 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17809
17810 /* Mic (rear) pin: input vref at 80% */
17811 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17812 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17813 /* Front Mic pin: input vref at 80% */
17814 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17815 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17816 /* Line In pin: input */
17817 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17818 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17819 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17820 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17821 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17822 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17823 /* CD pin widget for input */
17824 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17825
17826 /* FIXME: use matrix-type input source selection */
17827 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17828 /* Input mixer */
17829 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17830 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17831
17832 /* always trun on EAPD */
17833 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17834 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17835
bc9f98a9
KY
17836 { }
17837};
17838
cec27c89
KY
17839static struct hda_verb alc663_init_verbs[] = {
17840 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17841 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17842 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17843 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17844 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17845 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17846 { }
17847};
17848
17849static struct hda_verb alc272_init_verbs[] = {
17850 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17851 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17852 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17853 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17854 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17855 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17856 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17857 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17858 { }
17859};
17860
bc9f98a9
KY
17861static struct hda_verb alc662_sue_init_verbs[] = {
17862 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17863 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17864 {}
17865};
17866
17867static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17868 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17869 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17870 {}
bc9f98a9
KY
17871};
17872
8c427226
KY
17873/* Set Unsolicited Event*/
17874static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17875 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17876 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17877 {}
17878};
17879
6dda9f4a 17880static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17881 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17882 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17883 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17884 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17885 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17886 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17887 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17888 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17889 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17890 {}
17891};
17892
17893static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17894 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17895 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17896 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17897 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17898 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17899 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17900 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17901 {}
17902};
17903
17904static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17905 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17906 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17907 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17908 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17909 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17911 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17912 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17913 {}
17914};
6dda9f4a 17915
f1d4e28b
KY
17916static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17917 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17918 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17919 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17920 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17921 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17922 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17923 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17924 {}
17925};
6dda9f4a 17926
f1d4e28b
KY
17927static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17928 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17929 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17930 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17931 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17932 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17933 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17934 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17935 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17937 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17938 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17939 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17940 {}
17941};
17942
17943static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17944 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17945 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17946 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17947 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17948 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17949 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17950 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17951 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17953 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17954 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17955 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17956 {}
17957};
17958
17959static struct hda_verb alc663_g71v_init_verbs[] = {
17960 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17961 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17962 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17963
17964 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17965 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17966 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17967
17968 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17969 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17970 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17971 {}
17972};
17973
17974static struct hda_verb alc663_g50v_init_verbs[] = {
17975 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17976 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17977 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17978
17979 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17980 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17981 {}
17982};
17983
f1d4e28b
KY
17984static struct hda_verb alc662_ecs_init_verbs[] = {
17985 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17986 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17987 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17988 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17989 {}
17990};
17991
622e84cd
KY
17992static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17993 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17994 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17995 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17996 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17997 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17998 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17999 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18000 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18001 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18002 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18003 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18004 {}
18005};
18006
18007static struct hda_verb alc272_dell_init_verbs[] = {
18008 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18009 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18010 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18011 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18012 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18013 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18014 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18015 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18016 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18017 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18018 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18019 {}
18020};
18021
ebb83eeb
KY
18022static struct hda_verb alc663_mode7_init_verbs[] = {
18023 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18024 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18025 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18026 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18027 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18028 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18029 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18030 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18031 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18032 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18034 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18035 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18036 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18037 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18038 {}
18039};
18040
18041static struct hda_verb alc663_mode8_init_verbs[] = {
18042 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18043 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18044 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18045 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18046 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18047 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18048 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18049 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18050 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18051 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18052 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18054 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18055 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18056 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18057 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18058 {}
18059};
18060
f1d4e28b
KY
18061static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18062 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18063 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18064 { } /* end */
18065};
18066
622e84cd
KY
18067static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18068 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18069 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18070 { } /* end */
18071};
18072
bc9f98a9
KY
18073static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18074{
18075 unsigned int present;
f12ab1e0 18076 unsigned char bits;
bc9f98a9 18077
864f92be 18078 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 18079 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18080
47fd830a
TI
18081 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18082 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18083}
18084
18085static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18086{
18087 unsigned int present;
f12ab1e0 18088 unsigned char bits;
bc9f98a9 18089
864f92be 18090 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 18091 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18092
47fd830a
TI
18093 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18094 HDA_AMP_MUTE, bits);
18095 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18096 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18097}
18098
18099static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18100 unsigned int res)
18101{
18102 if ((res >> 26) == ALC880_HP_EVENT)
18103 alc662_lenovo_101e_all_automute(codec);
18104 if ((res >> 26) == ALC880_FRONT_EVENT)
18105 alc662_lenovo_101e_ispeaker_automute(codec);
18106}
18107
291702f0
KY
18108/* unsolicited event for HP jack sensing */
18109static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18110 unsigned int res)
18111{
291702f0 18112 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18113 alc_mic_automute(codec);
42171c17
TI
18114 else
18115 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18116}
18117
4f5d1706
TI
18118static void alc662_eeepc_setup(struct hda_codec *codec)
18119{
18120 struct alc_spec *spec = codec->spec;
18121
18122 alc262_hippo1_setup(codec);
18123 spec->ext_mic.pin = 0x18;
18124 spec->ext_mic.mux_idx = 0;
18125 spec->int_mic.pin = 0x19;
18126 spec->int_mic.mux_idx = 1;
18127 spec->auto_mic = 1;
18128}
18129
291702f0
KY
18130static void alc662_eeepc_inithook(struct hda_codec *codec)
18131{
4f5d1706
TI
18132 alc262_hippo_automute(codec);
18133 alc_mic_automute(codec);
291702f0
KY
18134}
18135
4f5d1706 18136static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18137{
42171c17
TI
18138 struct alc_spec *spec = codec->spec;
18139
18140 spec->autocfg.hp_pins[0] = 0x14;
18141 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18142}
18143
4f5d1706
TI
18144#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18145
6dda9f4a
KY
18146static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18147{
18148 unsigned int present;
18149 unsigned char bits;
18150
864f92be 18151 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18152 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18153 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18154 HDA_AMP_MUTE, bits);
f1d4e28b 18155 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18156 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18157}
18158
18159static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18160{
18161 unsigned int present;
18162 unsigned char bits;
18163
864f92be 18164 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18165 bits = present ? HDA_AMP_MUTE : 0;
18166 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18167 HDA_AMP_MUTE, bits);
f1d4e28b 18168 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18169 HDA_AMP_MUTE, bits);
f1d4e28b 18170 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18171 HDA_AMP_MUTE, bits);
f1d4e28b 18172 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18173 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18174}
18175
18176static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18177{
18178 unsigned int present;
18179 unsigned char bits;
18180
864f92be 18181 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18182 bits = present ? HDA_AMP_MUTE : 0;
18183 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18184 HDA_AMP_MUTE, bits);
f1d4e28b 18185 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18186 HDA_AMP_MUTE, bits);
f1d4e28b 18187 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18188 HDA_AMP_MUTE, bits);
f1d4e28b 18189 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18190 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18191}
18192
18193static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18194{
18195 unsigned int present;
18196 unsigned char bits;
18197
864f92be 18198 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18199 bits = present ? 0 : PIN_OUT;
18200 snd_hda_codec_write(codec, 0x14, 0,
18201 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18202}
18203
18204static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18205{
18206 unsigned int present1, present2;
18207
864f92be
WF
18208 present1 = snd_hda_jack_detect(codec, 0x21);
18209 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18210
18211 if (present1 || present2) {
18212 snd_hda_codec_write_cache(codec, 0x14, 0,
18213 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18214 } else {
18215 snd_hda_codec_write_cache(codec, 0x14, 0,
18216 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18217 }
18218}
18219
18220static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18221{
18222 unsigned int present1, present2;
18223
864f92be
WF
18224 present1 = snd_hda_jack_detect(codec, 0x1b);
18225 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18226
18227 if (present1 || present2) {
18228 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18229 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18230 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18231 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18232 } else {
18233 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18234 HDA_AMP_MUTE, 0);
f1d4e28b 18235 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18236 HDA_AMP_MUTE, 0);
f1d4e28b 18237 }
6dda9f4a
KY
18238}
18239
ebb83eeb
KY
18240static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18241{
18242 unsigned int present1, present2;
18243
18244 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18245 AC_VERB_GET_PIN_SENSE, 0)
18246 & AC_PINSENSE_PRESENCE;
18247 present2 = snd_hda_codec_read(codec, 0x21, 0,
18248 AC_VERB_GET_PIN_SENSE, 0)
18249 & AC_PINSENSE_PRESENCE;
18250
18251 if (present1 || present2) {
18252 snd_hda_codec_write_cache(codec, 0x14, 0,
18253 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18254 snd_hda_codec_write_cache(codec, 0x17, 0,
18255 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18256 } else {
18257 snd_hda_codec_write_cache(codec, 0x14, 0,
18258 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18259 snd_hda_codec_write_cache(codec, 0x17, 0,
18260 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18261 }
18262}
18263
18264static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18265{
18266 unsigned int present1, present2;
18267
18268 present1 = snd_hda_codec_read(codec, 0x21, 0,
18269 AC_VERB_GET_PIN_SENSE, 0)
18270 & AC_PINSENSE_PRESENCE;
18271 present2 = snd_hda_codec_read(codec, 0x15, 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
6dda9f4a
KY
18288static void alc663_m51va_unsol_event(struct hda_codec *codec,
18289 unsigned int res)
18290{
18291 switch (res >> 26) {
18292 case ALC880_HP_EVENT:
18293 alc663_m51va_speaker_automute(codec);
18294 break;
18295 case ALC880_MIC_EVENT:
4f5d1706 18296 alc_mic_automute(codec);
6dda9f4a
KY
18297 break;
18298 }
18299}
18300
4f5d1706
TI
18301static void alc663_m51va_setup(struct hda_codec *codec)
18302{
18303 struct alc_spec *spec = codec->spec;
18304 spec->ext_mic.pin = 0x18;
18305 spec->ext_mic.mux_idx = 0;
18306 spec->int_mic.pin = 0x12;
ebb83eeb 18307 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18308 spec->auto_mic = 1;
18309}
18310
6dda9f4a
KY
18311static void alc663_m51va_inithook(struct hda_codec *codec)
18312{
18313 alc663_m51va_speaker_automute(codec);
4f5d1706 18314 alc_mic_automute(codec);
6dda9f4a
KY
18315}
18316
f1d4e28b 18317/* ***************** Mode1 ******************************/
4f5d1706 18318#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18319
18320static void alc663_mode1_setup(struct hda_codec *codec)
18321{
18322 struct alc_spec *spec = codec->spec;
18323 spec->ext_mic.pin = 0x18;
18324 spec->ext_mic.mux_idx = 0;
18325 spec->int_mic.pin = 0x19;
18326 spec->int_mic.mux_idx = 1;
18327 spec->auto_mic = 1;
18328}
18329
4f5d1706 18330#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18331
f1d4e28b
KY
18332/* ***************** Mode2 ******************************/
18333static void alc662_mode2_unsol_event(struct hda_codec *codec,
18334 unsigned int res)
18335{
18336 switch (res >> 26) {
18337 case ALC880_HP_EVENT:
18338 alc662_f5z_speaker_automute(codec);
18339 break;
18340 case ALC880_MIC_EVENT:
4f5d1706 18341 alc_mic_automute(codec);
f1d4e28b
KY
18342 break;
18343 }
18344}
18345
ebb83eeb 18346#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18347
f1d4e28b
KY
18348static void alc662_mode2_inithook(struct hda_codec *codec)
18349{
18350 alc662_f5z_speaker_automute(codec);
4f5d1706 18351 alc_mic_automute(codec);
f1d4e28b
KY
18352}
18353/* ***************** Mode3 ******************************/
18354static void alc663_mode3_unsol_event(struct hda_codec *codec,
18355 unsigned int res)
18356{
18357 switch (res >> 26) {
18358 case ALC880_HP_EVENT:
18359 alc663_two_hp_m1_speaker_automute(codec);
18360 break;
18361 case ALC880_MIC_EVENT:
4f5d1706 18362 alc_mic_automute(codec);
f1d4e28b
KY
18363 break;
18364 }
18365}
18366
ebb83eeb 18367#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18368
f1d4e28b
KY
18369static void alc663_mode3_inithook(struct hda_codec *codec)
18370{
18371 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18372 alc_mic_automute(codec);
f1d4e28b
KY
18373}
18374/* ***************** Mode4 ******************************/
18375static void alc663_mode4_unsol_event(struct hda_codec *codec,
18376 unsigned int res)
18377{
18378 switch (res >> 26) {
18379 case ALC880_HP_EVENT:
18380 alc663_21jd_two_speaker_automute(codec);
18381 break;
18382 case ALC880_MIC_EVENT:
4f5d1706 18383 alc_mic_automute(codec);
f1d4e28b
KY
18384 break;
18385 }
18386}
18387
ebb83eeb 18388#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18389
f1d4e28b
KY
18390static void alc663_mode4_inithook(struct hda_codec *codec)
18391{
18392 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18393 alc_mic_automute(codec);
f1d4e28b
KY
18394}
18395/* ***************** Mode5 ******************************/
18396static void alc663_mode5_unsol_event(struct hda_codec *codec,
18397 unsigned int res)
18398{
18399 switch (res >> 26) {
18400 case ALC880_HP_EVENT:
18401 alc663_15jd_two_speaker_automute(codec);
18402 break;
18403 case ALC880_MIC_EVENT:
4f5d1706 18404 alc_mic_automute(codec);
f1d4e28b
KY
18405 break;
18406 }
18407}
18408
ebb83eeb 18409#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18410
f1d4e28b
KY
18411static void alc663_mode5_inithook(struct hda_codec *codec)
18412{
18413 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18414 alc_mic_automute(codec);
f1d4e28b
KY
18415}
18416/* ***************** Mode6 ******************************/
18417static void alc663_mode6_unsol_event(struct hda_codec *codec,
18418 unsigned int res)
18419{
18420 switch (res >> 26) {
18421 case ALC880_HP_EVENT:
18422 alc663_two_hp_m2_speaker_automute(codec);
18423 break;
18424 case ALC880_MIC_EVENT:
4f5d1706 18425 alc_mic_automute(codec);
f1d4e28b
KY
18426 break;
18427 }
18428}
18429
ebb83eeb 18430#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18431
f1d4e28b
KY
18432static void alc663_mode6_inithook(struct hda_codec *codec)
18433{
18434 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18435 alc_mic_automute(codec);
f1d4e28b
KY
18436}
18437
ebb83eeb
KY
18438/* ***************** Mode7 ******************************/
18439static void alc663_mode7_unsol_event(struct hda_codec *codec,
18440 unsigned int res)
18441{
18442 switch (res >> 26) {
18443 case ALC880_HP_EVENT:
18444 alc663_two_hp_m7_speaker_automute(codec);
18445 break;
18446 case ALC880_MIC_EVENT:
18447 alc_mic_automute(codec);
18448 break;
18449 }
18450}
18451
18452#define alc663_mode7_setup alc663_mode1_setup
18453
18454static void alc663_mode7_inithook(struct hda_codec *codec)
18455{
18456 alc663_two_hp_m7_speaker_automute(codec);
18457 alc_mic_automute(codec);
18458}
18459
18460/* ***************** Mode8 ******************************/
18461static void alc663_mode8_unsol_event(struct hda_codec *codec,
18462 unsigned int res)
18463{
18464 switch (res >> 26) {
18465 case ALC880_HP_EVENT:
18466 alc663_two_hp_m8_speaker_automute(codec);
18467 break;
18468 case ALC880_MIC_EVENT:
18469 alc_mic_automute(codec);
18470 break;
18471 }
18472}
18473
18474#define alc663_mode8_setup alc663_m51va_setup
18475
18476static void alc663_mode8_inithook(struct hda_codec *codec)
18477{
18478 alc663_two_hp_m8_speaker_automute(codec);
18479 alc_mic_automute(codec);
18480}
18481
6dda9f4a
KY
18482static void alc663_g71v_hp_automute(struct hda_codec *codec)
18483{
18484 unsigned int present;
18485 unsigned char bits;
18486
864f92be 18487 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18488 bits = present ? HDA_AMP_MUTE : 0;
18489 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18490 HDA_AMP_MUTE, bits);
18491 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18492 HDA_AMP_MUTE, bits);
18493}
18494
18495static void alc663_g71v_front_automute(struct hda_codec *codec)
18496{
18497 unsigned int present;
18498 unsigned char bits;
18499
864f92be 18500 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18501 bits = present ? HDA_AMP_MUTE : 0;
18502 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18503 HDA_AMP_MUTE, bits);
18504}
18505
18506static void alc663_g71v_unsol_event(struct hda_codec *codec,
18507 unsigned int res)
18508{
18509 switch (res >> 26) {
18510 case ALC880_HP_EVENT:
18511 alc663_g71v_hp_automute(codec);
18512 break;
18513 case ALC880_FRONT_EVENT:
18514 alc663_g71v_front_automute(codec);
18515 break;
18516 case ALC880_MIC_EVENT:
4f5d1706 18517 alc_mic_automute(codec);
6dda9f4a
KY
18518 break;
18519 }
18520}
18521
4f5d1706
TI
18522#define alc663_g71v_setup alc663_m51va_setup
18523
6dda9f4a
KY
18524static void alc663_g71v_inithook(struct hda_codec *codec)
18525{
18526 alc663_g71v_front_automute(codec);
18527 alc663_g71v_hp_automute(codec);
4f5d1706 18528 alc_mic_automute(codec);
6dda9f4a
KY
18529}
18530
18531static void alc663_g50v_unsol_event(struct hda_codec *codec,
18532 unsigned int res)
18533{
18534 switch (res >> 26) {
18535 case ALC880_HP_EVENT:
18536 alc663_m51va_speaker_automute(codec);
18537 break;
18538 case ALC880_MIC_EVENT:
4f5d1706 18539 alc_mic_automute(codec);
6dda9f4a
KY
18540 break;
18541 }
18542}
18543
4f5d1706
TI
18544#define alc663_g50v_setup alc663_m51va_setup
18545
6dda9f4a
KY
18546static void alc663_g50v_inithook(struct hda_codec *codec)
18547{
18548 alc663_m51va_speaker_automute(codec);
4f5d1706 18549 alc_mic_automute(codec);
6dda9f4a
KY
18550}
18551
f1d4e28b
KY
18552static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18553 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18554 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18555
5f99f86a 18556 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18557 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18558 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18559
5f99f86a 18560 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18561 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18562 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18563 { } /* end */
18564};
18565
9541ba1d
CP
18566static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18567 /* Master Playback automatically created from Speaker and Headphone */
18568 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18569 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18570 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18571 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18572
8607f7c4
DH
18573 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18574 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18575 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18576
28c4edb7
DH
18577 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18578 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18579 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18580 { } /* end */
18581};
18582
cb53c626
TI
18583#ifdef CONFIG_SND_HDA_POWER_SAVE
18584#define alc662_loopbacks alc880_loopbacks
18585#endif
18586
bc9f98a9 18587
def319f9 18588/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18589#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18590#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18591#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18592#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18593
18594/*
18595 * configuration and preset
18596 */
18597static const char *alc662_models[ALC662_MODEL_LAST] = {
18598 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18599 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18600 [ALC662_3ST_6ch] = "3stack-6ch",
18601 [ALC662_5ST_DIG] = "6stack-dig",
18602 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18603 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18604 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18605 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18606 [ALC663_ASUS_M51VA] = "m51va",
18607 [ALC663_ASUS_G71V] = "g71v",
18608 [ALC663_ASUS_H13] = "h13",
18609 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18610 [ALC663_ASUS_MODE1] = "asus-mode1",
18611 [ALC662_ASUS_MODE2] = "asus-mode2",
18612 [ALC663_ASUS_MODE3] = "asus-mode3",
18613 [ALC663_ASUS_MODE4] = "asus-mode4",
18614 [ALC663_ASUS_MODE5] = "asus-mode5",
18615 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18616 [ALC663_ASUS_MODE7] = "asus-mode7",
18617 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18618 [ALC272_DELL] = "dell",
18619 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18620 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18621 [ALC662_AUTO] = "auto",
18622};
18623
18624static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18625 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18626 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18627 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18628 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18629 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18630 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18631 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18632 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18633 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18634 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18635 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18636 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18637 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18638 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18639 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18640 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18641 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18642 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18643 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18644 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18645 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18646 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18647 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18648 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18649 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18650 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18651 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18652 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18653 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18654 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18655 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18656 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18657 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18658 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18659 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18660 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18661 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18662 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18663 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18664 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18665 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18666 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18667 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18668 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18669 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18670 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18671 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18672 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18673 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18674 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18675 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18676 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18677 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18678 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18679 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18680 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18681 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18682 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18683 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18684 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18685 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18686 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18687 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18688 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18689 ALC662_3ST_6ch_DIG),
4dee8baa 18690 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18691 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18692 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18693 ALC662_3ST_6ch_DIG),
6227cdce 18694 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18695 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18696 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18697 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18698 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18699 ALC662_3ST_6ch_DIG),
dea0a509
TI
18700 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18701 ALC663_ASUS_H13),
bc9f98a9
KY
18702 {}
18703};
18704
18705static struct alc_config_preset alc662_presets[] = {
18706 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18707 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18708 .init_verbs = { alc662_init_verbs },
18709 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18710 .dac_nids = alc662_dac_nids,
18711 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18712 .dig_in_nid = ALC662_DIGIN_NID,
18713 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18714 .channel_mode = alc662_3ST_2ch_modes,
18715 .input_mux = &alc662_capture_source,
18716 },
18717 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18718 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18719 .init_verbs = { alc662_init_verbs },
18720 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18721 .dac_nids = alc662_dac_nids,
18722 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18723 .dig_in_nid = ALC662_DIGIN_NID,
18724 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18725 .channel_mode = alc662_3ST_6ch_modes,
18726 .need_dac_fix = 1,
18727 .input_mux = &alc662_capture_source,
f12ab1e0 18728 },
bc9f98a9 18729 [ALC662_3ST_6ch] = {
f9e336f6 18730 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18731 .init_verbs = { alc662_init_verbs },
18732 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18733 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18734 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18735 .channel_mode = alc662_3ST_6ch_modes,
18736 .need_dac_fix = 1,
18737 .input_mux = &alc662_capture_source,
f12ab1e0 18738 },
bc9f98a9 18739 [ALC662_5ST_DIG] = {
f9e336f6 18740 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18741 .init_verbs = { alc662_init_verbs },
18742 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18743 .dac_nids = alc662_dac_nids,
18744 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18745 .dig_in_nid = ALC662_DIGIN_NID,
18746 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18747 .channel_mode = alc662_5stack_modes,
18748 .input_mux = &alc662_capture_source,
18749 },
18750 [ALC662_LENOVO_101E] = {
f9e336f6 18751 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18752 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18753 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18754 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18755 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18756 .channel_mode = alc662_3ST_2ch_modes,
18757 .input_mux = &alc662_lenovo_101e_capture_source,
18758 .unsol_event = alc662_lenovo_101e_unsol_event,
18759 .init_hook = alc662_lenovo_101e_all_automute,
18760 },
291702f0 18761 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18762 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18763 .init_verbs = { alc662_init_verbs,
18764 alc662_eeepc_sue_init_verbs },
18765 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18766 .dac_nids = alc662_dac_nids,
291702f0
KY
18767 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18768 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18769 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18770 .setup = alc662_eeepc_setup,
291702f0
KY
18771 .init_hook = alc662_eeepc_inithook,
18772 },
8c427226 18773 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18774 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18775 alc662_chmode_mixer },
18776 .init_verbs = { alc662_init_verbs,
18777 alc662_eeepc_ep20_sue_init_verbs },
18778 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18779 .dac_nids = alc662_dac_nids,
8c427226
KY
18780 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18781 .channel_mode = alc662_3ST_6ch_modes,
18782 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18783 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18784 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18785 .init_hook = alc662_eeepc_ep20_inithook,
18786 },
f1d4e28b 18787 [ALC662_ECS] = {
f9e336f6 18788 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18789 .init_verbs = { alc662_init_verbs,
18790 alc662_ecs_init_verbs },
18791 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18792 .dac_nids = alc662_dac_nids,
18793 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18794 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18795 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18796 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18797 .init_hook = alc662_eeepc_inithook,
18798 },
6dda9f4a 18799 [ALC663_ASUS_M51VA] = {
f9e336f6 18800 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18801 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18802 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18803 .dac_nids = alc662_dac_nids,
18804 .dig_out_nid = ALC662_DIGOUT_NID,
18805 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18806 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18807 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18808 .setup = alc663_m51va_setup,
6dda9f4a
KY
18809 .init_hook = alc663_m51va_inithook,
18810 },
18811 [ALC663_ASUS_G71V] = {
f9e336f6 18812 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18813 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18814 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18815 .dac_nids = alc662_dac_nids,
18816 .dig_out_nid = ALC662_DIGOUT_NID,
18817 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18818 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18819 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18820 .setup = alc663_g71v_setup,
6dda9f4a
KY
18821 .init_hook = alc663_g71v_inithook,
18822 },
18823 [ALC663_ASUS_H13] = {
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 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18829 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18830 .unsol_event = alc663_m51va_unsol_event,
18831 .init_hook = alc663_m51va_inithook,
18832 },
18833 [ALC663_ASUS_G50V] = {
f9e336f6 18834 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18835 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18836 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18837 .dac_nids = alc662_dac_nids,
18838 .dig_out_nid = ALC662_DIGOUT_NID,
18839 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18840 .channel_mode = alc662_3ST_6ch_modes,
18841 .input_mux = &alc663_capture_source,
18842 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18843 .setup = alc663_g50v_setup,
6dda9f4a
KY
18844 .init_hook = alc663_g50v_inithook,
18845 },
f1d4e28b 18846 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18847 .mixers = { alc663_m51va_mixer },
18848 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18849 .init_verbs = { alc662_init_verbs,
18850 alc663_21jd_amic_init_verbs },
18851 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18852 .hp_nid = 0x03,
18853 .dac_nids = alc662_dac_nids,
18854 .dig_out_nid = ALC662_DIGOUT_NID,
18855 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18856 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18857 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18858 .setup = alc663_mode1_setup,
f1d4e28b
KY
18859 .init_hook = alc663_mode1_inithook,
18860 },
18861 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18862 .mixers = { alc662_1bjd_mixer },
18863 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18864 .init_verbs = { alc662_init_verbs,
18865 alc662_1bjd_amic_init_verbs },
18866 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18867 .dac_nids = alc662_dac_nids,
18868 .dig_out_nid = ALC662_DIGOUT_NID,
18869 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18870 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18871 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18872 .setup = alc662_mode2_setup,
f1d4e28b
KY
18873 .init_hook = alc662_mode2_inithook,
18874 },
18875 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18876 .mixers = { alc663_two_hp_m1_mixer },
18877 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18878 .init_verbs = { alc662_init_verbs,
18879 alc663_two_hp_amic_m1_init_verbs },
18880 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18881 .hp_nid = 0x03,
18882 .dac_nids = alc662_dac_nids,
18883 .dig_out_nid = ALC662_DIGOUT_NID,
18884 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18885 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18886 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18887 .setup = alc663_mode3_setup,
f1d4e28b
KY
18888 .init_hook = alc663_mode3_inithook,
18889 },
18890 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18891 .mixers = { alc663_asus_21jd_clfe_mixer },
18892 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18893 .init_verbs = { alc662_init_verbs,
18894 alc663_21jd_amic_init_verbs},
18895 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18896 .hp_nid = 0x03,
18897 .dac_nids = alc662_dac_nids,
18898 .dig_out_nid = ALC662_DIGOUT_NID,
18899 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18900 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18901 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18902 .setup = alc663_mode4_setup,
f1d4e28b
KY
18903 .init_hook = alc663_mode4_inithook,
18904 },
18905 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18906 .mixers = { alc663_asus_15jd_clfe_mixer },
18907 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18908 .init_verbs = { alc662_init_verbs,
18909 alc663_15jd_amic_init_verbs },
18910 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18911 .hp_nid = 0x03,
18912 .dac_nids = alc662_dac_nids,
18913 .dig_out_nid = ALC662_DIGOUT_NID,
18914 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18915 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18916 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18917 .setup = alc663_mode5_setup,
f1d4e28b
KY
18918 .init_hook = alc663_mode5_inithook,
18919 },
18920 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18921 .mixers = { alc663_two_hp_m2_mixer },
18922 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18923 .init_verbs = { alc662_init_verbs,
18924 alc663_two_hp_amic_m2_init_verbs },
18925 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18926 .hp_nid = 0x03,
18927 .dac_nids = alc662_dac_nids,
18928 .dig_out_nid = ALC662_DIGOUT_NID,
18929 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18930 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18931 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18932 .setup = alc663_mode6_setup,
f1d4e28b
KY
18933 .init_hook = alc663_mode6_inithook,
18934 },
ebb83eeb
KY
18935 [ALC663_ASUS_MODE7] = {
18936 .mixers = { alc663_mode7_mixer },
18937 .cap_mixer = alc662_auto_capture_mixer,
18938 .init_verbs = { alc662_init_verbs,
18939 alc663_mode7_init_verbs },
18940 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18941 .hp_nid = 0x03,
18942 .dac_nids = alc662_dac_nids,
18943 .dig_out_nid = ALC662_DIGOUT_NID,
18944 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18945 .channel_mode = alc662_3ST_2ch_modes,
18946 .unsol_event = alc663_mode7_unsol_event,
18947 .setup = alc663_mode7_setup,
18948 .init_hook = alc663_mode7_inithook,
18949 },
18950 [ALC663_ASUS_MODE8] = {
18951 .mixers = { alc663_mode8_mixer },
18952 .cap_mixer = alc662_auto_capture_mixer,
18953 .init_verbs = { alc662_init_verbs,
18954 alc663_mode8_init_verbs },
18955 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18956 .hp_nid = 0x03,
18957 .dac_nids = alc662_dac_nids,
18958 .dig_out_nid = ALC662_DIGOUT_NID,
18959 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18960 .channel_mode = alc662_3ST_2ch_modes,
18961 .unsol_event = alc663_mode8_unsol_event,
18962 .setup = alc663_mode8_setup,
18963 .init_hook = alc663_mode8_inithook,
18964 },
622e84cd
KY
18965 [ALC272_DELL] = {
18966 .mixers = { alc663_m51va_mixer },
18967 .cap_mixer = alc272_auto_capture_mixer,
18968 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18969 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18970 .dac_nids = alc662_dac_nids,
18971 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18972 .adc_nids = alc272_adc_nids,
18973 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18974 .capsrc_nids = alc272_capsrc_nids,
18975 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18976 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18977 .setup = alc663_m51va_setup,
622e84cd
KY
18978 .init_hook = alc663_m51va_inithook,
18979 },
18980 [ALC272_DELL_ZM1] = {
18981 .mixers = { alc663_m51va_mixer },
18982 .cap_mixer = alc662_auto_capture_mixer,
18983 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18984 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18985 .dac_nids = alc662_dac_nids,
18986 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18987 .adc_nids = alc662_adc_nids,
b59bdf3b 18988 .num_adc_nids = 1,
622e84cd
KY
18989 .capsrc_nids = alc662_capsrc_nids,
18990 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18991 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18992 .setup = alc663_m51va_setup,
622e84cd
KY
18993 .init_hook = alc663_m51va_inithook,
18994 },
9541ba1d
CP
18995 [ALC272_SAMSUNG_NC10] = {
18996 .mixers = { alc272_nc10_mixer },
18997 .init_verbs = { alc662_init_verbs,
18998 alc663_21jd_amic_init_verbs },
18999 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19000 .dac_nids = alc272_dac_nids,
19001 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19002 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 19003 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 19004 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19005 .setup = alc663_mode4_setup,
9541ba1d
CP
19006 .init_hook = alc663_mode4_inithook,
19007 },
bc9f98a9
KY
19008};
19009
19010
19011/*
19012 * BIOS auto configuration
19013 */
19014
7085ec12
TI
19015/* convert from MIX nid to DAC */
19016static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19017{
19018 if (nid == 0x0f)
19019 return 0x02;
19020 else if (nid >= 0x0c && nid <= 0x0e)
19021 return nid - 0x0c + 0x02;
cc1c452e
DH
19022 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19023 return 0x25;
7085ec12
TI
19024 else
19025 return 0;
19026}
19027
19028/* get MIX nid connected to the given pin targeted to DAC */
19029static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19030 hda_nid_t dac)
19031{
cc1c452e 19032 hda_nid_t mix[5];
7085ec12
TI
19033 int i, num;
19034
19035 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19036 for (i = 0; i < num; i++) {
19037 if (alc662_mix_to_dac(mix[i]) == dac)
19038 return mix[i];
19039 }
19040 return 0;
19041}
19042
19043/* look for an empty DAC slot */
19044static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19045{
19046 struct alc_spec *spec = codec->spec;
19047 hda_nid_t srcs[5];
19048 int i, j, num;
19049
19050 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19051 if (num < 0)
19052 return 0;
19053 for (i = 0; i < num; i++) {
19054 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19055 if (!nid)
19056 continue;
19057 for (j = 0; j < spec->multiout.num_dacs; j++)
19058 if (spec->multiout.dac_nids[j] == nid)
19059 break;
19060 if (j >= spec->multiout.num_dacs)
19061 return nid;
19062 }
19063 return 0;
19064}
19065
19066/* fill in the dac_nids table from the parsed pin configuration */
19067static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19068 const struct auto_pin_cfg *cfg)
19069{
19070 struct alc_spec *spec = codec->spec;
19071 int i;
19072 hda_nid_t dac;
19073
19074 spec->multiout.dac_nids = spec->private_dac_nids;
19075 for (i = 0; i < cfg->line_outs; i++) {
19076 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19077 if (!dac)
19078 continue;
19079 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19080 }
19081 return 0;
19082}
19083
bcb2f0f5
TI
19084static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19085 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19086{
bcb2f0f5 19087 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
19088 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19089}
19090
bcb2f0f5
TI
19091static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19092 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19093{
bcb2f0f5 19094 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19095 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19096}
19097
bcb2f0f5
TI
19098#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19099 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19100#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19101 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19102#define alc662_add_stereo_vol(spec, pfx, nid) \
19103 alc662_add_vol_ctl(spec, pfx, nid, 3)
19104#define alc662_add_stereo_sw(spec, pfx, nid) \
19105 alc662_add_sw_ctl(spec, pfx, nid, 3)
19106
bc9f98a9 19107/* add playback controls from the parsed DAC table */
7085ec12 19108static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19109 const struct auto_pin_cfg *cfg)
19110{
7085ec12 19111 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19112 static const char *chname[4] = {
19113 "Front", "Surround", NULL /*CLFE*/, "Side"
19114 };
bcb2f0f5 19115 const char *pfx = alc_get_line_out_pfx(cfg, true);
7085ec12 19116 hda_nid_t nid, mix;
bc9f98a9
KY
19117 int i, err;
19118
19119 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19120 nid = spec->multiout.dac_nids[i];
19121 if (!nid)
19122 continue;
19123 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19124 if (!mix)
bc9f98a9 19125 continue;
bcb2f0f5 19126 if (!pfx && i == 2) {
bc9f98a9 19127 /* Center/LFE */
7085ec12 19128 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19129 if (err < 0)
19130 return err;
7085ec12 19131 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19132 if (err < 0)
19133 return err;
7085ec12 19134 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19135 if (err < 0)
19136 return err;
7085ec12 19137 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19138 if (err < 0)
19139 return err;
19140 } else {
bcb2f0f5
TI
19141 const char *name = pfx;
19142 if (!name)
19143 name = chname[i];
19144 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
bc9f98a9
KY
19145 if (err < 0)
19146 return err;
bcb2f0f5 19147 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
bc9f98a9
KY
19148 if (err < 0)
19149 return err;
19150 }
19151 }
19152 return 0;
19153}
19154
19155/* add playback controls for speaker and HP outputs */
7085ec12
TI
19156/* return DAC nid if any new DAC is assigned */
19157static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19158 const char *pfx)
19159{
7085ec12
TI
19160 struct alc_spec *spec = codec->spec;
19161 hda_nid_t nid, mix;
bc9f98a9 19162 int err;
bc9f98a9
KY
19163
19164 if (!pin)
19165 return 0;
7085ec12
TI
19166 nid = alc662_look_for_dac(codec, pin);
19167 if (!nid) {
7085ec12
TI
19168 /* the corresponding DAC is already occupied */
19169 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19170 return 0; /* no way */
19171 /* create a switch only */
0afe5f89 19172 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19173 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19174 }
19175
7085ec12
TI
19176 mix = alc662_dac_to_mix(codec, pin, nid);
19177 if (!mix)
19178 return 0;
19179 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19180 if (err < 0)
19181 return err;
19182 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19183 if (err < 0)
19184 return err;
19185 return nid;
bc9f98a9
KY
19186}
19187
19188/* create playback/capture controls for input pins */
05f5f477 19189#define alc662_auto_create_input_ctls \
4b7348a1 19190 alc882_auto_create_input_ctls
bc9f98a9
KY
19191
19192static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19193 hda_nid_t nid, int pin_type,
7085ec12 19194 hda_nid_t dac)
bc9f98a9 19195{
7085ec12 19196 int i, num;
ce503f38 19197 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19198
f6c7e546 19199 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19200 /* need the manual connection? */
7085ec12
TI
19201 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19202 if (num <= 1)
19203 return;
19204 for (i = 0; i < num; i++) {
19205 if (alc662_mix_to_dac(srcs[i]) != dac)
19206 continue;
19207 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19208 return;
bc9f98a9
KY
19209 }
19210}
19211
19212static void alc662_auto_init_multi_out(struct hda_codec *codec)
19213{
19214 struct alc_spec *spec = codec->spec;
7085ec12 19215 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19216 int i;
19217
19218 for (i = 0; i <= HDA_SIDE; i++) {
19219 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19220 if (nid)
baba8ee9 19221 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19222 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19223 }
19224}
19225
19226static void alc662_auto_init_hp_out(struct hda_codec *codec)
19227{
19228 struct alc_spec *spec = codec->spec;
19229 hda_nid_t pin;
19230
19231 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19232 if (pin)
19233 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19234 spec->multiout.hp_nid);
f6c7e546
TI
19235 pin = spec->autocfg.speaker_pins[0];
19236 if (pin)
7085ec12
TI
19237 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19238 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19239}
19240
bc9f98a9
KY
19241#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19242
19243static void alc662_auto_init_analog_input(struct hda_codec *codec)
19244{
19245 struct alc_spec *spec = codec->spec;
66ceeb6b 19246 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19247 int i;
19248
66ceeb6b
TI
19249 for (i = 0; i < cfg->num_inputs; i++) {
19250 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19251 if (alc_is_input_pin(codec, nid)) {
30ea098f 19252 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19253 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19254 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19255 snd_hda_codec_write(codec, nid, 0,
19256 AC_VERB_SET_AMP_GAIN_MUTE,
19257 AMP_OUT_MUTE);
19258 }
19259 }
19260}
19261
f511b01c
TI
19262#define alc662_auto_init_input_src alc882_auto_init_input_src
19263
bc9f98a9
KY
19264static int alc662_parse_auto_config(struct hda_codec *codec)
19265{
19266 struct alc_spec *spec = codec->spec;
19267 int err;
19268 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19269
19270 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19271 alc662_ignore);
19272 if (err < 0)
19273 return err;
19274 if (!spec->autocfg.line_outs)
19275 return 0; /* can't find valid BIOS pin config */
19276
7085ec12 19277 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19278 if (err < 0)
19279 return err;
7085ec12 19280 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19281 if (err < 0)
19282 return err;
7085ec12 19283 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19284 spec->autocfg.speaker_pins[0],
19285 "Speaker");
19286 if (err < 0)
19287 return err;
7085ec12
TI
19288 if (err)
19289 spec->multiout.extra_out_nid[0] = err;
19290 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19291 "Headphone");
19292 if (err < 0)
19293 return err;
7085ec12
TI
19294 if (err)
19295 spec->multiout.hp_nid = err;
05f5f477 19296 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19297 if (err < 0)
bc9f98a9
KY
19298 return err;
19299
19300 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19301
757899ac 19302 alc_auto_parse_digital(codec);
bc9f98a9 19303
603c4019 19304 if (spec->kctls.list)
d88897ea 19305 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19306
19307 spec->num_mux_defs = 1;
61b9b9b1 19308 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19309
cec27c89
KY
19310 add_verb(spec, alc662_init_verbs);
19311 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19312 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19313 add_verb(spec, alc663_init_verbs);
19314
19315 if (codec->vendor_id == 0x10ec0272)
19316 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19317
19318 err = alc_auto_add_mic_boost(codec);
19319 if (err < 0)
19320 return err;
19321
6227cdce
KY
19322 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19323 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19324 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19325 else
19326 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19327
8c87286f 19328 return 1;
bc9f98a9
KY
19329}
19330
19331/* additional initialization for auto-configuration model */
19332static void alc662_auto_init(struct hda_codec *codec)
19333{
f6c7e546 19334 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19335 alc662_auto_init_multi_out(codec);
19336 alc662_auto_init_hp_out(codec);
19337 alc662_auto_init_analog_input(codec);
f511b01c 19338 alc662_auto_init_input_src(codec);
757899ac 19339 alc_auto_init_digital(codec);
f6c7e546 19340 if (spec->unsol_event)
7fb0d78f 19341 alc_inithook(codec);
bc9f98a9
KY
19342}
19343
6be7948f
TB
19344static void alc272_fixup_mario(struct hda_codec *codec,
19345 const struct alc_fixup *fix, int pre_init) {
19346 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19347 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19348 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19349 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19350 (0 << AC_AMPCAP_MUTE_SHIFT)))
19351 printk(KERN_WARNING
19352 "hda_codec: failed to override amp caps for NID 0x2\n");
19353}
19354
6cb3b707 19355enum {
2df03514 19356 ALC662_FIXUP_ASPIRE,
6cb3b707 19357 ALC662_FIXUP_IDEAPAD,
6be7948f 19358 ALC272_FIXUP_MARIO,
6cb3b707
DH
19359};
19360
19361static const struct alc_fixup alc662_fixups[] = {
2df03514
DC
19362 [ALC662_FIXUP_ASPIRE] = {
19363 .pins = (const struct alc_pincfg[]) {
19364 { 0x15, 0x99130112 }, /* subwoofer */
19365 { }
19366 }
19367 },
6cb3b707
DH
19368 [ALC662_FIXUP_IDEAPAD] = {
19369 .pins = (const struct alc_pincfg[]) {
19370 { 0x17, 0x99130112 }, /* subwoofer */
19371 { }
19372 }
19373 },
6be7948f
TB
19374 [ALC272_FIXUP_MARIO] = {
19375 .func = alc272_fixup_mario,
19376 }
6cb3b707
DH
19377};
19378
19379static struct snd_pci_quirk alc662_fixup_tbl[] = {
2df03514 19380 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19381 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19382 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707
DH
19383 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19384 {}
19385};
19386
6be7948f
TB
19387static const struct alc_model_fixup alc662_fixup_models[] = {
19388 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19389 {}
19390};
6cb3b707
DH
19391
19392
bc9f98a9
KY
19393static int patch_alc662(struct hda_codec *codec)
19394{
19395 struct alc_spec *spec;
19396 int err, board_config;
693194f3 19397 int coef;
bc9f98a9
KY
19398
19399 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19400 if (!spec)
19401 return -ENOMEM;
19402
19403 codec->spec = spec;
19404
da00c244
KY
19405 alc_auto_parse_customize_define(codec);
19406
2c3bf9ab
TI
19407 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19408
693194f3
KY
19409 coef = alc_read_coef_idx(codec, 0);
19410 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19411 alc_codec_rename(codec, "ALC661");
693194f3
KY
19412 else if (coef & (1 << 14) &&
19413 codec->bus->pci->subsystem_vendor == 0x1025 &&
19414 spec->cdefine.platform_type == 1)
c027ddcd 19415 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19416 else if (coef == 0x4011)
19417 alc_codec_rename(codec, "ALC656");
274693f3 19418
bc9f98a9
KY
19419 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19420 alc662_models,
19421 alc662_cfg_tbl);
19422 if (board_config < 0) {
9a11f1aa
TI
19423 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19424 codec->chip_name);
bc9f98a9
KY
19425 board_config = ALC662_AUTO;
19426 }
19427
19428 if (board_config == ALC662_AUTO) {
6cb3b707 19429 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1);
bc9f98a9
KY
19430 /* automatic parse from the BIOS config */
19431 err = alc662_parse_auto_config(codec);
19432 if (err < 0) {
19433 alc_free(codec);
19434 return err;
8c87286f 19435 } else if (!err) {
bc9f98a9
KY
19436 printk(KERN_INFO
19437 "hda_codec: Cannot set up configuration "
19438 "from BIOS. Using base mode...\n");
19439 board_config = ALC662_3ST_2ch_DIG;
19440 }
19441 }
19442
dc1eae25 19443 if (has_cdefine_beep(codec)) {
8af2591d
TI
19444 err = snd_hda_attach_beep_device(codec, 0x1);
19445 if (err < 0) {
19446 alc_free(codec);
19447 return err;
19448 }
680cd536
KK
19449 }
19450
bc9f98a9 19451 if (board_config != ALC662_AUTO)
e9c364c0 19452 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19453
bc9f98a9
KY
19454 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19455 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19456
bc9f98a9
KY
19457 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19458 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19459
dd704698
TI
19460 if (!spec->adc_nids) {
19461 spec->adc_nids = alc662_adc_nids;
19462 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19463 }
19464 if (!spec->capsrc_nids)
19465 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19466
f9e336f6 19467 if (!spec->cap_mixer)
b59bdf3b 19468 set_capture_mixer(codec);
cec27c89 19469
dc1eae25 19470 if (has_cdefine_beep(codec)) {
da00c244
KY
19471 switch (codec->vendor_id) {
19472 case 0x10ec0662:
19473 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19474 break;
19475 case 0x10ec0272:
19476 case 0x10ec0663:
19477 case 0x10ec0665:
19478 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19479 break;
19480 case 0x10ec0273:
19481 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19482 break;
19483 }
cec27c89 19484 }
2134ea4f
TI
19485 spec->vmaster_nid = 0x02;
19486
bc9f98a9 19487 codec->patch_ops = alc_patch_ops;
6cb3b707 19488 if (board_config == ALC662_AUTO) {
bc9f98a9 19489 spec->init_hook = alc662_auto_init;
6be7948f
TB
19490 alc_pick_fixup_model(codec, alc662_fixup_models,
19491 alc662_fixup_tbl, alc662_fixups, 0);
6cb3b707
DH
19492 }
19493
bf1b0225
KY
19494 alc_init_jacks(codec);
19495
cb53c626
TI
19496#ifdef CONFIG_SND_HDA_POWER_SAVE
19497 if (!spec->loopback.amplist)
19498 spec->loopback.amplist = alc662_loopbacks;
19499#endif
bc9f98a9
KY
19500
19501 return 0;
19502}
19503
274693f3
KY
19504static int patch_alc888(struct hda_codec *codec)
19505{
19506 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19507 kfree(codec->chip_name);
01e0f137
KY
19508 if (codec->vendor_id == 0x10ec0887)
19509 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19510 else
19511 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19512 if (!codec->chip_name) {
19513 alc_free(codec);
274693f3 19514 return -ENOMEM;
ac2c92e0
TI
19515 }
19516 return patch_alc662(codec);
274693f3 19517 }
ac2c92e0 19518 return patch_alc882(codec);
274693f3
KY
19519}
19520
d1eb57f4
KY
19521/*
19522 * ALC680 support
19523 */
c69aefab 19524#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19525#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19526#define alc680_modes alc260_modes
19527
19528static hda_nid_t alc680_dac_nids[3] = {
19529 /* Lout1, Lout2, hp */
19530 0x02, 0x03, 0x04
19531};
19532
19533static hda_nid_t alc680_adc_nids[3] = {
19534 /* ADC0-2 */
19535 /* DMIC, MIC, Line-in*/
19536 0x07, 0x08, 0x09
19537};
19538
c69aefab
KY
19539/*
19540 * Analog capture ADC cgange
19541 */
66ceeb6b
TI
19542static void alc680_rec_autoswitch(struct hda_codec *codec)
19543{
19544 struct alc_spec *spec = codec->spec;
19545 struct auto_pin_cfg *cfg = &spec->autocfg;
19546 int pin_found = 0;
19547 int type_found = AUTO_PIN_LAST;
19548 hda_nid_t nid;
19549 int i;
19550
19551 for (i = 0; i < cfg->num_inputs; i++) {
19552 nid = cfg->inputs[i].pin;
19553 if (!(snd_hda_query_pin_caps(codec, nid) &
19554 AC_PINCAP_PRES_DETECT))
19555 continue;
19556 if (snd_hda_jack_detect(codec, nid)) {
19557 if (cfg->inputs[i].type < type_found) {
19558 type_found = cfg->inputs[i].type;
19559 pin_found = nid;
19560 }
19561 }
19562 }
19563
19564 nid = 0x07;
19565 if (pin_found)
19566 snd_hda_get_connections(codec, pin_found, &nid, 1);
19567
19568 if (nid != spec->cur_adc)
19569 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19570 spec->cur_adc = nid;
19571 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19572 spec->cur_adc_format);
19573}
19574
c69aefab
KY
19575static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19576 struct hda_codec *codec,
19577 unsigned int stream_tag,
19578 unsigned int format,
19579 struct snd_pcm_substream *substream)
19580{
19581 struct alc_spec *spec = codec->spec;
c69aefab 19582
66ceeb6b 19583 spec->cur_adc = 0x07;
c69aefab
KY
19584 spec->cur_adc_stream_tag = stream_tag;
19585 spec->cur_adc_format = format;
19586
66ceeb6b 19587 alc680_rec_autoswitch(codec);
c69aefab
KY
19588 return 0;
19589}
19590
19591static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19592 struct hda_codec *codec,
19593 struct snd_pcm_substream *substream)
19594{
19595 snd_hda_codec_cleanup_stream(codec, 0x07);
19596 snd_hda_codec_cleanup_stream(codec, 0x08);
19597 snd_hda_codec_cleanup_stream(codec, 0x09);
19598 return 0;
19599}
19600
19601static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19602 .substreams = 1, /* can be overridden */
19603 .channels_min = 2,
19604 .channels_max = 2,
19605 /* NID is set in alc_build_pcms */
19606 .ops = {
19607 .prepare = alc680_capture_pcm_prepare,
19608 .cleanup = alc680_capture_pcm_cleanup
19609 },
19610};
19611
d1eb57f4
KY
19612static struct snd_kcontrol_new alc680_base_mixer[] = {
19613 /* output mixer control */
19614 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19615 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19616 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19617 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19618 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19619 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19620 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19621 { }
19622};
19623
c69aefab
KY
19624static struct hda_bind_ctls alc680_bind_cap_vol = {
19625 .ops = &snd_hda_bind_vol,
19626 .values = {
19627 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19628 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19629 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19630 0
19631 },
19632};
19633
19634static struct hda_bind_ctls alc680_bind_cap_switch = {
19635 .ops = &snd_hda_bind_sw,
19636 .values = {
19637 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19638 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19639 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19640 0
19641 },
19642};
19643
19644static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19645 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19646 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19647 { } /* end */
19648};
19649
19650/*
19651 * generic initialization of ADC, input mixers and output mixers
19652 */
19653static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19654 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19655 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19656 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19657
c69aefab
KY
19658 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19659 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19661 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19662 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19663 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19664
19665 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19666 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19667 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19668 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19669 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19670
19671 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19672 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19673 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19674
d1eb57f4
KY
19675 { }
19676};
19677
c69aefab
KY
19678/* toggle speaker-output according to the hp-jack state */
19679static void alc680_base_setup(struct hda_codec *codec)
19680{
19681 struct alc_spec *spec = codec->spec;
19682
19683 spec->autocfg.hp_pins[0] = 0x16;
19684 spec->autocfg.speaker_pins[0] = 0x14;
19685 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19686 spec->autocfg.num_inputs = 2;
19687 spec->autocfg.inputs[0].pin = 0x18;
19688 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19689 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19690 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19691}
19692
19693static void alc680_unsol_event(struct hda_codec *codec,
19694 unsigned int res)
19695{
19696 if ((res >> 26) == ALC880_HP_EVENT)
19697 alc_automute_amp(codec);
19698 if ((res >> 26) == ALC880_MIC_EVENT)
19699 alc680_rec_autoswitch(codec);
19700}
19701
19702static void alc680_inithook(struct hda_codec *codec)
19703{
19704 alc_automute_amp(codec);
19705 alc680_rec_autoswitch(codec);
19706}
19707
d1eb57f4
KY
19708/* create input playback/capture controls for the given pin */
19709static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19710 const char *ctlname, int idx)
19711{
19712 hda_nid_t dac;
19713 int err;
19714
19715 switch (nid) {
19716 case 0x14:
19717 dac = 0x02;
19718 break;
19719 case 0x15:
19720 dac = 0x03;
19721 break;
19722 case 0x16:
19723 dac = 0x04;
19724 break;
19725 default:
19726 return 0;
19727 }
19728 if (spec->multiout.dac_nids[0] != dac &&
19729 spec->multiout.dac_nids[1] != dac) {
19730 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19731 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19732 HDA_OUTPUT));
19733 if (err < 0)
19734 return err;
19735
19736 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19737 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19738
19739 if (err < 0)
19740 return err;
19741 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19742 }
19743
19744 return 0;
19745}
19746
19747/* add playback controls from the parsed DAC table */
19748static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19749 const struct auto_pin_cfg *cfg)
19750{
19751 hda_nid_t nid;
19752 int err;
19753
19754 spec->multiout.dac_nids = spec->private_dac_nids;
19755
19756 nid = cfg->line_out_pins[0];
19757 if (nid) {
19758 const char *name;
19759 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19760 name = "Speaker";
19761 else
19762 name = "Front";
19763 err = alc680_new_analog_output(spec, nid, name, 0);
19764 if (err < 0)
19765 return err;
19766 }
19767
19768 nid = cfg->speaker_pins[0];
19769 if (nid) {
19770 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19771 if (err < 0)
19772 return err;
19773 }
19774 nid = cfg->hp_pins[0];
19775 if (nid) {
19776 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19777 if (err < 0)
19778 return err;
19779 }
19780
19781 return 0;
19782}
19783
19784static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19785 hda_nid_t nid, int pin_type)
19786{
19787 alc_set_pin_output(codec, nid, pin_type);
19788}
19789
19790static void alc680_auto_init_multi_out(struct hda_codec *codec)
19791{
19792 struct alc_spec *spec = codec->spec;
19793 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19794 if (nid) {
19795 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19796 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19797 }
19798}
19799
19800static void alc680_auto_init_hp_out(struct hda_codec *codec)
19801{
19802 struct alc_spec *spec = codec->spec;
19803 hda_nid_t pin;
19804
19805 pin = spec->autocfg.hp_pins[0];
19806 if (pin)
19807 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19808 pin = spec->autocfg.speaker_pins[0];
19809 if (pin)
19810 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19811}
19812
19813/* pcm configuration: identical with ALC880 */
19814#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19815#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19816#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19817#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19818#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19819
19820/*
19821 * BIOS auto configuration
19822 */
19823static int alc680_parse_auto_config(struct hda_codec *codec)
19824{
19825 struct alc_spec *spec = codec->spec;
19826 int err;
19827 static hda_nid_t alc680_ignore[] = { 0 };
19828
19829 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19830 alc680_ignore);
19831 if (err < 0)
19832 return err;
c69aefab 19833
d1eb57f4
KY
19834 if (!spec->autocfg.line_outs) {
19835 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19836 spec->multiout.max_channels = 2;
19837 spec->no_analog = 1;
19838 goto dig_only;
19839 }
19840 return 0; /* can't find valid BIOS pin config */
19841 }
19842 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19843 if (err < 0)
19844 return err;
19845
19846 spec->multiout.max_channels = 2;
19847
19848 dig_only:
19849 /* digital only support output */
757899ac 19850 alc_auto_parse_digital(codec);
d1eb57f4
KY
19851 if (spec->kctls.list)
19852 add_mixer(spec, spec->kctls.list);
19853
19854 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19855
19856 err = alc_auto_add_mic_boost(codec);
19857 if (err < 0)
19858 return err;
19859
19860 return 1;
19861}
19862
19863#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19864
19865/* init callback for auto-configuration model -- overriding the default init */
19866static void alc680_auto_init(struct hda_codec *codec)
19867{
19868 struct alc_spec *spec = codec->spec;
19869 alc680_auto_init_multi_out(codec);
19870 alc680_auto_init_hp_out(codec);
19871 alc680_auto_init_analog_input(codec);
757899ac 19872 alc_auto_init_digital(codec);
d1eb57f4
KY
19873 if (spec->unsol_event)
19874 alc_inithook(codec);
19875}
19876
19877/*
19878 * configuration and preset
19879 */
19880static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19881 [ALC680_BASE] = "base",
19882 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19883};
19884
19885static struct snd_pci_quirk alc680_cfg_tbl[] = {
19886 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19887 {}
19888};
19889
19890static struct alc_config_preset alc680_presets[] = {
19891 [ALC680_BASE] = {
19892 .mixers = { alc680_base_mixer },
c69aefab 19893 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19894 .init_verbs = { alc680_init_verbs },
19895 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19896 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19897 .dig_out_nid = ALC680_DIGOUT_NID,
19898 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19899 .channel_mode = alc680_modes,
c69aefab
KY
19900 .unsol_event = alc680_unsol_event,
19901 .setup = alc680_base_setup,
19902 .init_hook = alc680_inithook,
19903
d1eb57f4
KY
19904 },
19905};
19906
19907static int patch_alc680(struct hda_codec *codec)
19908{
19909 struct alc_spec *spec;
19910 int board_config;
19911 int err;
19912
19913 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19914 if (spec == NULL)
19915 return -ENOMEM;
19916
19917 codec->spec = spec;
19918
19919 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19920 alc680_models,
19921 alc680_cfg_tbl);
19922
19923 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19924 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19925 codec->chip_name);
19926 board_config = ALC680_AUTO;
19927 }
19928
19929 if (board_config == ALC680_AUTO) {
19930 /* automatic parse from the BIOS config */
19931 err = alc680_parse_auto_config(codec);
19932 if (err < 0) {
19933 alc_free(codec);
19934 return err;
19935 } else if (!err) {
19936 printk(KERN_INFO
19937 "hda_codec: Cannot set up configuration "
19938 "from BIOS. Using base mode...\n");
19939 board_config = ALC680_BASE;
19940 }
19941 }
19942
19943 if (board_config != ALC680_AUTO)
19944 setup_preset(codec, &alc680_presets[board_config]);
19945
19946 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19947 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19948 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19949 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19950
19951 if (!spec->adc_nids) {
19952 spec->adc_nids = alc680_adc_nids;
19953 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19954 }
19955
19956 if (!spec->cap_mixer)
19957 set_capture_mixer(codec);
19958
19959 spec->vmaster_nid = 0x02;
19960
19961 codec->patch_ops = alc_patch_ops;
19962 if (board_config == ALC680_AUTO)
19963 spec->init_hook = alc680_auto_init;
19964
19965 return 0;
19966}
19967
1da177e4
LT
19968/*
19969 * patch entries
19970 */
1289e9e8 19971static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19972 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19973 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19974 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19975 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19976 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19977 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19978 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19979 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19980 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19981 .patch = patch_alc861 },
f32610ed
JS
19982 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19983 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19984 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19985 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19986 .patch = patch_alc882 },
bc9f98a9
KY
19987 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19988 .patch = patch_alc662 },
6dda9f4a 19989 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19990 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19991 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19992 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19993 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19994 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19995 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19996 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19997 .patch = patch_alc882 },
cb308f97 19998 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19999 .patch = patch_alc882 },
df694daa 20000 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20001 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20002 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20003 .patch = patch_alc882 },
274693f3 20004 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20005 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20006 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20007 {} /* terminator */
20008};
1289e9e8
TI
20009
20010MODULE_ALIAS("snd-hda-codec-id:10ec*");
20011
20012MODULE_LICENSE("GPL");
20013MODULE_DESCRIPTION("Realtek HD-audio codec");
20014
20015static struct hda_codec_preset_list realtek_list = {
20016 .preset = snd_hda_preset_realtek,
20017 .owner = THIS_MODULE,
20018};
20019
20020static int __init patch_realtek_init(void)
20021{
20022 return snd_hda_add_codec_preset(&realtek_list);
20023}
20024
20025static void __exit patch_realtek_exit(void)
20026{
20027 snd_hda_delete_codec_preset(&realtek_list);
20028}
20029
20030module_init(patch_realtek_init)
20031module_exit(patch_realtek_exit)