]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
ALSA: HDA: Fix volume control naming for surround speakers on Realtek auto-parser
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
1da177e4
LT
302struct alc_spec {
303 /* codec parameterization */
df694daa 304 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 305 unsigned int num_mixers;
f9e336f6 306 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 307 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 308
2d9c6482 309 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
310 * don't forget NULL
311 * termination!
e9edcee0
TI
312 */
313 unsigned int num_init_verbs;
1da177e4 314
aa563af7 315 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
316 struct hda_pcm_stream *stream_analog_playback;
317 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
318 struct hda_pcm_stream *stream_analog_alt_playback;
319 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 320
aa563af7 321 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
322 struct hda_pcm_stream *stream_digital_playback;
323 struct hda_pcm_stream *stream_digital_capture;
324
325 /* playback */
16ded525
TI
326 struct hda_multi_out multiout; /* playback set-up
327 * max_channels, dacs must be set
328 * dig_out_nid and hp_nid are optional
329 */
6330079f 330 hda_nid_t alt_dac_nid;
6a05ac4a 331 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 332 int dig_out_type;
1da177e4
LT
333
334 /* capture */
335 unsigned int num_adc_nids;
336 hda_nid_t *adc_nids;
e1406348 337 hda_nid_t *capsrc_nids;
16ded525 338 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 339
840b64c0
TI
340 /* capture setup for dynamic dual-adc switch */
341 unsigned int cur_adc_idx;
342 hda_nid_t cur_adc;
343 unsigned int cur_adc_stream_tag;
344 unsigned int cur_adc_format;
345
1da177e4 346 /* capture source */
a1e8d2da 347 unsigned int num_mux_defs;
1da177e4
LT
348 const struct hda_input_mux *input_mux;
349 unsigned int cur_mux[3];
6c819492
TI
350 struct alc_mic_route ext_mic;
351 struct alc_mic_route int_mic;
1da177e4
LT
352
353 /* channel model */
d2a6d7dc 354 const struct hda_channel_mode *channel_mode;
1da177e4 355 int num_channel_mode;
4e195a7b 356 int need_dac_fix;
3b315d70
HM
357 int const_channel_count;
358 int ext_channel_count;
1da177e4
LT
359
360 /* PCM information */
4c5186ed 361 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 362
e9edcee0
TI
363 /* dynamic controls, init_verbs and input_mux */
364 struct auto_pin_cfg autocfg;
da00c244 365 struct alc_customize_define cdefine;
603c4019 366 struct snd_array kctls;
61b9b9b1 367 struct hda_input_mux private_imux[3];
41923e44 368 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
369 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
370 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 371
ae6b813a
TI
372 /* hooks */
373 void (*init_hook)(struct hda_codec *codec);
374 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 375#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 376 void (*power_hook)(struct hda_codec *codec);
f5de24b0 377#endif
ae6b813a 378
834be88d
TI
379 /* for pin sensing */
380 unsigned int sense_updated: 1;
381 unsigned int jack_present: 1;
bec15c3a 382 unsigned int master_sw: 1;
6c819492 383 unsigned int auto_mic:1;
cb53c626 384
e64f14f4
TI
385 /* other flags */
386 unsigned int no_analog :1; /* digital I/O only */
840b64c0 387 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
4a79ba34 388 int init_amp;
d433a678 389 int codec_variant; /* flag for other variants */
e64f14f4 390
2134ea4f
TI
391 /* for virtual master */
392 hda_nid_t vmaster_nid;
cb53c626
TI
393#ifdef CONFIG_SND_HDA_POWER_SAVE
394 struct hda_loopback_check loopback;
395#endif
2c3bf9ab
TI
396
397 /* for PLL fix */
398 hda_nid_t pll_nid;
399 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
400
401 /* fix-up list */
402 int fixup_id;
403 const struct alc_fixup *fixup_list;
404 const char *fixup_name;
df694daa
KY
405};
406
407/*
408 * configuration template - to be copied to the spec instance
409 */
410struct alc_config_preset {
9c7f852e
TI
411 struct snd_kcontrol_new *mixers[5]; /* should be identical size
412 * with spec
413 */
f9e336f6 414 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
415 const struct hda_verb *init_verbs[5];
416 unsigned int num_dacs;
417 hda_nid_t *dac_nids;
418 hda_nid_t dig_out_nid; /* optional */
419 hda_nid_t hp_nid; /* optional */
b25c9da1 420 hda_nid_t *slave_dig_outs;
df694daa
KY
421 unsigned int num_adc_nids;
422 hda_nid_t *adc_nids;
e1406348 423 hda_nid_t *capsrc_nids;
df694daa
KY
424 hda_nid_t dig_in_nid;
425 unsigned int num_channel_mode;
426 const struct hda_channel_mode *channel_mode;
4e195a7b 427 int need_dac_fix;
3b315d70 428 int const_channel_count;
a1e8d2da 429 unsigned int num_mux_defs;
df694daa 430 const struct hda_input_mux *input_mux;
ae6b813a 431 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 432 void (*setup)(struct hda_codec *);
ae6b813a 433 void (*init_hook)(struct hda_codec *);
cb53c626
TI
434#ifdef CONFIG_SND_HDA_POWER_SAVE
435 struct hda_amp_list *loopbacks;
c97259df 436 void (*power_hook)(struct hda_codec *codec);
cb53c626 437#endif
1da177e4
LT
438};
439
1da177e4
LT
440
441/*
442 * input MUX handling
443 */
9c7f852e
TI
444static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
445 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
446{
447 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
448 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
449 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
450 if (mux_idx >= spec->num_mux_defs)
451 mux_idx = 0;
5311114d
TI
452 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
453 mux_idx = 0;
a1e8d2da 454 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
455}
456
9c7f852e
TI
457static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
458 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
459{
460 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
461 struct alc_spec *spec = codec->spec;
462 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
463
464 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
465 return 0;
466}
467
9c7f852e
TI
468static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
469 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
470{
471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
472 struct alc_spec *spec = codec->spec;
cd896c33 473 const struct hda_input_mux *imux;
1da177e4 474 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 475 unsigned int mux_idx;
e1406348
TI
476 hda_nid_t nid = spec->capsrc_nids ?
477 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 478 unsigned int type;
1da177e4 479
cd896c33
TI
480 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
481 imux = &spec->input_mux[mux_idx];
5311114d
TI
482 if (!imux->num_items && mux_idx > 0)
483 imux = &spec->input_mux[0];
cd896c33 484
a22d543a 485 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 486 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
487 /* Matrix-mixer style (e.g. ALC882) */
488 unsigned int *cur_val = &spec->cur_mux[adc_idx];
489 unsigned int i, idx;
490
491 idx = ucontrol->value.enumerated.item[0];
492 if (idx >= imux->num_items)
493 idx = imux->num_items - 1;
494 if (*cur_val == idx)
495 return 0;
496 for (i = 0; i < imux->num_items; i++) {
497 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
498 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
499 imux->items[i].index,
500 HDA_AMP_MUTE, v);
501 }
502 *cur_val = idx;
503 return 1;
504 } else {
505 /* MUX style (e.g. ALC880) */
cd896c33 506 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
507 &spec->cur_mux[adc_idx]);
508 }
509}
e9edcee0 510
1da177e4
LT
511/*
512 * channel mode setting
513 */
9c7f852e
TI
514static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
515 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
516{
517 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
518 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
519 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
520 spec->num_channel_mode);
1da177e4
LT
521}
522
9c7f852e
TI
523static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
525{
526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct alc_spec *spec = codec->spec;
d2a6d7dc 528 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 529 spec->num_channel_mode,
3b315d70 530 spec->ext_channel_count);
1da177e4
LT
531}
532
9c7f852e
TI
533static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
534 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
535{
536 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
537 struct alc_spec *spec = codec->spec;
4e195a7b
TI
538 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
539 spec->num_channel_mode,
3b315d70
HM
540 &spec->ext_channel_count);
541 if (err >= 0 && !spec->const_channel_count) {
542 spec->multiout.max_channels = spec->ext_channel_count;
543 if (spec->need_dac_fix)
544 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
545 }
4e195a7b 546 return err;
1da177e4
LT
547}
548
a9430dd8 549/*
4c5186ed 550 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 551 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
552 * being part of a format specifier. Maximum allowed length of a value is
553 * 63 characters plus NULL terminator.
7cf51e48
JW
554 *
555 * Note: some retasking pin complexes seem to ignore requests for input
556 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
557 * are requested. Therefore order this list so that this behaviour will not
558 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
559 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
560 * March 2006.
4c5186ed
JW
561 */
562static char *alc_pin_mode_names[] = {
7cf51e48
JW
563 "Mic 50pc bias", "Mic 80pc bias",
564 "Line in", "Line out", "Headphone out",
4c5186ed
JW
565};
566static unsigned char alc_pin_mode_values[] = {
7cf51e48 567 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
568};
569/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
570 * in the pin being assumed to be exclusively an input or an output pin. In
571 * addition, "input" pins may or may not process the mic bias option
572 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
573 * accept requests for bias as of chip versions up to March 2006) and/or
574 * wiring in the computer.
a9430dd8 575 */
a1e8d2da
JW
576#define ALC_PIN_DIR_IN 0x00
577#define ALC_PIN_DIR_OUT 0x01
578#define ALC_PIN_DIR_INOUT 0x02
579#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
580#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 581
ea1fb29a 582/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
583 * For each direction the minimum and maximum values are given.
584 */
a1e8d2da 585static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
586 { 0, 2 }, /* ALC_PIN_DIR_IN */
587 { 3, 4 }, /* ALC_PIN_DIR_OUT */
588 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
589 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
590 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
591};
592#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
593#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
594#define alc_pin_mode_n_items(_dir) \
595 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
596
9c7f852e
TI
597static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
598 struct snd_ctl_elem_info *uinfo)
a9430dd8 599{
4c5186ed
JW
600 unsigned int item_num = uinfo->value.enumerated.item;
601 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
602
603 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 604 uinfo->count = 1;
4c5186ed
JW
605 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
606
607 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
608 item_num = alc_pin_mode_min(dir);
609 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
610 return 0;
611}
612
9c7f852e
TI
613static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
614 struct snd_ctl_elem_value *ucontrol)
a9430dd8 615{
4c5186ed 616 unsigned int i;
a9430dd8
JW
617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
618 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 619 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 620 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
621 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
622 AC_VERB_GET_PIN_WIDGET_CONTROL,
623 0x00);
a9430dd8 624
4c5186ed
JW
625 /* Find enumerated value for current pinctl setting */
626 i = alc_pin_mode_min(dir);
4b35d2ca 627 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 628 i++;
9c7f852e 629 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
630 return 0;
631}
632
9c7f852e
TI
633static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
634 struct snd_ctl_elem_value *ucontrol)
a9430dd8 635{
4c5186ed 636 signed int change;
a9430dd8
JW
637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
638 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
639 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
640 long val = *ucontrol->value.integer.value;
9c7f852e
TI
641 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
642 AC_VERB_GET_PIN_WIDGET_CONTROL,
643 0x00);
a9430dd8 644
f12ab1e0 645 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
646 val = alc_pin_mode_min(dir);
647
648 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
649 if (change) {
650 /* Set pin mode to that requested */
82beb8fd
TI
651 snd_hda_codec_write_cache(codec, nid, 0,
652 AC_VERB_SET_PIN_WIDGET_CONTROL,
653 alc_pin_mode_values[val]);
cdcd9268 654
ea1fb29a 655 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
656 * for the requested pin mode. Enum values of 2 or less are
657 * input modes.
658 *
659 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
660 * reduces noise slightly (particularly on input) so we'll
661 * do it. However, having both input and output buffers
662 * enabled simultaneously doesn't seem to be problematic if
663 * this turns out to be necessary in the future.
cdcd9268
JW
664 */
665 if (val <= 2) {
47fd830a
TI
666 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
667 HDA_AMP_MUTE, HDA_AMP_MUTE);
668 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
669 HDA_AMP_MUTE, 0);
cdcd9268 670 } else {
47fd830a
TI
671 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
672 HDA_AMP_MUTE, HDA_AMP_MUTE);
673 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
674 HDA_AMP_MUTE, 0);
cdcd9268
JW
675 }
676 }
a9430dd8
JW
677 return change;
678}
679
4c5186ed 680#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 681 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 682 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
683 .info = alc_pin_mode_info, \
684 .get = alc_pin_mode_get, \
685 .put = alc_pin_mode_put, \
686 .private_value = nid | (dir<<16) }
df694daa 687
5c8f858d
JW
688/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
689 * together using a mask with more than one bit set. This control is
690 * currently used only by the ALC260 test model. At this stage they are not
691 * needed for any "production" models.
692 */
693#ifdef CONFIG_SND_DEBUG
a5ce8890 694#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 695
9c7f852e
TI
696static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
697 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
698{
699 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
700 hda_nid_t nid = kcontrol->private_value & 0xffff;
701 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
702 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
703 unsigned int val = snd_hda_codec_read(codec, nid, 0,
704 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
705
706 *valp = (val & mask) != 0;
707 return 0;
708}
9c7f852e
TI
709static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
710 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
711{
712 signed int change;
713 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
714 hda_nid_t nid = kcontrol->private_value & 0xffff;
715 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
716 long val = *ucontrol->value.integer.value;
9c7f852e
TI
717 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
718 AC_VERB_GET_GPIO_DATA,
719 0x00);
5c8f858d
JW
720
721 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
722 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
723 if (val == 0)
5c8f858d
JW
724 gpio_data &= ~mask;
725 else
726 gpio_data |= mask;
82beb8fd
TI
727 snd_hda_codec_write_cache(codec, nid, 0,
728 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
729
730 return change;
731}
732#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
733 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 734 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
735 .info = alc_gpio_data_info, \
736 .get = alc_gpio_data_get, \
737 .put = alc_gpio_data_put, \
738 .private_value = nid | (mask<<16) }
739#endif /* CONFIG_SND_DEBUG */
740
92621f13
JW
741/* A switch control to allow the enabling of the digital IO pins on the
742 * ALC260. This is incredibly simplistic; the intention of this control is
743 * to provide something in the test model allowing digital outputs to be
744 * identified if present. If models are found which can utilise these
745 * outputs a more complete mixer control can be devised for those models if
746 * necessary.
747 */
748#ifdef CONFIG_SND_DEBUG
a5ce8890 749#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 750
9c7f852e
TI
751static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
752 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
753{
754 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
755 hda_nid_t nid = kcontrol->private_value & 0xffff;
756 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
757 long *valp = ucontrol->value.integer.value;
9c7f852e 758 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 759 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
760
761 *valp = (val & mask) != 0;
762 return 0;
763}
9c7f852e
TI
764static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
765 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
766{
767 signed int change;
768 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
769 hda_nid_t nid = kcontrol->private_value & 0xffff;
770 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
771 long val = *ucontrol->value.integer.value;
9c7f852e 772 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 773 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 774 0x00);
92621f13
JW
775
776 /* Set/unset the masked control bit(s) as needed */
9c7f852e 777 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
778 if (val==0)
779 ctrl_data &= ~mask;
780 else
781 ctrl_data |= mask;
82beb8fd
TI
782 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
783 ctrl_data);
92621f13
JW
784
785 return change;
786}
787#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
788 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 789 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
790 .info = alc_spdif_ctrl_info, \
791 .get = alc_spdif_ctrl_get, \
792 .put = alc_spdif_ctrl_put, \
793 .private_value = nid | (mask<<16) }
794#endif /* CONFIG_SND_DEBUG */
795
f8225f6d
JW
796/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
797 * Again, this is only used in the ALC26x test models to help identify when
798 * the EAPD line must be asserted for features to work.
799 */
800#ifdef CONFIG_SND_DEBUG
801#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
802
803static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
804 struct snd_ctl_elem_value *ucontrol)
805{
806 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
807 hda_nid_t nid = kcontrol->private_value & 0xffff;
808 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
809 long *valp = ucontrol->value.integer.value;
810 unsigned int val = snd_hda_codec_read(codec, nid, 0,
811 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
812
813 *valp = (val & mask) != 0;
814 return 0;
815}
816
817static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
818 struct snd_ctl_elem_value *ucontrol)
819{
820 int change;
821 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
822 hda_nid_t nid = kcontrol->private_value & 0xffff;
823 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
824 long val = *ucontrol->value.integer.value;
825 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
826 AC_VERB_GET_EAPD_BTLENABLE,
827 0x00);
828
829 /* Set/unset the masked control bit(s) as needed */
830 change = (!val ? 0 : mask) != (ctrl_data & mask);
831 if (!val)
832 ctrl_data &= ~mask;
833 else
834 ctrl_data |= mask;
835 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
836 ctrl_data);
837
838 return change;
839}
840
841#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
842 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 843 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
844 .info = alc_eapd_ctrl_info, \
845 .get = alc_eapd_ctrl_get, \
846 .put = alc_eapd_ctrl_put, \
847 .private_value = nid | (mask<<16) }
848#endif /* CONFIG_SND_DEBUG */
849
23f0c048
TI
850/*
851 * set up the input pin config (depending on the given auto-pin type)
852 */
853static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
854 int auto_pin_type)
855{
856 unsigned int val = PIN_IN;
857
86e2959a 858 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 859 unsigned int pincap;
954a29c8
TI
860 unsigned int oldval;
861 oldval = snd_hda_codec_read(codec, nid, 0,
862 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 863 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 864 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
865 /* if the default pin setup is vref50, we give it priority */
866 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 867 val = PIN_VREF80;
461c6c3a
TI
868 else if (pincap & AC_PINCAP_VREF_50)
869 val = PIN_VREF50;
870 else if (pincap & AC_PINCAP_VREF_100)
871 val = PIN_VREF100;
872 else if (pincap & AC_PINCAP_VREF_GRD)
873 val = PIN_VREFGRD;
23f0c048
TI
874 }
875 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
876}
877
f6837bbd
TI
878static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
879{
880 struct alc_spec *spec = codec->spec;
881 struct auto_pin_cfg *cfg = &spec->autocfg;
882
883 if (!cfg->line_outs) {
884 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
885 cfg->line_out_pins[cfg->line_outs])
886 cfg->line_outs++;
887 }
888 if (!cfg->speaker_outs) {
889 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
890 cfg->speaker_pins[cfg->speaker_outs])
891 cfg->speaker_outs++;
892 }
893 if (!cfg->hp_outs) {
894 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
895 cfg->hp_pins[cfg->hp_outs])
896 cfg->hp_outs++;
897 }
898}
899
d88897ea
TI
900/*
901 */
902static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
903{
904 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
905 return;
906 spec->mixers[spec->num_mixers++] = mix;
907}
908
909static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
910{
911 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
912 return;
913 spec->init_verbs[spec->num_init_verbs++] = verb;
914}
915
df694daa
KY
916/*
917 * set up from the preset table
918 */
e9c364c0 919static void setup_preset(struct hda_codec *codec,
9c7f852e 920 const struct alc_config_preset *preset)
df694daa 921{
e9c364c0 922 struct alc_spec *spec = codec->spec;
df694daa
KY
923 int i;
924
925 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 926 add_mixer(spec, preset->mixers[i]);
f9e336f6 927 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
928 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
929 i++)
d88897ea 930 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 931
df694daa
KY
932 spec->channel_mode = preset->channel_mode;
933 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 934 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 935 spec->const_channel_count = preset->const_channel_count;
df694daa 936
3b315d70
HM
937 if (preset->const_channel_count)
938 spec->multiout.max_channels = preset->const_channel_count;
939 else
940 spec->multiout.max_channels = spec->channel_mode[0].channels;
941 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
942
943 spec->multiout.num_dacs = preset->num_dacs;
944 spec->multiout.dac_nids = preset->dac_nids;
945 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 946 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 947 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 948
a1e8d2da 949 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 950 if (!spec->num_mux_defs)
a1e8d2da 951 spec->num_mux_defs = 1;
df694daa
KY
952 spec->input_mux = preset->input_mux;
953
954 spec->num_adc_nids = preset->num_adc_nids;
955 spec->adc_nids = preset->adc_nids;
e1406348 956 spec->capsrc_nids = preset->capsrc_nids;
df694daa 957 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
958
959 spec->unsol_event = preset->unsol_event;
960 spec->init_hook = preset->init_hook;
cb53c626 961#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 962 spec->power_hook = preset->power_hook;
cb53c626
TI
963 spec->loopback.amplist = preset->loopbacks;
964#endif
e9c364c0
TI
965
966 if (preset->setup)
967 preset->setup(codec);
f6837bbd
TI
968
969 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
970}
971
bc9f98a9
KY
972/* Enable GPIO mask and set output */
973static struct hda_verb alc_gpio1_init_verbs[] = {
974 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
975 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
976 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
977 { }
978};
979
980static struct hda_verb alc_gpio2_init_verbs[] = {
981 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
982 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
983 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
984 { }
985};
986
bdd148a3
KY
987static struct hda_verb alc_gpio3_init_verbs[] = {
988 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
989 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
990 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
991 { }
992};
993
2c3bf9ab
TI
994/*
995 * Fix hardware PLL issue
996 * On some codecs, the analog PLL gating control must be off while
997 * the default value is 1.
998 */
999static void alc_fix_pll(struct hda_codec *codec)
1000{
1001 struct alc_spec *spec = codec->spec;
1002 unsigned int val;
1003
1004 if (!spec->pll_nid)
1005 return;
1006 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1007 spec->pll_coef_idx);
1008 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1009 AC_VERB_GET_PROC_COEF, 0);
1010 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1011 spec->pll_coef_idx);
1012 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1013 val & ~(1 << spec->pll_coef_bit));
1014}
1015
1016static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1017 unsigned int coef_idx, unsigned int coef_bit)
1018{
1019 struct alc_spec *spec = codec->spec;
1020 spec->pll_nid = nid;
1021 spec->pll_coef_idx = coef_idx;
1022 spec->pll_coef_bit = coef_bit;
1023 alc_fix_pll(codec);
1024}
1025
9ad0e496
KY
1026static int alc_init_jacks(struct hda_codec *codec)
1027{
cd372fb3 1028#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1029 struct alc_spec *spec = codec->spec;
1030 int err;
1031 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1032 unsigned int mic_nid = spec->ext_mic.pin;
1033
265a0247 1034 if (hp_nid) {
cd372fb3
TI
1035 err = snd_hda_input_jack_add(codec, hp_nid,
1036 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1037 if (err < 0)
1038 return err;
cd372fb3 1039 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1040 }
9ad0e496 1041
265a0247 1042 if (mic_nid) {
cd372fb3
TI
1043 err = snd_hda_input_jack_add(codec, mic_nid,
1044 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1045 if (err < 0)
1046 return err;
cd372fb3 1047 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1048 }
cd372fb3 1049#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1050 return 0;
1051}
9ad0e496 1052
bb35febd 1053static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
c9b58006
KY
1054{
1055 struct alc_spec *spec = codec->spec;
bb35febd
TI
1056 unsigned int mute;
1057 hda_nid_t nid;
a9fd4f3f 1058 int i;
c9b58006 1059
bb35febd
TI
1060 spec->jack_present = 0;
1061 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1062 nid = spec->autocfg.hp_pins[i];
1063 if (!nid)
1064 break;
cd372fb3 1065 snd_hda_input_jack_report(codec, nid);
f0ce2799 1066 spec->jack_present |= snd_hda_jack_detect(codec, nid);
bb35febd
TI
1067 }
1068
1069 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1070 /* Toggle internal speakers muting */
a9fd4f3f
TI
1071 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1072 nid = spec->autocfg.speaker_pins[i];
1073 if (!nid)
1074 break;
bb35febd
TI
1075 if (pinctl) {
1076 snd_hda_codec_write(codec, nid, 0,
a9fd4f3f
TI
1077 AC_VERB_SET_PIN_WIDGET_CONTROL,
1078 spec->jack_present ? 0 : PIN_OUT);
bb35febd
TI
1079 } else {
1080 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1081 HDA_AMP_MUTE, mute);
1082 }
a9fd4f3f 1083 }
c9b58006
KY
1084}
1085
bb35febd
TI
1086static void alc_automute_pin(struct hda_codec *codec)
1087{
1088 alc_automute_speaker(codec, 1);
1089}
1090
6c819492
TI
1091static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1092 hda_nid_t nid)
1093{
1094 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1095 int i, nums;
1096
1097 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1098 for (i = 0; i < nums; i++)
1099 if (conn[i] == nid)
1100 return i;
1101 return -1;
1102}
1103
840b64c0
TI
1104/* switch the current ADC according to the jack state */
1105static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1106{
1107 struct alc_spec *spec = codec->spec;
1108 unsigned int present;
1109 hda_nid_t new_adc;
1110
1111 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1112 if (present)
1113 spec->cur_adc_idx = 1;
1114 else
1115 spec->cur_adc_idx = 0;
1116 new_adc = spec->adc_nids[spec->cur_adc_idx];
1117 if (spec->cur_adc && spec->cur_adc != new_adc) {
1118 /* stream is running, let's swap the current ADC */
f0cea797 1119 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1120 spec->cur_adc = new_adc;
1121 snd_hda_codec_setup_stream(codec, new_adc,
1122 spec->cur_adc_stream_tag, 0,
1123 spec->cur_adc_format);
1124 }
1125}
1126
7fb0d78f
KY
1127static void alc_mic_automute(struct hda_codec *codec)
1128{
1129 struct alc_spec *spec = codec->spec;
6c819492
TI
1130 struct alc_mic_route *dead, *alive;
1131 unsigned int present, type;
1132 hda_nid_t cap_nid;
1133
b59bdf3b
TI
1134 if (!spec->auto_mic)
1135 return;
6c819492
TI
1136 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1137 return;
1138 if (snd_BUG_ON(!spec->adc_nids))
1139 return;
1140
840b64c0
TI
1141 if (spec->dual_adc_switch) {
1142 alc_dual_mic_adc_auto_switch(codec);
1143 return;
1144 }
1145
6c819492
TI
1146 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1147
864f92be 1148 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1149 if (present) {
1150 alive = &spec->ext_mic;
1151 dead = &spec->int_mic;
1152 } else {
1153 alive = &spec->int_mic;
1154 dead = &spec->ext_mic;
1155 }
1156
6c819492
TI
1157 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1158 if (type == AC_WID_AUD_MIX) {
1159 /* Matrix-mixer style (e.g. ALC882) */
1160 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1161 alive->mux_idx,
1162 HDA_AMP_MUTE, 0);
1163 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1164 dead->mux_idx,
1165 HDA_AMP_MUTE, HDA_AMP_MUTE);
1166 } else {
1167 /* MUX style (e.g. ALC880) */
1168 snd_hda_codec_write_cache(codec, cap_nid, 0,
1169 AC_VERB_SET_CONNECT_SEL,
1170 alive->mux_idx);
1171 }
cd372fb3 1172 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1173
1174 /* FIXME: analog mixer */
7fb0d78f
KY
1175}
1176
c9b58006
KY
1177/* unsolicited event for HP jack sensing */
1178static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1179{
1180 if (codec->vendor_id == 0x10ec0880)
1181 res >>= 28;
1182 else
1183 res >>= 26;
a9fd4f3f
TI
1184 switch (res) {
1185 case ALC880_HP_EVENT:
1186 alc_automute_pin(codec);
1187 break;
1188 case ALC880_MIC_EVENT:
7fb0d78f 1189 alc_mic_automute(codec);
a9fd4f3f
TI
1190 break;
1191 }
7fb0d78f
KY
1192}
1193
1194static void alc_inithook(struct hda_codec *codec)
1195{
a9fd4f3f 1196 alc_automute_pin(codec);
7fb0d78f 1197 alc_mic_automute(codec);
c9b58006
KY
1198}
1199
f9423e7a
KY
1200/* additional initialization for ALC888 variants */
1201static void alc888_coef_init(struct hda_codec *codec)
1202{
1203 unsigned int tmp;
1204
1205 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1206 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1207 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1208 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1209 /* alc888S-VC */
1210 snd_hda_codec_read(codec, 0x20, 0,
1211 AC_VERB_SET_PROC_COEF, 0x830);
1212 else
1213 /* alc888-VB */
1214 snd_hda_codec_read(codec, 0x20, 0,
1215 AC_VERB_SET_PROC_COEF, 0x3030);
1216}
1217
87a8c370
JK
1218static void alc889_coef_init(struct hda_codec *codec)
1219{
1220 unsigned int tmp;
1221
1222 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1223 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1224 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1225 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1226}
1227
3fb4a508
TI
1228/* turn on/off EAPD control (only if available) */
1229static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1230{
1231 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1232 return;
1233 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1234 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1235 on ? 2 : 0);
1236}
1237
4a79ba34 1238static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1239{
4a79ba34 1240 unsigned int tmp;
bc9f98a9 1241
4a79ba34
TI
1242 switch (type) {
1243 case ALC_INIT_GPIO1:
bc9f98a9
KY
1244 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1245 break;
4a79ba34 1246 case ALC_INIT_GPIO2:
bc9f98a9
KY
1247 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1248 break;
4a79ba34 1249 case ALC_INIT_GPIO3:
bdd148a3
KY
1250 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1251 break;
4a79ba34 1252 case ALC_INIT_DEFAULT:
bdd148a3 1253 switch (codec->vendor_id) {
c9b58006 1254 case 0x10ec0260:
3fb4a508
TI
1255 set_eapd(codec, 0x0f, 1);
1256 set_eapd(codec, 0x10, 1);
c9b58006
KY
1257 break;
1258 case 0x10ec0262:
bdd148a3
KY
1259 case 0x10ec0267:
1260 case 0x10ec0268:
c9b58006 1261 case 0x10ec0269:
3fb4a508 1262 case 0x10ec0270:
c6e8f2da 1263 case 0x10ec0272:
f9423e7a
KY
1264 case 0x10ec0660:
1265 case 0x10ec0662:
1266 case 0x10ec0663:
c9b58006 1267 case 0x10ec0862:
20a3a05d 1268 case 0x10ec0889:
3fb4a508
TI
1269 set_eapd(codec, 0x14, 1);
1270 set_eapd(codec, 0x15, 1);
c9b58006 1271 break;
bdd148a3 1272 }
c9b58006
KY
1273 switch (codec->vendor_id) {
1274 case 0x10ec0260:
1275 snd_hda_codec_write(codec, 0x1a, 0,
1276 AC_VERB_SET_COEF_INDEX, 7);
1277 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1278 AC_VERB_GET_PROC_COEF, 0);
1279 snd_hda_codec_write(codec, 0x1a, 0,
1280 AC_VERB_SET_COEF_INDEX, 7);
1281 snd_hda_codec_write(codec, 0x1a, 0,
1282 AC_VERB_SET_PROC_COEF,
1283 tmp | 0x2010);
1284 break;
1285 case 0x10ec0262:
1286 case 0x10ec0880:
1287 case 0x10ec0882:
1288 case 0x10ec0883:
1289 case 0x10ec0885:
4a5a4c56 1290 case 0x10ec0887:
20a3a05d 1291 case 0x10ec0889:
87a8c370 1292 alc889_coef_init(codec);
c9b58006 1293 break;
f9423e7a 1294 case 0x10ec0888:
4a79ba34 1295 alc888_coef_init(codec);
f9423e7a 1296 break;
0aea778e 1297#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1298 case 0x10ec0267:
1299 case 0x10ec0268:
1300 snd_hda_codec_write(codec, 0x20, 0,
1301 AC_VERB_SET_COEF_INDEX, 7);
1302 tmp = snd_hda_codec_read(codec, 0x20, 0,
1303 AC_VERB_GET_PROC_COEF, 0);
1304 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1305 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1306 snd_hda_codec_write(codec, 0x20, 0,
1307 AC_VERB_SET_PROC_COEF,
1308 tmp | 0x3000);
1309 break;
0aea778e 1310#endif /* XXX */
bc9f98a9 1311 }
4a79ba34
TI
1312 break;
1313 }
1314}
1315
1316static void alc_init_auto_hp(struct hda_codec *codec)
1317{
1318 struct alc_spec *spec = codec->spec;
bb35febd
TI
1319 struct auto_pin_cfg *cfg = &spec->autocfg;
1320 int i;
4a79ba34 1321
bb35febd
TI
1322 if (!cfg->hp_pins[0]) {
1323 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1324 return;
1325 }
4a79ba34 1326
bb35febd
TI
1327 if (!cfg->speaker_pins[0]) {
1328 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4a79ba34 1329 return;
bb35febd
TI
1330 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1331 sizeof(cfg->speaker_pins));
1332 cfg->speaker_outs = cfg->line_outs;
1333 }
1334
1335 if (!cfg->hp_pins[0]) {
1336 memcpy(cfg->hp_pins, cfg->line_out_pins,
1337 sizeof(cfg->hp_pins));
1338 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1339 }
1340
bb35febd
TI
1341 for (i = 0; i < cfg->hp_outs; i++) {
1342 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1343 cfg->hp_pins[i]);
1344 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
4a79ba34
TI
1345 AC_VERB_SET_UNSOLICITED_ENABLE,
1346 AC_USRSP_EN | ALC880_HP_EVENT);
bb35febd 1347 }
4a79ba34
TI
1348 spec->unsol_event = alc_sku_unsol_event;
1349}
1350
6c819492
TI
1351static void alc_init_auto_mic(struct hda_codec *codec)
1352{
1353 struct alc_spec *spec = codec->spec;
1354 struct auto_pin_cfg *cfg = &spec->autocfg;
1355 hda_nid_t fixed, ext;
1356 int i;
1357
1358 /* there must be only two mic inputs exclusively */
66ceeb6b 1359 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1360 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1361 return;
1362
1363 fixed = ext = 0;
66ceeb6b
TI
1364 for (i = 0; i < cfg->num_inputs; i++) {
1365 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1366 unsigned int defcfg;
6c819492 1367 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1368 switch (snd_hda_get_input_pin_attr(defcfg)) {
1369 case INPUT_PIN_ATTR_INT:
6c819492
TI
1370 if (fixed)
1371 return; /* already occupied */
1372 fixed = nid;
1373 break;
99ae28be
TI
1374 case INPUT_PIN_ATTR_UNUSED:
1375 return; /* invalid entry */
1376 default:
6c819492
TI
1377 if (ext)
1378 return; /* already occupied */
1379 ext = nid;
1380 break;
6c819492
TI
1381 }
1382 }
eaa9b3a7
TI
1383 if (!ext || !fixed)
1384 return;
6c819492
TI
1385 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1386 return; /* no unsol support */
1387 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1388 ext, fixed);
1389 spec->ext_mic.pin = ext;
1390 spec->int_mic.pin = fixed;
1391 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1392 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1393 spec->auto_mic = 1;
1394 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1395 AC_VERB_SET_UNSOLICITED_ENABLE,
1396 AC_USRSP_EN | ALC880_MIC_EVENT);
1397 spec->unsol_event = alc_sku_unsol_event;
1398}
1399
90622917
DH
1400/* Could be any non-zero and even value. When used as fixup, tells
1401 * the driver to ignore any present sku defines.
1402 */
1403#define ALC_FIXUP_SKU_IGNORE (2)
1404
da00c244
KY
1405static int alc_auto_parse_customize_define(struct hda_codec *codec)
1406{
1407 unsigned int ass, tmp, i;
7fb56223 1408 unsigned nid = 0;
da00c244
KY
1409 struct alc_spec *spec = codec->spec;
1410
b6cbe517
TI
1411 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1412
90622917
DH
1413 if (spec->cdefine.fixup) {
1414 ass = spec->cdefine.sku_cfg;
1415 if (ass == ALC_FIXUP_SKU_IGNORE)
1416 return -1;
1417 goto do_sku;
1418 }
1419
da00c244 1420 ass = codec->subsystem_id & 0xffff;
b6cbe517 1421 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1422 goto do_sku;
1423
1424 nid = 0x1d;
1425 if (codec->vendor_id == 0x10ec0260)
1426 nid = 0x17;
1427 ass = snd_hda_codec_get_pincfg(codec, nid);
1428
1429 if (!(ass & 1)) {
1430 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1431 codec->chip_name, ass);
1432 return -1;
1433 }
1434
1435 /* check sum */
1436 tmp = 0;
1437 for (i = 1; i < 16; i++) {
1438 if ((ass >> i) & 1)
1439 tmp++;
1440 }
1441 if (((ass >> 16) & 0xf) != tmp)
1442 return -1;
1443
1444 spec->cdefine.port_connectivity = ass >> 30;
1445 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1446 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1447 spec->cdefine.customization = ass >> 8;
1448do_sku:
1449 spec->cdefine.sku_cfg = ass;
1450 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1451 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1452 spec->cdefine.swap = (ass & 0x2) >> 1;
1453 spec->cdefine.override = ass & 0x1;
1454
1455 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1456 nid, spec->cdefine.sku_cfg);
1457 snd_printd("SKU: port_connectivity=0x%x\n",
1458 spec->cdefine.port_connectivity);
1459 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1460 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1461 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1462 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1463 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1464 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1465 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1466
1467 return 0;
1468}
1469
4a79ba34
TI
1470/* check subsystem ID and set up device-specific initialization;
1471 * return 1 if initialized, 0 if invalid SSID
1472 */
1473/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1474 * 31 ~ 16 : Manufacture ID
1475 * 15 ~ 8 : SKU ID
1476 * 7 ~ 0 : Assembly ID
1477 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1478 */
1479static int alc_subsystem_id(struct hda_codec *codec,
1480 hda_nid_t porta, hda_nid_t porte,
6227cdce 1481 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1482{
1483 unsigned int ass, tmp, i;
1484 unsigned nid;
1485 struct alc_spec *spec = codec->spec;
1486
90622917
DH
1487 if (spec->cdefine.fixup) {
1488 ass = spec->cdefine.sku_cfg;
1489 if (ass == ALC_FIXUP_SKU_IGNORE)
1490 return 0;
1491 goto do_sku;
1492 }
1493
4a79ba34
TI
1494 ass = codec->subsystem_id & 0xffff;
1495 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1496 goto do_sku;
1497
1498 /* invalid SSID, check the special NID pin defcfg instead */
1499 /*
def319f9 1500 * 31~30 : port connectivity
4a79ba34
TI
1501 * 29~21 : reserve
1502 * 20 : PCBEEP input
1503 * 19~16 : Check sum (15:1)
1504 * 15~1 : Custom
1505 * 0 : override
1506 */
1507 nid = 0x1d;
1508 if (codec->vendor_id == 0x10ec0260)
1509 nid = 0x17;
1510 ass = snd_hda_codec_get_pincfg(codec, nid);
1511 snd_printd("realtek: No valid SSID, "
1512 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1513 ass, nid);
6227cdce 1514 if (!(ass & 1))
4a79ba34
TI
1515 return 0;
1516 if ((ass >> 30) != 1) /* no physical connection */
1517 return 0;
1518
1519 /* check sum */
1520 tmp = 0;
1521 for (i = 1; i < 16; i++) {
1522 if ((ass >> i) & 1)
1523 tmp++;
1524 }
1525 if (((ass >> 16) & 0xf) != tmp)
1526 return 0;
1527do_sku:
1528 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1529 ass & 0xffff, codec->vendor_id);
1530 /*
1531 * 0 : override
1532 * 1 : Swap Jack
1533 * 2 : 0 --> Desktop, 1 --> Laptop
1534 * 3~5 : External Amplifier control
1535 * 7~6 : Reserved
1536 */
1537 tmp = (ass & 0x38) >> 3; /* external Amp control */
1538 switch (tmp) {
1539 case 1:
1540 spec->init_amp = ALC_INIT_GPIO1;
1541 break;
1542 case 3:
1543 spec->init_amp = ALC_INIT_GPIO2;
1544 break;
1545 case 7:
1546 spec->init_amp = ALC_INIT_GPIO3;
1547 break;
1548 case 5:
5a8cfb4e 1549 default:
4a79ba34 1550 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1551 break;
1552 }
ea1fb29a 1553
8c427226 1554 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1555 * when the external headphone out jack is plugged"
1556 */
8c427226 1557 if (!(ass & 0x8000))
4a79ba34 1558 return 1;
c9b58006
KY
1559 /*
1560 * 10~8 : Jack location
1561 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1562 * 14~13: Resvered
1563 * 15 : 1 --> enable the function "Mute internal speaker
1564 * when the external headphone out jack is plugged"
1565 */
c9b58006 1566 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1567 hda_nid_t nid;
c9b58006
KY
1568 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1569 if (tmp == 0)
01d4825d 1570 nid = porta;
c9b58006 1571 else if (tmp == 1)
01d4825d 1572 nid = porte;
c9b58006 1573 else if (tmp == 2)
01d4825d 1574 nid = portd;
6227cdce
KY
1575 else if (tmp == 3)
1576 nid = porti;
c9b58006 1577 else
4a79ba34 1578 return 1;
01d4825d
TI
1579 for (i = 0; i < spec->autocfg.line_outs; i++)
1580 if (spec->autocfg.line_out_pins[i] == nid)
1581 return 1;
1582 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1583 }
1584
4a79ba34 1585 alc_init_auto_hp(codec);
6c819492 1586 alc_init_auto_mic(codec);
4a79ba34
TI
1587 return 1;
1588}
ea1fb29a 1589
4a79ba34 1590static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1591 hda_nid_t porta, hda_nid_t porte,
1592 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1593{
6227cdce 1594 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1595 struct alc_spec *spec = codec->spec;
1596 snd_printd("realtek: "
1597 "Enable default setup for auto mode as fallback\n");
1598 spec->init_amp = ALC_INIT_DEFAULT;
1599 alc_init_auto_hp(codec);
6c819492 1600 alc_init_auto_mic(codec);
4a79ba34 1601 }
bc9f98a9
KY
1602}
1603
f95474ec 1604/*
f8f25ba3 1605 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1606 */
1607
1608struct alc_pincfg {
1609 hda_nid_t nid;
1610 u32 val;
1611};
1612
e1eb5f10
TB
1613struct alc_model_fixup {
1614 const int id;
1615 const char *name;
1616};
1617
f8f25ba3 1618struct alc_fixup {
b5bfbc67 1619 int type;
361fe6e9
TI
1620 bool chained;
1621 int chain_id;
b5bfbc67
TI
1622 union {
1623 unsigned int sku;
1624 const struct alc_pincfg *pins;
1625 const struct hda_verb *verbs;
1626 void (*func)(struct hda_codec *codec,
1627 const struct alc_fixup *fix,
1628 int action);
1629 } v;
f8f25ba3
TI
1630};
1631
b5bfbc67
TI
1632enum {
1633 ALC_FIXUP_INVALID,
1634 ALC_FIXUP_SKU,
1635 ALC_FIXUP_PINS,
1636 ALC_FIXUP_VERBS,
1637 ALC_FIXUP_FUNC,
1638};
1639
1640enum {
1641 ALC_FIXUP_ACT_PRE_PROBE,
1642 ALC_FIXUP_ACT_PROBE,
58701120 1643 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1644};
1645
1646static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1647{
b5bfbc67
TI
1648 struct alc_spec *spec = codec->spec;
1649 int id = spec->fixup_id;
aa1d0c52 1650#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1651 const char *modelname = spec->fixup_name;
aa1d0c52 1652#endif
b5bfbc67 1653 int depth = 0;
f95474ec 1654
b5bfbc67
TI
1655 if (!spec->fixup_list)
1656 return;
1657
1658 while (id >= 0) {
1659 const struct alc_fixup *fix = spec->fixup_list + id;
1660 const struct alc_pincfg *cfg;
1661
1662 switch (fix->type) {
1663 case ALC_FIXUP_SKU:
1664 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1665 break;;
1666 snd_printdd(KERN_INFO "hda_codec: %s: "
1667 "Apply sku override for %s\n",
1668 codec->chip_name, modelname);
1669 spec->cdefine.sku_cfg = fix->v.sku;
1670 spec->cdefine.fixup = 1;
1671 break;
1672 case ALC_FIXUP_PINS:
1673 cfg = fix->v.pins;
1674 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1675 break;
1676 snd_printdd(KERN_INFO "hda_codec: %s: "
1677 "Apply pincfg for %s\n",
1678 codec->chip_name, modelname);
1679 for (; cfg->nid; cfg++)
1680 snd_hda_codec_set_pincfg(codec, cfg->nid,
1681 cfg->val);
1682 break;
1683 case ALC_FIXUP_VERBS:
1684 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1685 break;
1686 snd_printdd(KERN_INFO "hda_codec: %s: "
1687 "Apply fix-verbs for %s\n",
1688 codec->chip_name, modelname);
1689 add_verb(codec->spec, fix->v.verbs);
1690 break;
1691 case ALC_FIXUP_FUNC:
1692 if (!fix->v.func)
1693 break;
1694 snd_printdd(KERN_INFO "hda_codec: %s: "
1695 "Apply fix-func for %s\n",
1696 codec->chip_name, modelname);
1697 fix->v.func(codec, fix, action);
1698 break;
1699 default:
1700 snd_printk(KERN_ERR "hda_codec: %s: "
1701 "Invalid fixup type %d\n",
1702 codec->chip_name, fix->type);
1703 break;
1704 }
1705 if (!fix[id].chained)
1706 break;
1707 if (++depth > 10)
1708 break;
1709 id = fix[id].chain_id;
9d57883f 1710 }
f95474ec
TI
1711}
1712
e1eb5f10 1713static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1714 const struct alc_model_fixup *models,
1715 const struct snd_pci_quirk *quirk,
1716 const struct alc_fixup *fixlist)
e1eb5f10 1717{
b5bfbc67
TI
1718 struct alc_spec *spec = codec->spec;
1719 int id = -1;
1720 const char *name = NULL;
e1eb5f10 1721
e1eb5f10
TB
1722 if (codec->modelname && models) {
1723 while (models->name) {
1724 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
1725 id = models->id;
1726 name = models->name;
e1eb5f10
TB
1727 break;
1728 }
1729 models++;
1730 }
b5bfbc67
TI
1731 }
1732 if (id < 0) {
1733 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1734 if (quirk) {
1735 id = quirk->value;
1736#ifdef CONFIG_SND_DEBUG_VERBOSE
1737 name = quirk->name;
1738#endif
1739 }
1740 }
1741
1742 spec->fixup_id = id;
1743 if (id >= 0) {
1744 spec->fixup_list = fixlist;
1745 spec->fixup_name = name;
e1eb5f10 1746 }
f95474ec
TI
1747}
1748
274693f3
KY
1749static int alc_read_coef_idx(struct hda_codec *codec,
1750 unsigned int coef_idx)
1751{
1752 unsigned int val;
1753 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1754 coef_idx);
1755 val = snd_hda_codec_read(codec, 0x20, 0,
1756 AC_VERB_GET_PROC_COEF, 0);
1757 return val;
1758}
1759
977ddd6b
KY
1760static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1761 unsigned int coef_val)
1762{
1763 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1764 coef_idx);
1765 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1766 coef_val);
1767}
1768
757899ac
TI
1769/* set right pin controls for digital I/O */
1770static void alc_auto_init_digital(struct hda_codec *codec)
1771{
1772 struct alc_spec *spec = codec->spec;
1773 int i;
1774 hda_nid_t pin;
1775
1776 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1777 pin = spec->autocfg.dig_out_pins[i];
1778 if (pin) {
1779 snd_hda_codec_write(codec, pin, 0,
1780 AC_VERB_SET_PIN_WIDGET_CONTROL,
1781 PIN_OUT);
1782 }
1783 }
1784 pin = spec->autocfg.dig_in_pin;
1785 if (pin)
1786 snd_hda_codec_write(codec, pin, 0,
1787 AC_VERB_SET_PIN_WIDGET_CONTROL,
1788 PIN_IN);
1789}
1790
1791/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1792static void alc_auto_parse_digital(struct hda_codec *codec)
1793{
1794 struct alc_spec *spec = codec->spec;
1795 int i, err;
1796 hda_nid_t dig_nid;
1797
1798 /* support multiple SPDIFs; the secondary is set up as a slave */
1799 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1800 err = snd_hda_get_connections(codec,
1801 spec->autocfg.dig_out_pins[i],
1802 &dig_nid, 1);
1803 if (err < 0)
1804 continue;
1805 if (!i) {
1806 spec->multiout.dig_out_nid = dig_nid;
1807 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1808 } else {
1809 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1810 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1811 break;
1812 spec->slave_dig_outs[i - 1] = dig_nid;
1813 }
1814 }
1815
1816 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
1817 dig_nid = codec->start_nid;
1818 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1819 unsigned int wcaps = get_wcaps(codec, dig_nid);
1820 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1821 continue;
1822 if (!(wcaps & AC_WCAP_DIGITAL))
1823 continue;
1824 if (!(wcaps & AC_WCAP_CONN_LIST))
1825 continue;
1826 err = get_connection_index(codec, dig_nid,
1827 spec->autocfg.dig_in_pin);
1828 if (err >= 0) {
1829 spec->dig_in_nid = dig_nid;
1830 break;
1831 }
1832 }
757899ac
TI
1833 }
1834}
1835
ef8ef5fb
VP
1836/*
1837 * ALC888
1838 */
1839
1840/*
1841 * 2ch mode
1842 */
1843static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1844/* Mic-in jack as mic in */
1845 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1846 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1847/* Line-in jack as Line in */
1848 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1849 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1850/* Line-Out as Front */
1851 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1852 { } /* end */
1853};
1854
1855/*
1856 * 4ch mode
1857 */
1858static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1859/* Mic-in jack as mic in */
1860 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1861 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1862/* Line-in jack as Surround */
1863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1865/* Line-Out as Front */
1866 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1867 { } /* end */
1868};
1869
1870/*
1871 * 6ch mode
1872 */
1873static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1874/* Mic-in jack as CLFE */
1875 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1876 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1877/* Line-in jack as Surround */
1878 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1879 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1880/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1881 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1882 { } /* end */
1883};
1884
1885/*
1886 * 8ch mode
1887 */
1888static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1889/* Mic-in jack as CLFE */
1890 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1891 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1892/* Line-in jack as Surround */
1893 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1894 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1895/* Line-Out as Side */
1896 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1897 { } /* end */
1898};
1899
1900static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1901 { 2, alc888_4ST_ch2_intel_init },
1902 { 4, alc888_4ST_ch4_intel_init },
1903 { 6, alc888_4ST_ch6_intel_init },
1904 { 8, alc888_4ST_ch8_intel_init },
1905};
1906
1907/*
1908 * ALC888 Fujitsu Siemens Amillo xa3530
1909 */
1910
1911static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1912/* Front Mic: set to PIN_IN (empty by default) */
1913 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1914/* Connect Internal HP to Front */
1915 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1917 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1918/* Connect Bass HP to Front */
1919 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1920 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1921 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1922/* Connect Line-Out side jack (SPDIF) to Side */
1923 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1924 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1925 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1926/* Connect Mic jack to CLFE */
1927 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1928 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1929 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1930/* Connect Line-in jack to Surround */
1931 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1932 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1933 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1934/* Connect HP out jack to Front */
1935 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1936 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1937 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1938/* Enable unsolicited event for HP jack and Line-out jack */
1939 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1940 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1941 {}
1942};
1943
a9fd4f3f 1944static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1945{
bb35febd 1946 alc_automute_speaker(codec, 0);
ef8ef5fb
VP
1947}
1948
a9fd4f3f
TI
1949static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1950 unsigned int res)
ef8ef5fb 1951{
a9fd4f3f
TI
1952 if (codec->vendor_id == 0x10ec0880)
1953 res >>= 28;
1954 else
1955 res >>= 26;
1956 if (res == ALC880_HP_EVENT)
1957 alc_automute_amp(codec);
ef8ef5fb
VP
1958}
1959
4f5d1706 1960static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1961{
1962 struct alc_spec *spec = codec->spec;
1963
1964 spec->autocfg.hp_pins[0] = 0x15;
1965 spec->autocfg.speaker_pins[0] = 0x14;
1966 spec->autocfg.speaker_pins[1] = 0x16;
1967 spec->autocfg.speaker_pins[2] = 0x17;
1968 spec->autocfg.speaker_pins[3] = 0x19;
1969 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1970}
1971
1972static void alc889_intel_init_hook(struct hda_codec *codec)
1973{
1974 alc889_coef_init(codec);
4f5d1706 1975 alc_automute_amp(codec);
6732bd0d
WF
1976}
1977
4f5d1706 1978static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1979{
1980 struct alc_spec *spec = codec->spec;
1981
1982 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1983 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1984 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1985 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1986}
ef8ef5fb 1987
5b2d1eca
VP
1988/*
1989 * ALC888 Acer Aspire 4930G model
1990 */
1991
1992static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1993/* Front Mic: set to PIN_IN (empty by default) */
1994 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1995/* Unselect Front Mic by default in input mixer 3 */
1996 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1997/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1998 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1999/* Connect Internal HP to front */
2000 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2001 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2002 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2003/* Connect HP out to front */
2004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2005 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2006 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2007 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2008 { }
2009};
2010
d2fd4b09
TV
2011/*
2012 * ALC888 Acer Aspire 6530G model
2013 */
2014
2015static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2016/* Route to built-in subwoofer as well as speakers */
2017 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2018 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2019 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2021/* Bias voltage on for external mic port */
2022 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2023/* Front Mic: set to PIN_IN (empty by default) */
2024 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2025/* Unselect Front Mic by default in input mixer 3 */
2026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2027/* Enable unsolicited event for HP jack */
2028 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2029/* Enable speaker output */
2030 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2031 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2032 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2033/* Enable headphone output */
2034 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2035 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2036 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2037 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2038 { }
2039};
2040
d9477207
DK
2041/*
2042 *ALC888 Acer Aspire 7730G model
2043 */
2044
2045static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2046/* Bias voltage on for external mic port */
2047 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2048/* Front Mic: set to PIN_IN (empty by default) */
2049 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2050/* Unselect Front Mic by default in input mixer 3 */
2051 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2052/* Enable unsolicited event for HP jack */
2053 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2054/* Enable speaker output */
2055 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2057 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2058/* Enable headphone output */
2059 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2060 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2061 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2062 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2063/*Enable internal subwoofer */
2064 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2065 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2066 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2067 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2068 { }
2069};
2070
3b315d70 2071/*
018df418 2072 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2073 */
2074
018df418 2075static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2076/* Front Mic: set to PIN_IN (empty by default) */
2077 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2078/* Unselect Front Mic by default in input mixer 3 */
2079 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2080/* Enable unsolicited event for HP jack */
2081 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2082/* Connect Internal Front to Front */
2083 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2084 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2085 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2086/* Connect Internal Rear to Rear */
2087 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2088 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2089 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2090/* Connect Internal CLFE to CLFE */
2091 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2092 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2093 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2094/* Connect HP out to Front */
018df418 2095 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2096 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2097 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2098/* Enable all DACs */
2099/* DAC DISABLE/MUTE 1? */
2100/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2101 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2102 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2103/* DAC DISABLE/MUTE 2? */
2104/* some bit here disables the other DACs. Init=0x4900 */
2105 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2106 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2107/* DMIC fix
2108 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2109 * which makes the stereo useless. However, either the mic or the ALC889
2110 * makes the signal become a difference/sum signal instead of standard
2111 * stereo, which is annoying. So instead we flip this bit which makes the
2112 * codec replicate the sum signal to both channels, turning it into a
2113 * normal mono mic.
2114 */
2115/* DMIC_CONTROL? Init value = 0x0001 */
2116 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2117 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2118 { }
2119};
2120
ef8ef5fb 2121static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2122 /* Front mic only available on one ADC */
2123 {
2124 .num_items = 4,
2125 .items = {
2126 { "Mic", 0x0 },
2127 { "Line", 0x2 },
2128 { "CD", 0x4 },
2129 { "Front Mic", 0xb },
2130 },
2131 },
2132 {
2133 .num_items = 3,
2134 .items = {
2135 { "Mic", 0x0 },
2136 { "Line", 0x2 },
2137 { "CD", 0x4 },
2138 },
2139 }
2140};
2141
d2fd4b09
TV
2142static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2143 /* Interal mic only available on one ADC */
2144 {
684a8842 2145 .num_items = 5,
d2fd4b09 2146 .items = {
8607f7c4 2147 { "Mic", 0x0 },
684a8842 2148 { "Line In", 0x2 },
d2fd4b09 2149 { "CD", 0x4 },
684a8842 2150 { "Input Mix", 0xa },
28c4edb7 2151 { "Internal Mic", 0xb },
d2fd4b09
TV
2152 },
2153 },
2154 {
684a8842 2155 .num_items = 4,
d2fd4b09 2156 .items = {
8607f7c4 2157 { "Mic", 0x0 },
684a8842 2158 { "Line In", 0x2 },
d2fd4b09 2159 { "CD", 0x4 },
684a8842 2160 { "Input Mix", 0xa },
d2fd4b09
TV
2161 },
2162 }
2163};
2164
018df418
HM
2165static struct hda_input_mux alc889_capture_sources[3] = {
2166 /* Digital mic only available on first "ADC" */
2167 {
2168 .num_items = 5,
2169 .items = {
2170 { "Mic", 0x0 },
2171 { "Line", 0x2 },
2172 { "CD", 0x4 },
2173 { "Front Mic", 0xb },
2174 { "Input Mix", 0xa },
2175 },
2176 },
2177 {
2178 .num_items = 4,
2179 .items = {
2180 { "Mic", 0x0 },
2181 { "Line", 0x2 },
2182 { "CD", 0x4 },
2183 { "Input Mix", 0xa },
2184 },
2185 },
2186 {
2187 .num_items = 4,
2188 .items = {
2189 { "Mic", 0x0 },
2190 { "Line", 0x2 },
2191 { "CD", 0x4 },
2192 { "Input Mix", 0xa },
2193 },
2194 }
2195};
2196
ef8ef5fb 2197static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2199 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2200 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2201 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2202 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2203 HDA_OUTPUT),
2204 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2205 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2206 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2207 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2208 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2209 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2210 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2211 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2212 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2213 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2216 { } /* end */
2217};
2218
460c92fa
ŁW
2219static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2222 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2223 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2225 HDA_OUTPUT),
786c51f9
ŁW
2226 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2227 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2229 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2230 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2238 { } /* end */
2239};
2240
556eea9a
HM
2241static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2242 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2243 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2244 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2245 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2246 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2247 HDA_OUTPUT),
2248 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2249 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2250 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2254 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2256 { } /* end */
2257};
2258
2259
4f5d1706 2260static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2261{
a9fd4f3f 2262 struct alc_spec *spec = codec->spec;
5b2d1eca 2263
a9fd4f3f
TI
2264 spec->autocfg.hp_pins[0] = 0x15;
2265 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2266 spec->autocfg.speaker_pins[1] = 0x16;
2267 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2268}
2269
4f5d1706 2270static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2271{
2272 struct alc_spec *spec = codec->spec;
2273
2274 spec->autocfg.hp_pins[0] = 0x15;
2275 spec->autocfg.speaker_pins[0] = 0x14;
2276 spec->autocfg.speaker_pins[1] = 0x16;
2277 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2278}
2279
d9477207
DK
2280static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2281{
2282 struct alc_spec *spec = codec->spec;
2283
2284 spec->autocfg.hp_pins[0] = 0x15;
2285 spec->autocfg.speaker_pins[0] = 0x14;
2286 spec->autocfg.speaker_pins[1] = 0x16;
2287 spec->autocfg.speaker_pins[2] = 0x17;
2288}
2289
4f5d1706 2290static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2291{
2292 struct alc_spec *spec = codec->spec;
2293
2294 spec->autocfg.hp_pins[0] = 0x15;
2295 spec->autocfg.speaker_pins[0] = 0x14;
2296 spec->autocfg.speaker_pins[1] = 0x16;
2297 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2298}
2299
1da177e4 2300/*
e9edcee0
TI
2301 * ALC880 3-stack model
2302 *
2303 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2304 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2305 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2306 */
2307
e9edcee0
TI
2308static hda_nid_t alc880_dac_nids[4] = {
2309 /* front, rear, clfe, rear_surr */
2310 0x02, 0x05, 0x04, 0x03
2311};
2312
2313static hda_nid_t alc880_adc_nids[3] = {
2314 /* ADC0-2 */
2315 0x07, 0x08, 0x09,
2316};
2317
2318/* The datasheet says the node 0x07 is connected from inputs,
2319 * but it shows zero connection in the real implementation on some devices.
df694daa 2320 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2321 */
e9edcee0
TI
2322static hda_nid_t alc880_adc_nids_alt[2] = {
2323 /* ADC1-2 */
2324 0x08, 0x09,
2325};
2326
2327#define ALC880_DIGOUT_NID 0x06
2328#define ALC880_DIGIN_NID 0x0a
2329
2330static struct hda_input_mux alc880_capture_source = {
2331 .num_items = 4,
2332 .items = {
2333 { "Mic", 0x0 },
2334 { "Front Mic", 0x3 },
2335 { "Line", 0x2 },
2336 { "CD", 0x4 },
2337 },
2338};
2339
2340/* channel source setting (2/6 channel selection for 3-stack) */
2341/* 2ch mode */
2342static struct hda_verb alc880_threestack_ch2_init[] = {
2343 /* set line-in to input, mute it */
2344 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2345 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2346 /* set mic-in to input vref 80%, mute it */
2347 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2348 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2349 { } /* end */
2350};
2351
2352/* 6ch mode */
2353static struct hda_verb alc880_threestack_ch6_init[] = {
2354 /* set line-in to output, unmute it */
2355 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2356 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2357 /* set mic-in to output, unmute it */
2358 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2359 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2360 { } /* end */
2361};
2362
d2a6d7dc 2363static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2364 { 2, alc880_threestack_ch2_init },
2365 { 6, alc880_threestack_ch6_init },
2366};
2367
c8b6bf9b 2368static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2369 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2370 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2371 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2372 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2373 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2374 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2375 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2376 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2377 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2378 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2379 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2380 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2383 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2384 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2385 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2386 {
2387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2388 .name = "Channel Mode",
df694daa
KY
2389 .info = alc_ch_mode_info,
2390 .get = alc_ch_mode_get,
2391 .put = alc_ch_mode_put,
e9edcee0
TI
2392 },
2393 { } /* end */
2394};
2395
2396/* capture mixer elements */
f9e336f6
TI
2397static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2398 struct snd_ctl_elem_info *uinfo)
2399{
2400 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2401 struct alc_spec *spec = codec->spec;
2402 int err;
1da177e4 2403
5a9e02e9 2404 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2405 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2406 HDA_INPUT);
2407 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2408 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2409 return err;
2410}
2411
2412static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2413 unsigned int size, unsigned int __user *tlv)
2414{
2415 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2416 struct alc_spec *spec = codec->spec;
2417 int err;
1da177e4 2418
5a9e02e9 2419 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2420 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2421 HDA_INPUT);
2422 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2423 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2424 return err;
2425}
2426
2427typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2428 struct snd_ctl_elem_value *ucontrol);
2429
2430static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2431 struct snd_ctl_elem_value *ucontrol,
2432 getput_call_t func)
2433{
2434 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2435 struct alc_spec *spec = codec->spec;
2436 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2437 int err;
2438
5a9e02e9 2439 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2440 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2441 3, 0, HDA_INPUT);
2442 err = func(kcontrol, ucontrol);
5a9e02e9 2443 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2444 return err;
2445}
2446
2447static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2448 struct snd_ctl_elem_value *ucontrol)
2449{
2450 return alc_cap_getput_caller(kcontrol, ucontrol,
2451 snd_hda_mixer_amp_volume_get);
2452}
2453
2454static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2455 struct snd_ctl_elem_value *ucontrol)
2456{
2457 return alc_cap_getput_caller(kcontrol, ucontrol,
2458 snd_hda_mixer_amp_volume_put);
2459}
2460
2461/* capture mixer elements */
2462#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2463
2464static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2465 struct snd_ctl_elem_value *ucontrol)
2466{
2467 return alc_cap_getput_caller(kcontrol, ucontrol,
2468 snd_hda_mixer_amp_switch_get);
2469}
2470
2471static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2472 struct snd_ctl_elem_value *ucontrol)
2473{
2474 return alc_cap_getput_caller(kcontrol, ucontrol,
2475 snd_hda_mixer_amp_switch_put);
2476}
2477
a23b688f 2478#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2479 { \
2480 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2481 .name = "Capture Switch", \
2482 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2483 .count = num, \
2484 .info = alc_cap_sw_info, \
2485 .get = alc_cap_sw_get, \
2486 .put = alc_cap_sw_put, \
2487 }, \
2488 { \
2489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2490 .name = "Capture Volume", \
2491 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2492 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2493 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2494 .count = num, \
2495 .info = alc_cap_vol_info, \
2496 .get = alc_cap_vol_get, \
2497 .put = alc_cap_vol_put, \
2498 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2499 }
2500
2501#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2502 { \
2503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2504 /* .name = "Capture Source", */ \
2505 .name = "Input Source", \
2506 .count = num, \
2507 .info = alc_mux_enum_info, \
2508 .get = alc_mux_enum_get, \
2509 .put = alc_mux_enum_put, \
a23b688f
TI
2510 }
2511
2512#define DEFINE_CAPMIX(num) \
2513static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2514 _DEFINE_CAPMIX(num), \
2515 _DEFINE_CAPSRC(num), \
2516 { } /* end */ \
2517}
2518
2519#define DEFINE_CAPMIX_NOSRC(num) \
2520static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2521 _DEFINE_CAPMIX(num), \
2522 { } /* end */ \
f9e336f6
TI
2523}
2524
2525/* up to three ADCs */
2526DEFINE_CAPMIX(1);
2527DEFINE_CAPMIX(2);
2528DEFINE_CAPMIX(3);
a23b688f
TI
2529DEFINE_CAPMIX_NOSRC(1);
2530DEFINE_CAPMIX_NOSRC(2);
2531DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2532
2533/*
2534 * ALC880 5-stack model
2535 *
9c7f852e
TI
2536 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2537 * Side = 0x02 (0xd)
e9edcee0
TI
2538 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2539 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2540 */
2541
2542/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2543static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2544 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2545 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2546 { } /* end */
2547};
2548
e9edcee0
TI
2549/* channel source setting (6/8 channel selection for 5-stack) */
2550/* 6ch mode */
2551static struct hda_verb alc880_fivestack_ch6_init[] = {
2552 /* set line-in to input, mute it */
2553 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2554 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2555 { } /* end */
2556};
2557
e9edcee0
TI
2558/* 8ch mode */
2559static struct hda_verb alc880_fivestack_ch8_init[] = {
2560 /* set line-in to output, unmute it */
2561 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2562 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2563 { } /* end */
2564};
2565
d2a6d7dc 2566static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2567 { 6, alc880_fivestack_ch6_init },
2568 { 8, alc880_fivestack_ch8_init },
2569};
2570
2571
2572/*
2573 * ALC880 6-stack model
2574 *
9c7f852e
TI
2575 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2576 * Side = 0x05 (0x0f)
e9edcee0
TI
2577 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2578 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2579 */
2580
2581static hda_nid_t alc880_6st_dac_nids[4] = {
2582 /* front, rear, clfe, rear_surr */
2583 0x02, 0x03, 0x04, 0x05
f12ab1e0 2584};
e9edcee0
TI
2585
2586static struct hda_input_mux alc880_6stack_capture_source = {
2587 .num_items = 4,
2588 .items = {
2589 { "Mic", 0x0 },
2590 { "Front Mic", 0x1 },
2591 { "Line", 0x2 },
2592 { "CD", 0x4 },
2593 },
2594};
2595
2596/* fixed 8-channels */
d2a6d7dc 2597static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2598 { 8, NULL },
2599};
2600
c8b6bf9b 2601static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2602 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2603 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2604 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2605 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2606 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2607 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2608 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2609 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2610 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2611 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2612 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2613 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2614 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2615 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2618 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2619 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2620 {
2621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2622 .name = "Channel Mode",
df694daa
KY
2623 .info = alc_ch_mode_info,
2624 .get = alc_ch_mode_get,
2625 .put = alc_ch_mode_put,
16ded525
TI
2626 },
2627 { } /* end */
2628};
2629
e9edcee0
TI
2630
2631/*
2632 * ALC880 W810 model
2633 *
2634 * W810 has rear IO for:
2635 * Front (DAC 02)
2636 * Surround (DAC 03)
2637 * Center/LFE (DAC 04)
2638 * Digital out (06)
2639 *
2640 * The system also has a pair of internal speakers, and a headphone jack.
2641 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2642 *
e9edcee0
TI
2643 * There is a variable resistor to control the speaker or headphone
2644 * volume. This is a hardware-only device without a software API.
2645 *
2646 * Plugging headphones in will disable the internal speakers. This is
2647 * implemented in hardware, not via the driver using jack sense. In
2648 * a similar fashion, plugging into the rear socket marked "front" will
2649 * disable both the speakers and headphones.
2650 *
2651 * For input, there's a microphone jack, and an "audio in" jack.
2652 * These may not do anything useful with this driver yet, because I
2653 * haven't setup any initialization verbs for these yet...
2654 */
2655
2656static hda_nid_t alc880_w810_dac_nids[3] = {
2657 /* front, rear/surround, clfe */
2658 0x02, 0x03, 0x04
16ded525
TI
2659};
2660
e9edcee0 2661/* fixed 6 channels */
d2a6d7dc 2662static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2663 { 6, NULL }
2664};
2665
2666/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2667static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2668 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2669 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2670 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2671 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2672 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2673 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2674 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2675 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2676 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2677 { } /* end */
2678};
2679
2680
2681/*
2682 * Z710V model
2683 *
2684 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2685 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2686 * Line = 0x1a
e9edcee0
TI
2687 */
2688
2689static hda_nid_t alc880_z71v_dac_nids[1] = {
2690 0x02
2691};
2692#define ALC880_Z71V_HP_DAC 0x03
2693
2694/* fixed 2 channels */
d2a6d7dc 2695static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2696 { 2, NULL }
2697};
2698
c8b6bf9b 2699static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2700 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2701 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2702 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2703 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2704 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2705 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2708 { } /* end */
2709};
2710
e9edcee0 2711
e9edcee0
TI
2712/*
2713 * ALC880 F1734 model
2714 *
2715 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2716 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2717 */
2718
2719static hda_nid_t alc880_f1734_dac_nids[1] = {
2720 0x03
2721};
2722#define ALC880_F1734_HP_DAC 0x02
2723
c8b6bf9b 2724static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2725 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2726 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2727 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2728 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2729 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2730 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2731 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2732 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2733 { } /* end */
2734};
2735
937b4160
TI
2736static struct hda_input_mux alc880_f1734_capture_source = {
2737 .num_items = 2,
2738 .items = {
2739 { "Mic", 0x1 },
2740 { "CD", 0x4 },
2741 },
2742};
2743
e9edcee0 2744
e9edcee0
TI
2745/*
2746 * ALC880 ASUS model
2747 *
2748 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2749 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2750 * Mic = 0x18, Line = 0x1a
2751 */
2752
2753#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2754#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2755
c8b6bf9b 2756static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2757 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2758 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2759 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2760 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2761 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2762 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2763 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2764 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2765 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2766 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2767 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2768 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2771 {
2772 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2773 .name = "Channel Mode",
df694daa
KY
2774 .info = alc_ch_mode_info,
2775 .get = alc_ch_mode_get,
2776 .put = alc_ch_mode_put,
16ded525
TI
2777 },
2778 { } /* end */
2779};
e9edcee0 2780
e9edcee0
TI
2781/*
2782 * ALC880 ASUS W1V model
2783 *
2784 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2785 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2786 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2787 */
2788
2789/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2790static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2791 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2792 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2793 { } /* end */
2794};
2795
df694daa
KY
2796/* TCL S700 */
2797static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2798 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2799 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2800 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2801 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2802 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2805 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2806 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2807 { } /* end */
2808};
2809
ccc656ce
KY
2810/* Uniwill */
2811static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2812 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2813 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2814 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2815 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2816 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2817 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2818 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2819 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2820 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2821 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2822 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2823 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2824 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2826 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2827 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2828 {
2829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2830 .name = "Channel Mode",
2831 .info = alc_ch_mode_info,
2832 .get = alc_ch_mode_get,
2833 .put = alc_ch_mode_put,
2834 },
2835 { } /* end */
2836};
2837
2cf9f0fc
TD
2838static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2839 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2840 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2841 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2842 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2843 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2844 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
2845 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2846 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
2847 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2848 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
2849 { } /* end */
2850};
2851
ccc656ce 2852static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2853 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2854 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2855 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2856 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2859 { } /* end */
2860};
2861
2134ea4f
TI
2862/*
2863 * virtual master controls
2864 */
2865
2866/*
2867 * slave controls for virtual master
2868 */
ea734963 2869static const char * const alc_slave_vols[] = {
2134ea4f
TI
2870 "Front Playback Volume",
2871 "Surround Playback Volume",
2872 "Center Playback Volume",
2873 "LFE Playback Volume",
2874 "Side Playback Volume",
2875 "Headphone Playback Volume",
2876 "Speaker Playback Volume",
2877 "Mono Playback Volume",
2134ea4f 2878 "Line-Out Playback Volume",
26f5df26 2879 "PCM Playback Volume",
2134ea4f
TI
2880 NULL,
2881};
2882
ea734963 2883static const char * const alc_slave_sws[] = {
2134ea4f
TI
2884 "Front Playback Switch",
2885 "Surround Playback Switch",
2886 "Center Playback Switch",
2887 "LFE Playback Switch",
2888 "Side Playback Switch",
2889 "Headphone Playback Switch",
2890 "Speaker Playback Switch",
2891 "Mono Playback Switch",
edb54a55 2892 "IEC958 Playback Switch",
23033b2b
TI
2893 "Line-Out Playback Switch",
2894 "PCM Playback Switch",
2134ea4f
TI
2895 NULL,
2896};
2897
1da177e4 2898/*
e9edcee0 2899 * build control elements
1da177e4 2900 */
603c4019 2901
5b0cb1d8
JK
2902#define NID_MAPPING (-1)
2903
2904#define SUBDEV_SPEAKER_ (0 << 6)
2905#define SUBDEV_HP_ (1 << 6)
2906#define SUBDEV_LINE_ (2 << 6)
2907#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2908#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2909#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2910
603c4019
TI
2911static void alc_free_kctls(struct hda_codec *codec);
2912
67d634c0 2913#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2914/* additional beep mixers; the actual parameters are overwritten at build */
2915static struct snd_kcontrol_new alc_beep_mixer[] = {
2916 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2917 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2918 { } /* end */
2919};
67d634c0 2920#endif
45bdd1c1 2921
1da177e4
LT
2922static int alc_build_controls(struct hda_codec *codec)
2923{
2924 struct alc_spec *spec = codec->spec;
2f44f847 2925 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2926 struct snd_kcontrol_new *knew;
2927 int i, j, err;
2928 unsigned int u;
2929 hda_nid_t nid;
1da177e4
LT
2930
2931 for (i = 0; i < spec->num_mixers; i++) {
2932 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2933 if (err < 0)
2934 return err;
2935 }
f9e336f6
TI
2936 if (spec->cap_mixer) {
2937 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2938 if (err < 0)
2939 return err;
2940 }
1da177e4 2941 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2942 err = snd_hda_create_spdif_out_ctls(codec,
2943 spec->multiout.dig_out_nid);
1da177e4
LT
2944 if (err < 0)
2945 return err;
e64f14f4
TI
2946 if (!spec->no_analog) {
2947 err = snd_hda_create_spdif_share_sw(codec,
2948 &spec->multiout);
2949 if (err < 0)
2950 return err;
2951 spec->multiout.share_spdif = 1;
2952 }
1da177e4
LT
2953 }
2954 if (spec->dig_in_nid) {
2955 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2956 if (err < 0)
2957 return err;
2958 }
2134ea4f 2959
67d634c0 2960#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2961 /* create beep controls if needed */
2962 if (spec->beep_amp) {
2963 struct snd_kcontrol_new *knew;
2964 for (knew = alc_beep_mixer; knew->name; knew++) {
2965 struct snd_kcontrol *kctl;
2966 kctl = snd_ctl_new1(knew, codec);
2967 if (!kctl)
2968 return -ENOMEM;
2969 kctl->private_value = spec->beep_amp;
5e26dfd0 2970 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2971 if (err < 0)
2972 return err;
2973 }
2974 }
67d634c0 2975#endif
45bdd1c1 2976
2134ea4f 2977 /* if we have no master control, let's create it */
e64f14f4
TI
2978 if (!spec->no_analog &&
2979 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2980 unsigned int vmaster_tlv[4];
2134ea4f 2981 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2982 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2983 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2984 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2985 if (err < 0)
2986 return err;
2987 }
e64f14f4
TI
2988 if (!spec->no_analog &&
2989 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2990 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2991 NULL, alc_slave_sws);
2992 if (err < 0)
2993 return err;
2994 }
2995
5b0cb1d8 2996 /* assign Capture Source enums to NID */
fbe618f2
TI
2997 if (spec->capsrc_nids || spec->adc_nids) {
2998 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2999 if (!kctl)
3000 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3001 for (i = 0; kctl && i < kctl->count; i++) {
3002 hda_nid_t *nids = spec->capsrc_nids;
3003 if (!nids)
3004 nids = spec->adc_nids;
3005 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3006 if (err < 0)
3007 return err;
3008 }
5b0cb1d8
JK
3009 }
3010 if (spec->cap_mixer) {
3011 const char *kname = kctl ? kctl->id.name : NULL;
3012 for (knew = spec->cap_mixer; knew->name; knew++) {
3013 if (kname && strcmp(knew->name, kname) == 0)
3014 continue;
3015 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3016 for (i = 0; kctl && i < kctl->count; i++) {
3017 err = snd_hda_add_nid(codec, kctl, i,
3018 spec->adc_nids[i]);
3019 if (err < 0)
3020 return err;
3021 }
3022 }
3023 }
3024
3025 /* other nid->control mapping */
3026 for (i = 0; i < spec->num_mixers; i++) {
3027 for (knew = spec->mixers[i]; knew->name; knew++) {
3028 if (knew->iface != NID_MAPPING)
3029 continue;
3030 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3031 if (kctl == NULL)
3032 continue;
3033 u = knew->subdevice;
3034 for (j = 0; j < 4; j++, u >>= 8) {
3035 nid = u & 0x3f;
3036 if (nid == 0)
3037 continue;
3038 switch (u & 0xc0) {
3039 case SUBDEV_SPEAKER_:
3040 nid = spec->autocfg.speaker_pins[nid];
3041 break;
3042 case SUBDEV_LINE_:
3043 nid = spec->autocfg.line_out_pins[nid];
3044 break;
3045 case SUBDEV_HP_:
3046 nid = spec->autocfg.hp_pins[nid];
3047 break;
3048 default:
3049 continue;
3050 }
3051 err = snd_hda_add_nid(codec, kctl, 0, nid);
3052 if (err < 0)
3053 return err;
3054 }
3055 u = knew->private_value;
3056 for (j = 0; j < 4; j++, u >>= 8) {
3057 nid = u & 0xff;
3058 if (nid == 0)
3059 continue;
3060 err = snd_hda_add_nid(codec, kctl, 0, nid);
3061 if (err < 0)
3062 return err;
3063 }
3064 }
3065 }
bae84e70
TI
3066
3067 alc_free_kctls(codec); /* no longer needed */
3068
1da177e4
LT
3069 return 0;
3070}
3071
e9edcee0 3072
1da177e4
LT
3073/*
3074 * initialize the codec volumes, etc
3075 */
3076
e9edcee0
TI
3077/*
3078 * generic initialization of ADC, input mixers and output mixers
3079 */
3080static struct hda_verb alc880_volume_init_verbs[] = {
3081 /*
3082 * Unmute ADC0-2 and set the default input to mic-in
3083 */
71fe7b82 3084 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3086 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3087 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3088 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3090
e9edcee0
TI
3091 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3092 * mixer widget
9c7f852e
TI
3093 * Note: PASD motherboards uses the Line In 2 as the input for front
3094 * panel mic (mic 2)
1da177e4 3095 */
e9edcee0 3096 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3104
e9edcee0
TI
3105 /*
3106 * Set up output mixers (0x0c - 0x0f)
1da177e4 3107 */
e9edcee0
TI
3108 /* set vol=0 to output mixers */
3109 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3110 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3112 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3113 /* set up input amps for analog loopback */
3114 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3117 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3118 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3119 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3120 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3121 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3122 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3123
3124 { }
3125};
3126
e9edcee0
TI
3127/*
3128 * 3-stack pin configuration:
3129 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3130 */
3131static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3132 /*
3133 * preset connection lists of input pins
3134 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3135 */
3136 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3137 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3138 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3139
3140 /*
3141 * Set pin mode and muting
3142 */
3143 /* set front pin widgets 0x14 for output */
05acb863 3144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3145 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3146 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3147 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3148 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3149 /* Mic2 (as headphone out) for HP output */
3150 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3151 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3152 /* Line In pin widget for input */
05acb863 3153 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3154 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3155 /* Line2 (as front mic) pin widget for input and vref at 80% */
3156 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3157 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3158 /* CD pin widget for input */
05acb863 3159 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3160
e9edcee0
TI
3161 { }
3162};
1da177e4 3163
e9edcee0
TI
3164/*
3165 * 5-stack pin configuration:
3166 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3167 * line-in/side = 0x1a, f-mic = 0x1b
3168 */
3169static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3170 /*
3171 * preset connection lists of input pins
3172 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3173 */
e9edcee0
TI
3174 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3175 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3176
e9edcee0
TI
3177 /*
3178 * Set pin mode and muting
1da177e4 3179 */
e9edcee0
TI
3180 /* set pin widgets 0x14-0x17 for output */
3181 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3184 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3185 /* unmute pins for output (no gain on this amp) */
3186 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3188 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3189 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3190
3191 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3192 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3193 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3194 /* Mic2 (as headphone out) for HP output */
3195 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3196 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3197 /* Line In pin widget for input */
3198 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3199 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3200 /* Line2 (as front mic) pin widget for input and vref at 80% */
3201 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3202 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3203 /* CD pin widget for input */
3204 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3205
3206 { }
3207};
3208
e9edcee0
TI
3209/*
3210 * W810 pin configuration:
3211 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3212 */
3213static struct hda_verb alc880_pin_w810_init_verbs[] = {
3214 /* hphone/speaker input selector: front DAC */
3215 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3216
05acb863 3217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3220 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3221 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3222 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3223
e9edcee0 3224 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3225 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3226
1da177e4
LT
3227 { }
3228};
3229
e9edcee0
TI
3230/*
3231 * Z71V pin configuration:
3232 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3233 */
3234static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3235 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3236 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3237 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3238 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3239
16ded525 3240 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3241 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3242 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3243 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3244
3245 { }
3246};
3247
e9edcee0
TI
3248/*
3249 * 6-stack pin configuration:
9c7f852e
TI
3250 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3251 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3252 */
3253static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3254 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3255
16ded525 3256 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3257 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3258 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3259 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3260 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3261 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3262 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3263 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3264
16ded525 3265 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3266 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3267 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3269 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3270 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3272 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3273 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3274
e9edcee0
TI
3275 { }
3276};
3277
ccc656ce
KY
3278/*
3279 * Uniwill pin configuration:
3280 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3281 * line = 0x1a
3282 */
3283static struct hda_verb alc880_uniwill_init_verbs[] = {
3284 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3285
3286 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3287 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3290 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3291 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3292 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3293 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3296 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3297 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3298 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3299 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3300
3301 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3302 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3303 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3304 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3307 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3308 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3309 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3310
3311 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3312 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3313
3314 { }
3315};
3316
3317/*
3318* Uniwill P53
ea1fb29a 3319* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3320 */
3321static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3322 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3323
3324 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3325 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3327 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3328 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3329 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3332 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3333 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3335 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3336
3337 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3339 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3340 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3341 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3343
3344 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3345 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3346
3347 { }
3348};
3349
2cf9f0fc
TD
3350static struct hda_verb alc880_beep_init_verbs[] = {
3351 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3352 { }
3353};
3354
458a4fab 3355/* auto-toggle front mic */
eeb43387 3356static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3357{
3358 unsigned int present;
3359 unsigned char bits;
ccc656ce 3360
864f92be 3361 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3362 bits = present ? HDA_AMP_MUTE : 0;
3363 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3364}
3365
4f5d1706 3366static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3367{
a9fd4f3f
TI
3368 struct alc_spec *spec = codec->spec;
3369
3370 spec->autocfg.hp_pins[0] = 0x14;
3371 spec->autocfg.speaker_pins[0] = 0x15;
3372 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3373}
3374
3375static void alc880_uniwill_init_hook(struct hda_codec *codec)
3376{
a9fd4f3f 3377 alc_automute_amp(codec);
eeb43387 3378 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3379}
3380
3381static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3382 unsigned int res)
3383{
3384 /* Looks like the unsol event is incompatible with the standard
3385 * definition. 4bit tag is placed at 28 bit!
3386 */
458a4fab 3387 switch (res >> 28) {
458a4fab 3388 case ALC880_MIC_EVENT:
eeb43387 3389 alc88x_simple_mic_automute(codec);
458a4fab 3390 break;
a9fd4f3f
TI
3391 default:
3392 alc_automute_amp_unsol_event(codec, res);
3393 break;
458a4fab 3394 }
ccc656ce
KY
3395}
3396
4f5d1706 3397static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3398{
a9fd4f3f 3399 struct alc_spec *spec = codec->spec;
ccc656ce 3400
a9fd4f3f
TI
3401 spec->autocfg.hp_pins[0] = 0x14;
3402 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3403}
3404
3405static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3406{
3407 unsigned int present;
ea1fb29a 3408
ccc656ce 3409 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3410 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3411 present &= HDA_AMP_VOLMASK;
3412 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3413 HDA_AMP_VOLMASK, present);
3414 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3415 HDA_AMP_VOLMASK, present);
ccc656ce 3416}
47fd830a 3417
ccc656ce
KY
3418static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3419 unsigned int res)
3420{
3421 /* Looks like the unsol event is incompatible with the standard
3422 * definition. 4bit tag is placed at 28 bit!
3423 */
f12ab1e0 3424 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3425 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3426 else
3427 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3428}
3429
e9edcee0
TI
3430/*
3431 * F1734 pin configuration:
3432 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3433 */
3434static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3435 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3436 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3437 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3438 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3439 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3440
e9edcee0 3441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3442 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3443 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3444 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3445
e9edcee0
TI
3446 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3447 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3448 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3449 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3450 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3451 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3452 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3453 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3454 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3455
937b4160
TI
3456 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3457 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3458
dfc0ff62
TI
3459 { }
3460};
3461
e9edcee0
TI
3462/*
3463 * ASUS pin configuration:
3464 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3465 */
3466static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3467 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3468 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3469 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3470 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3471
3472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3474 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3475 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3476 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3477 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3478 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3479 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3480
3481 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3482 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3483 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3488 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3489 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3490
e9edcee0
TI
3491 { }
3492};
16ded525 3493
e9edcee0 3494/* Enable GPIO mask and set output */
bc9f98a9
KY
3495#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3496#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3497#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3498
3499/* Clevo m520g init */
3500static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3501 /* headphone output */
3502 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3503 /* line-out */
3504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3506 /* Line-in */
3507 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3508 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3509 /* CD */
3510 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3511 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3512 /* Mic1 (rear panel) */
3513 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3514 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3515 /* Mic2 (front panel) */
3516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3517 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3518 /* headphone */
3519 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3520 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3521 /* change to EAPD mode */
3522 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3523 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3524
3525 { }
16ded525
TI
3526};
3527
df694daa 3528static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3529 /* change to EAPD mode */
3530 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3531 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3532
df694daa
KY
3533 /* Headphone output */
3534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3535 /* Front output*/
3536 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3538
3539 /* Line In pin widget for input */
3540 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3541 /* CD pin widget for input */
3542 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3543 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3544 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3545
3546 /* change to EAPD mode */
3547 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3548 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3549
3550 { }
3551};
16ded525 3552
e9edcee0 3553/*
ae6b813a
TI
3554 * LG m1 express dual
3555 *
3556 * Pin assignment:
3557 * Rear Line-In/Out (blue): 0x14
3558 * Build-in Mic-In: 0x15
3559 * Speaker-out: 0x17
3560 * HP-Out (green): 0x1b
3561 * Mic-In/Out (red): 0x19
3562 * SPDIF-Out: 0x1e
3563 */
3564
3565/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3566static hda_nid_t alc880_lg_dac_nids[3] = {
3567 0x05, 0x02, 0x03
3568};
3569
3570/* seems analog CD is not working */
3571static struct hda_input_mux alc880_lg_capture_source = {
3572 .num_items = 3,
3573 .items = {
3574 { "Mic", 0x1 },
3575 { "Line", 0x5 },
3576 { "Internal Mic", 0x6 },
3577 },
3578};
3579
3580/* 2,4,6 channel modes */
3581static struct hda_verb alc880_lg_ch2_init[] = {
3582 /* set line-in and mic-in to input */
3583 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3584 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3585 { }
3586};
3587
3588static struct hda_verb alc880_lg_ch4_init[] = {
3589 /* set line-in to out and mic-in to input */
3590 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3591 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3592 { }
3593};
3594
3595static struct hda_verb alc880_lg_ch6_init[] = {
3596 /* set line-in and mic-in to output */
3597 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3598 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3599 { }
3600};
3601
3602static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3603 { 2, alc880_lg_ch2_init },
3604 { 4, alc880_lg_ch4_init },
3605 { 6, alc880_lg_ch6_init },
3606};
3607
3608static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3609 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3610 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3611 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3612 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3613 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3614 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3615 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3616 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3618 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3620 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3621 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3622 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3623 {
3624 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3625 .name = "Channel Mode",
3626 .info = alc_ch_mode_info,
3627 .get = alc_ch_mode_get,
3628 .put = alc_ch_mode_put,
3629 },
3630 { } /* end */
3631};
3632
3633static struct hda_verb alc880_lg_init_verbs[] = {
3634 /* set capture source to mic-in */
3635 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3636 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3637 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3638 /* mute all amp mixer inputs */
3639 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3640 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3642 /* line-in to input */
3643 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3644 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3645 /* built-in mic */
3646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3648 /* speaker-out */
3649 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3650 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3651 /* mic-in to input */
3652 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3655 /* HP-out */
3656 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3657 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3658 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3659 /* jack sense */
a9fd4f3f 3660 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3661 { }
3662};
3663
3664/* toggle speaker-output according to the hp-jack state */
4f5d1706 3665static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3666{
a9fd4f3f 3667 struct alc_spec *spec = codec->spec;
ae6b813a 3668
a9fd4f3f
TI
3669 spec->autocfg.hp_pins[0] = 0x1b;
3670 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3671}
3672
d681518a
TI
3673/*
3674 * LG LW20
3675 *
3676 * Pin assignment:
3677 * Speaker-out: 0x14
3678 * Mic-In: 0x18
e4f41da9
CM
3679 * Built-in Mic-In: 0x19
3680 * Line-In: 0x1b
3681 * HP-Out: 0x1a
d681518a
TI
3682 * SPDIF-Out: 0x1e
3683 */
3684
d681518a 3685static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3686 .num_items = 3,
d681518a
TI
3687 .items = {
3688 { "Mic", 0x0 },
3689 { "Internal Mic", 0x1 },
e4f41da9 3690 { "Line In", 0x2 },
d681518a
TI
3691 },
3692};
3693
0a8c5da3
CM
3694#define alc880_lg_lw_modes alc880_threestack_modes
3695
d681518a 3696static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3697 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3698 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3699 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3700 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3701 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3702 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3703 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3704 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3705 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3706 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3709 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3710 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3711 {
3712 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3713 .name = "Channel Mode",
3714 .info = alc_ch_mode_info,
3715 .get = alc_ch_mode_get,
3716 .put = alc_ch_mode_put,
3717 },
d681518a
TI
3718 { } /* end */
3719};
3720
3721static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3722 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3723 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3724 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3725
d681518a
TI
3726 /* set capture source to mic-in */
3727 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3728 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3729 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3730 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3731 /* speaker-out */
3732 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3733 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3734 /* HP-out */
d681518a
TI
3735 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3736 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3737 /* mic-in to input */
3738 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3739 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3740 /* built-in mic */
3741 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3742 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3743 /* jack sense */
a9fd4f3f 3744 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3745 { }
3746};
3747
3748/* toggle speaker-output according to the hp-jack state */
4f5d1706 3749static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3750{
a9fd4f3f 3751 struct alc_spec *spec = codec->spec;
d681518a 3752
a9fd4f3f
TI
3753 spec->autocfg.hp_pins[0] = 0x1b;
3754 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3755}
3756
df99cd33
TI
3757static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3758 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3759 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3761 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3762 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3763 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3764 { } /* end */
3765};
3766
3767static struct hda_input_mux alc880_medion_rim_capture_source = {
3768 .num_items = 2,
3769 .items = {
3770 { "Mic", 0x0 },
3771 { "Internal Mic", 0x1 },
3772 },
3773};
3774
3775static struct hda_verb alc880_medion_rim_init_verbs[] = {
3776 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3777
3778 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3779 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3780
3781 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3782 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3783 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3784 /* Mic2 (as headphone out) for HP output */
3785 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3787 /* Internal Speaker */
3788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3789 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3790
3791 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3792 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3793
3794 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3795 { }
3796};
3797
3798/* toggle speaker-output according to the hp-jack state */
3799static void alc880_medion_rim_automute(struct hda_codec *codec)
3800{
a9fd4f3f
TI
3801 struct alc_spec *spec = codec->spec;
3802 alc_automute_amp(codec);
3803 /* toggle EAPD */
3804 if (spec->jack_present)
df99cd33
TI
3805 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3806 else
3807 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3808}
3809
3810static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3811 unsigned int res)
3812{
3813 /* Looks like the unsol event is incompatible with the standard
3814 * definition. 4bit tag is placed at 28 bit!
3815 */
3816 if ((res >> 28) == ALC880_HP_EVENT)
3817 alc880_medion_rim_automute(codec);
3818}
3819
4f5d1706 3820static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3821{
3822 struct alc_spec *spec = codec->spec;
3823
3824 spec->autocfg.hp_pins[0] = 0x14;
3825 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3826}
3827
cb53c626
TI
3828#ifdef CONFIG_SND_HDA_POWER_SAVE
3829static struct hda_amp_list alc880_loopbacks[] = {
3830 { 0x0b, HDA_INPUT, 0 },
3831 { 0x0b, HDA_INPUT, 1 },
3832 { 0x0b, HDA_INPUT, 2 },
3833 { 0x0b, HDA_INPUT, 3 },
3834 { 0x0b, HDA_INPUT, 4 },
3835 { } /* end */
3836};
3837
3838static struct hda_amp_list alc880_lg_loopbacks[] = {
3839 { 0x0b, HDA_INPUT, 1 },
3840 { 0x0b, HDA_INPUT, 6 },
3841 { 0x0b, HDA_INPUT, 7 },
3842 { } /* end */
3843};
3844#endif
3845
ae6b813a
TI
3846/*
3847 * Common callbacks
e9edcee0
TI
3848 */
3849
1da177e4
LT
3850static int alc_init(struct hda_codec *codec)
3851{
3852 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3853 unsigned int i;
3854
2c3bf9ab 3855 alc_fix_pll(codec);
4a79ba34 3856 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3857
e9edcee0
TI
3858 for (i = 0; i < spec->num_init_verbs; i++)
3859 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3860
3861 if (spec->init_hook)
3862 spec->init_hook(codec);
3863
58701120
TI
3864 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
3865
9e5341b9 3866 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
3867 return 0;
3868}
3869
ae6b813a
TI
3870static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3871{
3872 struct alc_spec *spec = codec->spec;
3873
3874 if (spec->unsol_event)
3875 spec->unsol_event(codec, res);
3876}
3877
cb53c626
TI
3878#ifdef CONFIG_SND_HDA_POWER_SAVE
3879static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3880{
3881 struct alc_spec *spec = codec->spec;
3882 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3883}
3884#endif
3885
1da177e4
LT
3886/*
3887 * Analog playback callbacks
3888 */
3889static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3890 struct hda_codec *codec,
c8b6bf9b 3891 struct snd_pcm_substream *substream)
1da177e4
LT
3892{
3893 struct alc_spec *spec = codec->spec;
9a08160b
TI
3894 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3895 hinfo);
1da177e4
LT
3896}
3897
3898static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3899 struct hda_codec *codec,
3900 unsigned int stream_tag,
3901 unsigned int format,
c8b6bf9b 3902 struct snd_pcm_substream *substream)
1da177e4
LT
3903{
3904 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3905 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3906 stream_tag, format, substream);
1da177e4
LT
3907}
3908
3909static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3910 struct hda_codec *codec,
c8b6bf9b 3911 struct snd_pcm_substream *substream)
1da177e4
LT
3912{
3913 struct alc_spec *spec = codec->spec;
3914 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3915}
3916
3917/*
3918 * Digital out
3919 */
3920static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3921 struct hda_codec *codec,
c8b6bf9b 3922 struct snd_pcm_substream *substream)
1da177e4
LT
3923{
3924 struct alc_spec *spec = codec->spec;
3925 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3926}
3927
6b97eb45
TI
3928static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3929 struct hda_codec *codec,
3930 unsigned int stream_tag,
3931 unsigned int format,
3932 struct snd_pcm_substream *substream)
3933{
3934 struct alc_spec *spec = codec->spec;
3935 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3936 stream_tag, format, substream);
3937}
3938
9b5f12e5
TI
3939static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3940 struct hda_codec *codec,
3941 struct snd_pcm_substream *substream)
3942{
3943 struct alc_spec *spec = codec->spec;
3944 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3945}
3946
1da177e4
LT
3947static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3948 struct hda_codec *codec,
c8b6bf9b 3949 struct snd_pcm_substream *substream)
1da177e4
LT
3950{
3951 struct alc_spec *spec = codec->spec;
3952 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3953}
3954
3955/*
3956 * Analog capture
3957 */
6330079f 3958static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3959 struct hda_codec *codec,
3960 unsigned int stream_tag,
3961 unsigned int format,
c8b6bf9b 3962 struct snd_pcm_substream *substream)
1da177e4
LT
3963{
3964 struct alc_spec *spec = codec->spec;
3965
6330079f 3966 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3967 stream_tag, 0, format);
3968 return 0;
3969}
3970
6330079f 3971static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3972 struct hda_codec *codec,
c8b6bf9b 3973 struct snd_pcm_substream *substream)
1da177e4
LT
3974{
3975 struct alc_spec *spec = codec->spec;
3976
888afa15
TI
3977 snd_hda_codec_cleanup_stream(codec,
3978 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3979 return 0;
3980}
3981
840b64c0
TI
3982/* analog capture with dynamic dual-adc changes */
3983static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3984 struct hda_codec *codec,
3985 unsigned int stream_tag,
3986 unsigned int format,
3987 struct snd_pcm_substream *substream)
3988{
3989 struct alc_spec *spec = codec->spec;
3990 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3991 spec->cur_adc_stream_tag = stream_tag;
3992 spec->cur_adc_format = format;
3993 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3994 return 0;
3995}
3996
3997static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3998 struct hda_codec *codec,
3999 struct snd_pcm_substream *substream)
4000{
4001 struct alc_spec *spec = codec->spec;
4002 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4003 spec->cur_adc = 0;
4004 return 0;
4005}
4006
4007static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4008 .substreams = 1,
4009 .channels_min = 2,
4010 .channels_max = 2,
4011 .nid = 0, /* fill later */
4012 .ops = {
4013 .prepare = dualmic_capture_pcm_prepare,
4014 .cleanup = dualmic_capture_pcm_cleanup
4015 },
4016};
1da177e4
LT
4017
4018/*
4019 */
4020static struct hda_pcm_stream alc880_pcm_analog_playback = {
4021 .substreams = 1,
4022 .channels_min = 2,
4023 .channels_max = 8,
e9edcee0 4024 /* NID is set in alc_build_pcms */
1da177e4
LT
4025 .ops = {
4026 .open = alc880_playback_pcm_open,
4027 .prepare = alc880_playback_pcm_prepare,
4028 .cleanup = alc880_playback_pcm_cleanup
4029 },
4030};
4031
4032static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4033 .substreams = 1,
4034 .channels_min = 2,
4035 .channels_max = 2,
4036 /* NID is set in alc_build_pcms */
4037};
4038
4039static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4040 .substreams = 1,
4041 .channels_min = 2,
4042 .channels_max = 2,
4043 /* NID is set in alc_build_pcms */
4044};
4045
4046static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4047 .substreams = 2, /* can be overridden */
1da177e4
LT
4048 .channels_min = 2,
4049 .channels_max = 2,
e9edcee0 4050 /* NID is set in alc_build_pcms */
1da177e4 4051 .ops = {
6330079f
TI
4052 .prepare = alc880_alt_capture_pcm_prepare,
4053 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4054 },
4055};
4056
4057static struct hda_pcm_stream alc880_pcm_digital_playback = {
4058 .substreams = 1,
4059 .channels_min = 2,
4060 .channels_max = 2,
4061 /* NID is set in alc_build_pcms */
4062 .ops = {
4063 .open = alc880_dig_playback_pcm_open,
6b97eb45 4064 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4065 .prepare = alc880_dig_playback_pcm_prepare,
4066 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4067 },
4068};
4069
4070static struct hda_pcm_stream alc880_pcm_digital_capture = {
4071 .substreams = 1,
4072 .channels_min = 2,
4073 .channels_max = 2,
4074 /* NID is set in alc_build_pcms */
4075};
4076
4c5186ed 4077/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 4078static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4079 .substreams = 0,
4080 .channels_min = 0,
4081 .channels_max = 0,
4082};
4083
1da177e4
LT
4084static int alc_build_pcms(struct hda_codec *codec)
4085{
4086 struct alc_spec *spec = codec->spec;
4087 struct hda_pcm *info = spec->pcm_rec;
4088 int i;
4089
4090 codec->num_pcms = 1;
4091 codec->pcm_info = info;
4092
e64f14f4
TI
4093 if (spec->no_analog)
4094 goto skip_analog;
4095
812a2cca
TI
4096 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4097 "%s Analog", codec->chip_name);
1da177e4 4098 info->name = spec->stream_name_analog;
274693f3 4099
4a471b7d 4100 if (spec->stream_analog_playback) {
da3cec35
TI
4101 if (snd_BUG_ON(!spec->multiout.dac_nids))
4102 return -EINVAL;
4a471b7d
TI
4103 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4104 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4105 }
4106 if (spec->stream_analog_capture) {
da3cec35
TI
4107 if (snd_BUG_ON(!spec->adc_nids))
4108 return -EINVAL;
4a471b7d
TI
4109 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4110 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4111 }
4112
4113 if (spec->channel_mode) {
4114 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4115 for (i = 0; i < spec->num_channel_mode; i++) {
4116 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4117 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4118 }
1da177e4
LT
4119 }
4120 }
4121
e64f14f4 4122 skip_analog:
e08a007d 4123 /* SPDIF for stream index #1 */
1da177e4 4124 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4125 snprintf(spec->stream_name_digital,
4126 sizeof(spec->stream_name_digital),
4127 "%s Digital", codec->chip_name);
e08a007d 4128 codec->num_pcms = 2;
b25c9da1 4129 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4130 info = spec->pcm_rec + 1;
1da177e4 4131 info->name = spec->stream_name_digital;
8c441982
TI
4132 if (spec->dig_out_type)
4133 info->pcm_type = spec->dig_out_type;
4134 else
4135 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4136 if (spec->multiout.dig_out_nid &&
4137 spec->stream_digital_playback) {
1da177e4
LT
4138 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4139 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4140 }
4a471b7d
TI
4141 if (spec->dig_in_nid &&
4142 spec->stream_digital_capture) {
1da177e4
LT
4143 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4144 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4145 }
963f803f
TI
4146 /* FIXME: do we need this for all Realtek codec models? */
4147 codec->spdif_status_reset = 1;
1da177e4
LT
4148 }
4149
e64f14f4
TI
4150 if (spec->no_analog)
4151 return 0;
4152
e08a007d
TI
4153 /* If the use of more than one ADC is requested for the current
4154 * model, configure a second analog capture-only PCM.
4155 */
4156 /* Additional Analaog capture for index #2 */
6330079f
TI
4157 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4158 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4159 codec->num_pcms = 3;
c06134d7 4160 info = spec->pcm_rec + 2;
e08a007d 4161 info->name = spec->stream_name_analog;
6330079f
TI
4162 if (spec->alt_dac_nid) {
4163 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4164 *spec->stream_analog_alt_playback;
4165 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4166 spec->alt_dac_nid;
4167 } else {
4168 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4169 alc_pcm_null_stream;
4170 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4171 }
4172 if (spec->num_adc_nids > 1) {
4173 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4174 *spec->stream_analog_alt_capture;
4175 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4176 spec->adc_nids[1];
4177 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4178 spec->num_adc_nids - 1;
4179 } else {
4180 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4181 alc_pcm_null_stream;
4182 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4183 }
4184 }
4185
1da177e4
LT
4186 return 0;
4187}
4188
a4e09aa3
TI
4189static inline void alc_shutup(struct hda_codec *codec)
4190{
4191 snd_hda_shutup_pins(codec);
4192}
4193
603c4019
TI
4194static void alc_free_kctls(struct hda_codec *codec)
4195{
4196 struct alc_spec *spec = codec->spec;
4197
4198 if (spec->kctls.list) {
4199 struct snd_kcontrol_new *kctl = spec->kctls.list;
4200 int i;
4201 for (i = 0; i < spec->kctls.used; i++)
4202 kfree(kctl[i].name);
4203 }
4204 snd_array_free(&spec->kctls);
4205}
4206
1da177e4
LT
4207static void alc_free(struct hda_codec *codec)
4208{
e9edcee0 4209 struct alc_spec *spec = codec->spec;
e9edcee0 4210
f12ab1e0 4211 if (!spec)
e9edcee0
TI
4212 return;
4213
a4e09aa3 4214 alc_shutup(codec);
cd372fb3 4215 snd_hda_input_jack_free(codec);
603c4019 4216 alc_free_kctls(codec);
e9edcee0 4217 kfree(spec);
680cd536 4218 snd_hda_detach_beep_device(codec);
1da177e4
LT
4219}
4220
f5de24b0 4221#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4222static void alc_power_eapd(struct hda_codec *codec)
4223{
4224 /* We currently only handle front, HP */
4225 switch (codec->vendor_id) {
4226 case 0x10ec0260:
9e4c8496
TI
4227 set_eapd(codec, 0x0f, 0);
4228 set_eapd(codec, 0x10, 0);
c97259df
DC
4229 break;
4230 case 0x10ec0262:
4231 case 0x10ec0267:
4232 case 0x10ec0268:
4233 case 0x10ec0269:
9e4c8496 4234 case 0x10ec0270:
c97259df
DC
4235 case 0x10ec0272:
4236 case 0x10ec0660:
4237 case 0x10ec0662:
4238 case 0x10ec0663:
4239 case 0x10ec0862:
4240 case 0x10ec0889:
9e4c8496
TI
4241 set_eapd(codec, 0x14, 0);
4242 set_eapd(codec, 0x15, 0);
c97259df
DC
4243 break;
4244 }
4245}
4246
f5de24b0
HM
4247static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4248{
4249 struct alc_spec *spec = codec->spec;
a4e09aa3 4250 alc_shutup(codec);
f5de24b0 4251 if (spec && spec->power_hook)
c97259df 4252 spec->power_hook(codec);
f5de24b0
HM
4253 return 0;
4254}
4255#endif
4256
e044c39a 4257#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4258static int alc_resume(struct hda_codec *codec)
4259{
e044c39a
TI
4260 codec->patch_ops.init(codec);
4261 snd_hda_codec_resume_amp(codec);
4262 snd_hda_codec_resume_cache(codec);
9e5341b9 4263 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4264 return 0;
4265}
e044c39a
TI
4266#endif
4267
1da177e4
LT
4268/*
4269 */
4270static struct hda_codec_ops alc_patch_ops = {
4271 .build_controls = alc_build_controls,
4272 .build_pcms = alc_build_pcms,
4273 .init = alc_init,
4274 .free = alc_free,
ae6b813a 4275 .unsol_event = alc_unsol_event,
e044c39a
TI
4276#ifdef SND_HDA_NEEDS_RESUME
4277 .resume = alc_resume,
4278#endif
cb53c626 4279#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4280 .suspend = alc_suspend,
cb53c626
TI
4281 .check_power_status = alc_check_power_status,
4282#endif
c97259df 4283 .reboot_notify = alc_shutup,
1da177e4
LT
4284};
4285
c027ddcd
KY
4286/* replace the codec chip_name with the given string */
4287static int alc_codec_rename(struct hda_codec *codec, const char *name)
4288{
4289 kfree(codec->chip_name);
4290 codec->chip_name = kstrdup(name, GFP_KERNEL);
4291 if (!codec->chip_name) {
4292 alc_free(codec);
4293 return -ENOMEM;
4294 }
4295 return 0;
4296}
4297
2fa522be
TI
4298/*
4299 * Test configuration for debugging
4300 *
4301 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4302 * enum controls.
4303 */
4304#ifdef CONFIG_SND_DEBUG
4305static hda_nid_t alc880_test_dac_nids[4] = {
4306 0x02, 0x03, 0x04, 0x05
4307};
4308
4309static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4310 .num_items = 7,
2fa522be
TI
4311 .items = {
4312 { "In-1", 0x0 },
4313 { "In-2", 0x1 },
4314 { "In-3", 0x2 },
4315 { "In-4", 0x3 },
4316 { "CD", 0x4 },
ae6b813a
TI
4317 { "Front", 0x5 },
4318 { "Surround", 0x6 },
2fa522be
TI
4319 },
4320};
4321
d2a6d7dc 4322static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4323 { 2, NULL },
fd2c326d 4324 { 4, NULL },
2fa522be 4325 { 6, NULL },
fd2c326d 4326 { 8, NULL },
2fa522be
TI
4327};
4328
9c7f852e
TI
4329static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4330 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4331{
4332 static char *texts[] = {
4333 "N/A", "Line Out", "HP Out",
4334 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4335 };
4336 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4337 uinfo->count = 1;
4338 uinfo->value.enumerated.items = 8;
4339 if (uinfo->value.enumerated.item >= 8)
4340 uinfo->value.enumerated.item = 7;
4341 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4342 return 0;
4343}
4344
9c7f852e
TI
4345static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4346 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4347{
4348 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4349 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4350 unsigned int pin_ctl, item = 0;
4351
4352 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4353 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4354 if (pin_ctl & AC_PINCTL_OUT_EN) {
4355 if (pin_ctl & AC_PINCTL_HP_EN)
4356 item = 2;
4357 else
4358 item = 1;
4359 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4360 switch (pin_ctl & AC_PINCTL_VREFEN) {
4361 case AC_PINCTL_VREF_HIZ: item = 3; break;
4362 case AC_PINCTL_VREF_50: item = 4; break;
4363 case AC_PINCTL_VREF_GRD: item = 5; break;
4364 case AC_PINCTL_VREF_80: item = 6; break;
4365 case AC_PINCTL_VREF_100: item = 7; break;
4366 }
4367 }
4368 ucontrol->value.enumerated.item[0] = item;
4369 return 0;
4370}
4371
9c7f852e
TI
4372static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4373 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4374{
4375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4376 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4377 static unsigned int ctls[] = {
4378 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4379 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4380 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4381 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4382 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4383 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4384 };
4385 unsigned int old_ctl, new_ctl;
4386
4387 old_ctl = snd_hda_codec_read(codec, nid, 0,
4388 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4389 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4390 if (old_ctl != new_ctl) {
82beb8fd
TI
4391 int val;
4392 snd_hda_codec_write_cache(codec, nid, 0,
4393 AC_VERB_SET_PIN_WIDGET_CONTROL,
4394 new_ctl);
47fd830a
TI
4395 val = ucontrol->value.enumerated.item[0] >= 3 ?
4396 HDA_AMP_MUTE : 0;
4397 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4398 HDA_AMP_MUTE, val);
2fa522be
TI
4399 return 1;
4400 }
4401 return 0;
4402}
4403
9c7f852e
TI
4404static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4405 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4406{
4407 static char *texts[] = {
4408 "Front", "Surround", "CLFE", "Side"
4409 };
4410 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4411 uinfo->count = 1;
4412 uinfo->value.enumerated.items = 4;
4413 if (uinfo->value.enumerated.item >= 4)
4414 uinfo->value.enumerated.item = 3;
4415 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4416 return 0;
4417}
4418
9c7f852e
TI
4419static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4420 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4421{
4422 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4423 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4424 unsigned int sel;
4425
4426 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4427 ucontrol->value.enumerated.item[0] = sel & 3;
4428 return 0;
4429}
4430
9c7f852e
TI
4431static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4432 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4433{
4434 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4435 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4436 unsigned int sel;
4437
4438 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4439 if (ucontrol->value.enumerated.item[0] != sel) {
4440 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4441 snd_hda_codec_write_cache(codec, nid, 0,
4442 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4443 return 1;
4444 }
4445 return 0;
4446}
4447
4448#define PIN_CTL_TEST(xname,nid) { \
4449 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4450 .name = xname, \
5b0cb1d8 4451 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4452 .info = alc_test_pin_ctl_info, \
4453 .get = alc_test_pin_ctl_get, \
4454 .put = alc_test_pin_ctl_put, \
4455 .private_value = nid \
4456 }
4457
4458#define PIN_SRC_TEST(xname,nid) { \
4459 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4460 .name = xname, \
5b0cb1d8 4461 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4462 .info = alc_test_pin_src_info, \
4463 .get = alc_test_pin_src_get, \
4464 .put = alc_test_pin_src_put, \
4465 .private_value = nid \
4466 }
4467
c8b6bf9b 4468static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4469 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4470 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4471 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4472 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4473 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4474 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4475 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4476 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4477 PIN_CTL_TEST("Front Pin Mode", 0x14),
4478 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4479 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4480 PIN_CTL_TEST("Side Pin Mode", 0x17),
4481 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4482 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4483 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4484 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4485 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4486 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4487 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4488 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4489 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4490 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4491 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4492 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4493 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4494 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4495 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4496 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4497 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4498 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4499 {
4500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4501 .name = "Channel Mode",
df694daa
KY
4502 .info = alc_ch_mode_info,
4503 .get = alc_ch_mode_get,
4504 .put = alc_ch_mode_put,
2fa522be
TI
4505 },
4506 { } /* end */
4507};
4508
4509static struct hda_verb alc880_test_init_verbs[] = {
4510 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4517 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4519 /* Vol output for 0x0c-0x0f */
05acb863
TI
4520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4521 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4522 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4523 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4524 /* Set output pins 0x14-0x17 */
05acb863
TI
4525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4527 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4528 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4529 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4530 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4531 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4532 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4533 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4534 /* Set input pins 0x18-0x1c */
16ded525
TI
4535 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4536 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4537 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4538 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4539 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4540 /* Mute input pins 0x18-0x1b */
05acb863
TI
4541 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4542 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4543 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4544 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4545 /* ADC set up */
05acb863 4546 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4547 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4548 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4549 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4550 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4551 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4552 /* Analog input/passthru */
4553 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4554 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4555 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4558 { }
4559};
4560#endif
4561
1da177e4
LT
4562/*
4563 */
4564
ea734963 4565static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4566 [ALC880_3ST] = "3stack",
4567 [ALC880_TCL_S700] = "tcl",
4568 [ALC880_3ST_DIG] = "3stack-digout",
4569 [ALC880_CLEVO] = "clevo",
4570 [ALC880_5ST] = "5stack",
4571 [ALC880_5ST_DIG] = "5stack-digout",
4572 [ALC880_W810] = "w810",
4573 [ALC880_Z71V] = "z71v",
4574 [ALC880_6ST] = "6stack",
4575 [ALC880_6ST_DIG] = "6stack-digout",
4576 [ALC880_ASUS] = "asus",
4577 [ALC880_ASUS_W1V] = "asus-w1v",
4578 [ALC880_ASUS_DIG] = "asus-dig",
4579 [ALC880_ASUS_DIG2] = "asus-dig2",
4580 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4581 [ALC880_UNIWILL_P53] = "uniwill-p53",
4582 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4583 [ALC880_F1734] = "F1734",
4584 [ALC880_LG] = "lg",
4585 [ALC880_LG_LW] = "lg-lw",
df99cd33 4586 [ALC880_MEDION_RIM] = "medion",
2fa522be 4587#ifdef CONFIG_SND_DEBUG
f5fcc13c 4588 [ALC880_TEST] = "test",
2fa522be 4589#endif
f5fcc13c
TI
4590 [ALC880_AUTO] = "auto",
4591};
4592
4593static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4594 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4595 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4596 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4597 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4598 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4599 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4600 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4601 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4602 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4603 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4604 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4605 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4606 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4607 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4608 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4609 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4610 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4611 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4612 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4613 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4614 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4615 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4616 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4617 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4618 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4619 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4620 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4621 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4622 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4623 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4624 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4625 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4626 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4627 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4628 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4629 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4630 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4631 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4632 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4633 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4634 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4635 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4636 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4637 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4638 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4639 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4640 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4641 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4642 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4643 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4644 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4645 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4646 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4647 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4648 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4649 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4650 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4651 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4652 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4653 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4654 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4655 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4656 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4657 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4658 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4659 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4660 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4661 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4662 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4663 /* default Intel */
4664 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4665 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4666 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4667 {}
4668};
4669
16ded525 4670/*
df694daa 4671 * ALC880 codec presets
16ded525 4672 */
16ded525
TI
4673static struct alc_config_preset alc880_presets[] = {
4674 [ALC880_3ST] = {
e9edcee0 4675 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4676 .init_verbs = { alc880_volume_init_verbs,
4677 alc880_pin_3stack_init_verbs },
16ded525 4678 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4679 .dac_nids = alc880_dac_nids,
16ded525
TI
4680 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4681 .channel_mode = alc880_threestack_modes,
4e195a7b 4682 .need_dac_fix = 1,
16ded525
TI
4683 .input_mux = &alc880_capture_source,
4684 },
4685 [ALC880_3ST_DIG] = {
e9edcee0 4686 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4687 .init_verbs = { alc880_volume_init_verbs,
4688 alc880_pin_3stack_init_verbs },
16ded525 4689 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4690 .dac_nids = alc880_dac_nids,
4691 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4692 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4693 .channel_mode = alc880_threestack_modes,
4e195a7b 4694 .need_dac_fix = 1,
16ded525
TI
4695 .input_mux = &alc880_capture_source,
4696 },
df694daa
KY
4697 [ALC880_TCL_S700] = {
4698 .mixers = { alc880_tcl_s700_mixer },
4699 .init_verbs = { alc880_volume_init_verbs,
4700 alc880_pin_tcl_S700_init_verbs,
4701 alc880_gpio2_init_verbs },
4702 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4703 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4704 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4705 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4706 .hp_nid = 0x03,
4707 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4708 .channel_mode = alc880_2_jack_modes,
4709 .input_mux = &alc880_capture_source,
4710 },
16ded525 4711 [ALC880_5ST] = {
f12ab1e0
TI
4712 .mixers = { alc880_three_stack_mixer,
4713 alc880_five_stack_mixer},
4714 .init_verbs = { alc880_volume_init_verbs,
4715 alc880_pin_5stack_init_verbs },
16ded525
TI
4716 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4717 .dac_nids = alc880_dac_nids,
16ded525
TI
4718 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4719 .channel_mode = alc880_fivestack_modes,
4720 .input_mux = &alc880_capture_source,
4721 },
4722 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4723 .mixers = { alc880_three_stack_mixer,
4724 alc880_five_stack_mixer },
4725 .init_verbs = { alc880_volume_init_verbs,
4726 alc880_pin_5stack_init_verbs },
16ded525
TI
4727 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4728 .dac_nids = alc880_dac_nids,
4729 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4730 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4731 .channel_mode = alc880_fivestack_modes,
4732 .input_mux = &alc880_capture_source,
4733 },
b6482d48
TI
4734 [ALC880_6ST] = {
4735 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4736 .init_verbs = { alc880_volume_init_verbs,
4737 alc880_pin_6stack_init_verbs },
b6482d48
TI
4738 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4739 .dac_nids = alc880_6st_dac_nids,
4740 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4741 .channel_mode = alc880_sixstack_modes,
4742 .input_mux = &alc880_6stack_capture_source,
4743 },
16ded525 4744 [ALC880_6ST_DIG] = {
e9edcee0 4745 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4746 .init_verbs = { alc880_volume_init_verbs,
4747 alc880_pin_6stack_init_verbs },
16ded525
TI
4748 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4749 .dac_nids = alc880_6st_dac_nids,
4750 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4751 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4752 .channel_mode = alc880_sixstack_modes,
4753 .input_mux = &alc880_6stack_capture_source,
4754 },
4755 [ALC880_W810] = {
e9edcee0 4756 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4757 .init_verbs = { alc880_volume_init_verbs,
4758 alc880_pin_w810_init_verbs,
b0af0de5 4759 alc880_gpio2_init_verbs },
16ded525
TI
4760 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4761 .dac_nids = alc880_w810_dac_nids,
4762 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4763 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4764 .channel_mode = alc880_w810_modes,
4765 .input_mux = &alc880_capture_source,
4766 },
4767 [ALC880_Z71V] = {
e9edcee0 4768 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4769 .init_verbs = { alc880_volume_init_verbs,
4770 alc880_pin_z71v_init_verbs },
16ded525
TI
4771 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4772 .dac_nids = alc880_z71v_dac_nids,
4773 .dig_out_nid = ALC880_DIGOUT_NID,
4774 .hp_nid = 0x03,
e9edcee0
TI
4775 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4776 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4777 .input_mux = &alc880_capture_source,
4778 },
4779 [ALC880_F1734] = {
e9edcee0 4780 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4781 .init_verbs = { alc880_volume_init_verbs,
4782 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4783 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4784 .dac_nids = alc880_f1734_dac_nids,
4785 .hp_nid = 0x02,
4786 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4787 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4788 .input_mux = &alc880_f1734_capture_source,
4789 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4790 .setup = alc880_uniwill_p53_setup,
4791 .init_hook = alc_automute_amp,
16ded525
TI
4792 },
4793 [ALC880_ASUS] = {
e9edcee0 4794 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4795 .init_verbs = { alc880_volume_init_verbs,
4796 alc880_pin_asus_init_verbs,
e9edcee0
TI
4797 alc880_gpio1_init_verbs },
4798 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4799 .dac_nids = alc880_asus_dac_nids,
4800 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4801 .channel_mode = alc880_asus_modes,
4e195a7b 4802 .need_dac_fix = 1,
16ded525
TI
4803 .input_mux = &alc880_capture_source,
4804 },
4805 [ALC880_ASUS_DIG] = {
e9edcee0 4806 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4807 .init_verbs = { alc880_volume_init_verbs,
4808 alc880_pin_asus_init_verbs,
e9edcee0
TI
4809 alc880_gpio1_init_verbs },
4810 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4811 .dac_nids = alc880_asus_dac_nids,
16ded525 4812 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4813 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4814 .channel_mode = alc880_asus_modes,
4e195a7b 4815 .need_dac_fix = 1,
16ded525
TI
4816 .input_mux = &alc880_capture_source,
4817 },
df694daa
KY
4818 [ALC880_ASUS_DIG2] = {
4819 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4820 .init_verbs = { alc880_volume_init_verbs,
4821 alc880_pin_asus_init_verbs,
df694daa
KY
4822 alc880_gpio2_init_verbs }, /* use GPIO2 */
4823 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4824 .dac_nids = alc880_asus_dac_nids,
4825 .dig_out_nid = ALC880_DIGOUT_NID,
4826 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4827 .channel_mode = alc880_asus_modes,
4e195a7b 4828 .need_dac_fix = 1,
df694daa
KY
4829 .input_mux = &alc880_capture_source,
4830 },
16ded525 4831 [ALC880_ASUS_W1V] = {
e9edcee0 4832 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4833 .init_verbs = { alc880_volume_init_verbs,
4834 alc880_pin_asus_init_verbs,
e9edcee0
TI
4835 alc880_gpio1_init_verbs },
4836 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4837 .dac_nids = alc880_asus_dac_nids,
16ded525 4838 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4839 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4840 .channel_mode = alc880_asus_modes,
4e195a7b 4841 .need_dac_fix = 1,
16ded525
TI
4842 .input_mux = &alc880_capture_source,
4843 },
4844 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4845 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4846 .init_verbs = { alc880_volume_init_verbs,
4847 alc880_pin_asus_init_verbs },
e9edcee0
TI
4848 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4849 .dac_nids = alc880_asus_dac_nids,
16ded525 4850 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4851 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4852 .channel_mode = alc880_asus_modes,
4e195a7b 4853 .need_dac_fix = 1,
16ded525
TI
4854 .input_mux = &alc880_capture_source,
4855 },
ccc656ce
KY
4856 [ALC880_UNIWILL] = {
4857 .mixers = { alc880_uniwill_mixer },
4858 .init_verbs = { alc880_volume_init_verbs,
4859 alc880_uniwill_init_verbs },
4860 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4861 .dac_nids = alc880_asus_dac_nids,
4862 .dig_out_nid = ALC880_DIGOUT_NID,
4863 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4864 .channel_mode = alc880_threestack_modes,
4865 .need_dac_fix = 1,
4866 .input_mux = &alc880_capture_source,
4867 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4868 .setup = alc880_uniwill_setup,
a9fd4f3f 4869 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4870 },
4871 [ALC880_UNIWILL_P53] = {
4872 .mixers = { alc880_uniwill_p53_mixer },
4873 .init_verbs = { alc880_volume_init_verbs,
4874 alc880_uniwill_p53_init_verbs },
4875 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4876 .dac_nids = alc880_asus_dac_nids,
4877 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4878 .channel_mode = alc880_threestack_modes,
4879 .input_mux = &alc880_capture_source,
4880 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4881 .setup = alc880_uniwill_p53_setup,
4882 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4883 },
4884 [ALC880_FUJITSU] = {
45bdd1c1 4885 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4886 .init_verbs = { alc880_volume_init_verbs,
4887 alc880_uniwill_p53_init_verbs,
4888 alc880_beep_init_verbs },
4889 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4890 .dac_nids = alc880_dac_nids,
d53d7d9e 4891 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4892 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4893 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4894 .input_mux = &alc880_capture_source,
4895 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4896 .setup = alc880_uniwill_p53_setup,
4897 .init_hook = alc_automute_amp,
ccc656ce 4898 },
df694daa
KY
4899 [ALC880_CLEVO] = {
4900 .mixers = { alc880_three_stack_mixer },
4901 .init_verbs = { alc880_volume_init_verbs,
4902 alc880_pin_clevo_init_verbs },
4903 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4904 .dac_nids = alc880_dac_nids,
4905 .hp_nid = 0x03,
4906 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4907 .channel_mode = alc880_threestack_modes,
4e195a7b 4908 .need_dac_fix = 1,
df694daa
KY
4909 .input_mux = &alc880_capture_source,
4910 },
ae6b813a
TI
4911 [ALC880_LG] = {
4912 .mixers = { alc880_lg_mixer },
4913 .init_verbs = { alc880_volume_init_verbs,
4914 alc880_lg_init_verbs },
4915 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4916 .dac_nids = alc880_lg_dac_nids,
4917 .dig_out_nid = ALC880_DIGOUT_NID,
4918 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4919 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4920 .need_dac_fix = 1,
ae6b813a 4921 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4922 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4923 .setup = alc880_lg_setup,
4924 .init_hook = alc_automute_amp,
cb53c626
TI
4925#ifdef CONFIG_SND_HDA_POWER_SAVE
4926 .loopbacks = alc880_lg_loopbacks,
4927#endif
ae6b813a 4928 },
d681518a
TI
4929 [ALC880_LG_LW] = {
4930 .mixers = { alc880_lg_lw_mixer },
4931 .init_verbs = { alc880_volume_init_verbs,
4932 alc880_lg_lw_init_verbs },
0a8c5da3 4933 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4934 .dac_nids = alc880_dac_nids,
4935 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4936 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4937 .channel_mode = alc880_lg_lw_modes,
d681518a 4938 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4939 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4940 .setup = alc880_lg_lw_setup,
4941 .init_hook = alc_automute_amp,
d681518a 4942 },
df99cd33
TI
4943 [ALC880_MEDION_RIM] = {
4944 .mixers = { alc880_medion_rim_mixer },
4945 .init_verbs = { alc880_volume_init_verbs,
4946 alc880_medion_rim_init_verbs,
4947 alc_gpio2_init_verbs },
4948 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4949 .dac_nids = alc880_dac_nids,
4950 .dig_out_nid = ALC880_DIGOUT_NID,
4951 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4952 .channel_mode = alc880_2_jack_modes,
4953 .input_mux = &alc880_medion_rim_capture_source,
4954 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4955 .setup = alc880_medion_rim_setup,
4956 .init_hook = alc880_medion_rim_automute,
df99cd33 4957 },
16ded525
TI
4958#ifdef CONFIG_SND_DEBUG
4959 [ALC880_TEST] = {
e9edcee0
TI
4960 .mixers = { alc880_test_mixer },
4961 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4962 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4963 .dac_nids = alc880_test_dac_nids,
4964 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4965 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4966 .channel_mode = alc880_test_modes,
4967 .input_mux = &alc880_test_capture_source,
4968 },
4969#endif
4970};
4971
e9edcee0
TI
4972/*
4973 * Automatic parse of I/O pins from the BIOS configuration
4974 */
4975
e9edcee0
TI
4976enum {
4977 ALC_CTL_WIDGET_VOL,
4978 ALC_CTL_WIDGET_MUTE,
4979 ALC_CTL_BIND_MUTE,
4980};
c8b6bf9b 4981static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4982 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4983 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4984 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4985};
4986
4987/* add dynamic controls */
f12ab1e0 4988static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 4989 int cidx, unsigned long val)
e9edcee0 4990{
c8b6bf9b 4991 struct snd_kcontrol_new *knew;
e9edcee0 4992
603c4019
TI
4993 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4994 knew = snd_array_new(&spec->kctls);
4995 if (!knew)
4996 return -ENOMEM;
e9edcee0 4997 *knew = alc880_control_templates[type];
543537bd 4998 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4999 if (!knew->name)
e9edcee0 5000 return -ENOMEM;
66ceeb6b 5001 knew->index = cidx;
4d02d1b6 5002 if (get_amp_nid_(val))
5e26dfd0 5003 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5004 knew->private_value = val;
e9edcee0
TI
5005 return 0;
5006}
5007
0afe5f89
TI
5008static int add_control_with_pfx(struct alc_spec *spec, int type,
5009 const char *pfx, const char *dir,
66ceeb6b 5010 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5011{
5012 char name[32];
5013 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5014 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5015}
5016
66ceeb6b
TI
5017#define add_pb_vol_ctrl(spec, type, pfx, val) \
5018 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5019#define add_pb_sw_ctrl(spec, type, pfx, val) \
5020 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5021#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5022 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5023#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5024 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5025
e9edcee0
TI
5026#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5027#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5028#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5029#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5030#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5031#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5032#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5033#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5034#define ALC880_PIN_CD_NID 0x1c
5035
5036/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5037static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5038 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5039{
5040 hda_nid_t nid;
5041 int assigned[4];
5042 int i, j;
5043
5044 memset(assigned, 0, sizeof(assigned));
b0af0de5 5045 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5046
5047 /* check the pins hardwired to audio widget */
5048 for (i = 0; i < cfg->line_outs; i++) {
5049 nid = cfg->line_out_pins[i];
5050 if (alc880_is_fixed_pin(nid)) {
5051 int idx = alc880_fixed_pin_idx(nid);
5014f193 5052 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5053 assigned[idx] = 1;
5054 }
5055 }
5056 /* left pins can be connect to any audio widget */
5057 for (i = 0; i < cfg->line_outs; i++) {
5058 nid = cfg->line_out_pins[i];
5059 if (alc880_is_fixed_pin(nid))
5060 continue;
5061 /* search for an empty channel */
5062 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
5063 if (!assigned[j]) {
5064 spec->multiout.dac_nids[i] =
5065 alc880_idx_to_dac(j);
e9edcee0
TI
5066 assigned[j] = 1;
5067 break;
5068 }
5069 }
5070 }
5071 spec->multiout.num_dacs = cfg->line_outs;
5072 return 0;
5073}
5074
bcb2f0f5
TI
5075static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5076 bool can_be_master)
5077{
5078 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5079 return "Master";
5080
5081 switch (cfg->line_out_type) {
5082 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5083 if (cfg->line_outs == 1)
5084 return "Speaker";
5085 break;
bcb2f0f5
TI
5086 case AUTO_PIN_HP_OUT:
5087 return "Headphone";
5088 default:
5089 if (cfg->line_outs == 1)
5090 return "PCM";
5091 break;
5092 }
5093 return NULL;
5094}
5095
e9edcee0 5096/* add playback controls from the parsed DAC table */
df694daa
KY
5097static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5098 const struct auto_pin_cfg *cfg)
e9edcee0 5099{
ea734963 5100 static const char * const chname[4] = {
f12ab1e0
TI
5101 "Front", "Surround", NULL /*CLFE*/, "Side"
5102 };
bcb2f0f5 5103 const char *pfx = alc_get_line_out_pfx(cfg, false);
e9edcee0
TI
5104 hda_nid_t nid;
5105 int i, err;
5106
5107 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 5108 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5109 continue;
5110 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5111 if (!pfx && i == 2) {
e9edcee0 5112 /* Center/LFE */
0afe5f89
TI
5113 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5114 "Center",
f12ab1e0
TI
5115 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5116 HDA_OUTPUT));
5117 if (err < 0)
e9edcee0 5118 return err;
0afe5f89
TI
5119 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5120 "LFE",
f12ab1e0
TI
5121 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5122 HDA_OUTPUT));
5123 if (err < 0)
e9edcee0 5124 return err;
0afe5f89
TI
5125 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5126 "Center",
f12ab1e0
TI
5127 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5128 HDA_INPUT));
5129 if (err < 0)
e9edcee0 5130 return err;
0afe5f89
TI
5131 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5132 "LFE",
f12ab1e0
TI
5133 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5134 HDA_INPUT));
5135 if (err < 0)
e9edcee0
TI
5136 return err;
5137 } else {
bcb2f0f5
TI
5138 const char *name = pfx;
5139 if (!name)
5140 name = chname[i];
5141 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5142 name, i,
f12ab1e0
TI
5143 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5144 HDA_OUTPUT));
5145 if (err < 0)
e9edcee0 5146 return err;
bcb2f0f5
TI
5147 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5148 name, i,
f12ab1e0
TI
5149 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5150 HDA_INPUT));
5151 if (err < 0)
e9edcee0
TI
5152 return err;
5153 }
5154 }
e9edcee0
TI
5155 return 0;
5156}
5157
8d88bc3d
TI
5158/* add playback controls for speaker and HP outputs */
5159static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5160 const char *pfx)
e9edcee0
TI
5161{
5162 hda_nid_t nid;
5163 int err;
5164
f12ab1e0 5165 if (!pin)
e9edcee0
TI
5166 return 0;
5167
5168 if (alc880_is_fixed_pin(pin)) {
5169 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5170 /* specify the DAC as the extra output */
f12ab1e0 5171 if (!spec->multiout.hp_nid)
e9edcee0 5172 spec->multiout.hp_nid = nid;
82bc955f
TI
5173 else
5174 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5175 /* control HP volume/switch on the output mixer amp */
5176 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5177 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5178 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5179 if (err < 0)
e9edcee0 5180 return err;
0afe5f89 5181 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5182 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5183 if (err < 0)
e9edcee0
TI
5184 return err;
5185 } else if (alc880_is_multi_pin(pin)) {
5186 /* set manual connection */
e9edcee0 5187 /* we have only a switch on HP-out PIN */
0afe5f89 5188 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5189 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5190 if (err < 0)
e9edcee0
TI
5191 return err;
5192 }
5193 return 0;
5194}
5195
5196/* create input playback/capture controls for the given pin */
f12ab1e0 5197static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5198 const char *ctlname, int ctlidx,
df694daa 5199 int idx, hda_nid_t mix_nid)
e9edcee0 5200{
df694daa 5201 int err;
e9edcee0 5202
66ceeb6b 5203 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5204 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5205 if (err < 0)
e9edcee0 5206 return err;
66ceeb6b 5207 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5208 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5209 if (err < 0)
e9edcee0
TI
5210 return err;
5211 return 0;
5212}
5213
05f5f477
TI
5214static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5215{
5216 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5217 return (pincap & AC_PINCAP_IN) != 0;
5218}
5219
e9edcee0 5220/* create playback/capture controls for input pins */
05f5f477
TI
5221static int alc_auto_create_input_ctls(struct hda_codec *codec,
5222 const struct auto_pin_cfg *cfg,
5223 hda_nid_t mixer,
5224 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5225{
05f5f477 5226 struct alc_spec *spec = codec->spec;
61b9b9b1 5227 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5228 int i, err, idx, type_idx = 0;
5229 const char *prev_label = NULL;
e9edcee0 5230
66ceeb6b 5231 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5232 hda_nid_t pin;
10a20af7 5233 const char *label;
05f5f477 5234
66ceeb6b 5235 pin = cfg->inputs[i].pin;
05f5f477
TI
5236 if (!alc_is_input_pin(codec, pin))
5237 continue;
5238
5322bf27
DH
5239 label = hda_get_autocfg_input_label(codec, cfg, i);
5240 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5241 type_idx++;
5242 else
5243 type_idx = 0;
5322bf27
DH
5244 prev_label = label;
5245
05f5f477
TI
5246 if (mixer) {
5247 idx = get_connection_index(codec, mixer, pin);
5248 if (idx >= 0) {
5249 err = new_analog_input(spec, pin,
10a20af7
TI
5250 label, type_idx,
5251 idx, mixer);
05f5f477
TI
5252 if (err < 0)
5253 return err;
5254 }
5255 }
5256
5257 if (!cap1)
5258 continue;
5259 idx = get_connection_index(codec, cap1, pin);
5260 if (idx < 0 && cap2)
5261 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5262 if (idx >= 0)
5263 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5264 }
5265 return 0;
5266}
5267
05f5f477
TI
5268static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5269 const struct auto_pin_cfg *cfg)
5270{
5271 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5272}
5273
f6c7e546
TI
5274static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5275 unsigned int pin_type)
5276{
5277 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5278 pin_type);
5279 /* unmute pin */
d260cdf6
TI
5280 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5281 AMP_OUT_UNMUTE);
f6c7e546
TI
5282}
5283
df694daa
KY
5284static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5285 hda_nid_t nid, int pin_type,
e9edcee0
TI
5286 int dac_idx)
5287{
f6c7e546 5288 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5289 /* need the manual connection? */
5290 if (alc880_is_multi_pin(nid)) {
5291 struct alc_spec *spec = codec->spec;
5292 int idx = alc880_multi_pin_idx(nid);
5293 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5294 AC_VERB_SET_CONNECT_SEL,
5295 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5296 }
5297}
5298
baba8ee9
TI
5299static int get_pin_type(int line_out_type)
5300{
5301 if (line_out_type == AUTO_PIN_HP_OUT)
5302 return PIN_HP;
5303 else
5304 return PIN_OUT;
5305}
5306
e9edcee0
TI
5307static void alc880_auto_init_multi_out(struct hda_codec *codec)
5308{
5309 struct alc_spec *spec = codec->spec;
5310 int i;
ea1fb29a 5311
e9edcee0
TI
5312 for (i = 0; i < spec->autocfg.line_outs; i++) {
5313 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5314 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5315 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5316 }
5317}
5318
8d88bc3d 5319static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5320{
5321 struct alc_spec *spec = codec->spec;
5322 hda_nid_t pin;
5323
82bc955f 5324 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5325 if (pin) /* connect to front */
5326 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5327 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5328 if (pin) /* connect to front */
5329 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5330}
5331
5332static void alc880_auto_init_analog_input(struct hda_codec *codec)
5333{
5334 struct alc_spec *spec = codec->spec;
66ceeb6b 5335 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5336 int i;
5337
66ceeb6b
TI
5338 for (i = 0; i < cfg->num_inputs; i++) {
5339 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5340 if (alc_is_input_pin(codec, nid)) {
30ea098f 5341 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5342 if (nid != ALC880_PIN_CD_NID &&
5343 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5344 snd_hda_codec_write(codec, nid, 0,
5345 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5346 AMP_OUT_MUTE);
5347 }
5348 }
5349}
5350
7f311a46
TI
5351static void alc880_auto_init_input_src(struct hda_codec *codec)
5352{
5353 struct alc_spec *spec = codec->spec;
5354 int c;
5355
5356 for (c = 0; c < spec->num_adc_nids; c++) {
5357 unsigned int mux_idx;
5358 const struct hda_input_mux *imux;
5359 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5360 imux = &spec->input_mux[mux_idx];
5361 if (!imux->num_items && mux_idx > 0)
5362 imux = &spec->input_mux[0];
5363 if (imux)
5364 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5365 AC_VERB_SET_CONNECT_SEL,
5366 imux->items[0].index);
5367 }
5368}
5369
e9edcee0 5370/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5371/* return 1 if successful, 0 if the proper config is not found,
5372 * or a negative error code
5373 */
e9edcee0
TI
5374static int alc880_parse_auto_config(struct hda_codec *codec)
5375{
5376 struct alc_spec *spec = codec->spec;
757899ac 5377 int err;
df694daa 5378 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5379
f12ab1e0
TI
5380 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5381 alc880_ignore);
5382 if (err < 0)
e9edcee0 5383 return err;
f12ab1e0 5384 if (!spec->autocfg.line_outs)
e9edcee0 5385 return 0; /* can't find valid BIOS pin config */
df694daa 5386
f12ab1e0
TI
5387 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5388 if (err < 0)
5389 return err;
5390 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5391 if (err < 0)
5392 return err;
5393 err = alc880_auto_create_extra_out(spec,
5394 spec->autocfg.speaker_pins[0],
5395 "Speaker");
5396 if (err < 0)
5397 return err;
5398 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5399 "Headphone");
5400 if (err < 0)
5401 return err;
05f5f477 5402 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5403 if (err < 0)
e9edcee0
TI
5404 return err;
5405
5406 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5407
757899ac 5408 alc_auto_parse_digital(codec);
e9edcee0 5409
603c4019 5410 if (spec->kctls.list)
d88897ea 5411 add_mixer(spec, spec->kctls.list);
e9edcee0 5412
d88897ea 5413 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5414
a1e8d2da 5415 spec->num_mux_defs = 1;
61b9b9b1 5416 spec->input_mux = &spec->private_imux[0];
e9edcee0 5417
6227cdce 5418 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5419
e9edcee0
TI
5420 return 1;
5421}
5422
ae6b813a
TI
5423/* additional initialization for auto-configuration model */
5424static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5425{
f6c7e546 5426 struct alc_spec *spec = codec->spec;
e9edcee0 5427 alc880_auto_init_multi_out(codec);
8d88bc3d 5428 alc880_auto_init_extra_out(codec);
e9edcee0 5429 alc880_auto_init_analog_input(codec);
7f311a46 5430 alc880_auto_init_input_src(codec);
757899ac 5431 alc_auto_init_digital(codec);
f6c7e546 5432 if (spec->unsol_event)
7fb0d78f 5433 alc_inithook(codec);
e9edcee0
TI
5434}
5435
b59bdf3b
TI
5436/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5437 * one of two digital mic pins, e.g. on ALC272
5438 */
5439static void fixup_automic_adc(struct hda_codec *codec)
5440{
5441 struct alc_spec *spec = codec->spec;
5442 int i;
5443
5444 for (i = 0; i < spec->num_adc_nids; i++) {
5445 hda_nid_t cap = spec->capsrc_nids ?
5446 spec->capsrc_nids[i] : spec->adc_nids[i];
5447 int iidx, eidx;
5448
5449 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5450 if (iidx < 0)
5451 continue;
5452 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5453 if (eidx < 0)
5454 continue;
5455 spec->int_mic.mux_idx = iidx;
5456 spec->ext_mic.mux_idx = eidx;
5457 if (spec->capsrc_nids)
5458 spec->capsrc_nids += i;
5459 spec->adc_nids += i;
5460 spec->num_adc_nids = 1;
5461 return;
5462 }
5463 snd_printd(KERN_INFO "hda_codec: %s: "
5464 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5465 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5466 spec->auto_mic = 0; /* disable auto-mic to be sure */
5467}
5468
748cce43
TI
5469/* select or unmute the given capsrc route */
5470static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5471 int idx)
5472{
5473 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5474 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5475 HDA_AMP_MUTE, 0);
5476 } else {
5477 snd_hda_codec_write_cache(codec, cap, 0,
5478 AC_VERB_SET_CONNECT_SEL, idx);
5479 }
5480}
5481
840b64c0
TI
5482/* set the default connection to that pin */
5483static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5484{
5485 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5486 int i;
5487
eaa9b3a7
TI
5488 for (i = 0; i < spec->num_adc_nids; i++) {
5489 hda_nid_t cap = spec->capsrc_nids ?
5490 spec->capsrc_nids[i] : spec->adc_nids[i];
5491 int idx;
5492
5493 idx = get_connection_index(codec, cap, pin);
5494 if (idx < 0)
5495 continue;
748cce43 5496 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5497 return i; /* return the found index */
5498 }
5499 return -1; /* not found */
5500}
5501
5502/* choose the ADC/MUX containing the input pin and initialize the setup */
5503static void fixup_single_adc(struct hda_codec *codec)
5504{
5505 struct alc_spec *spec = codec->spec;
66ceeb6b 5506 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5507 int i;
5508
5509 /* search for the input pin; there must be only one */
66ceeb6b 5510 if (cfg->num_inputs != 1)
eaa9b3a7 5511 return;
66ceeb6b 5512 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5513 if (i >= 0) {
5514 /* use only this ADC */
5515 if (spec->capsrc_nids)
5516 spec->capsrc_nids += i;
5517 spec->adc_nids += i;
5518 spec->num_adc_nids = 1;
eaa9b3a7
TI
5519 }
5520}
5521
840b64c0
TI
5522/* initialize dual adcs */
5523static void fixup_dual_adc_switch(struct hda_codec *codec)
5524{
5525 struct alc_spec *spec = codec->spec;
5526 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5527 init_capsrc_for_pin(codec, spec->int_mic.pin);
5528}
5529
b59bdf3b 5530static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5531{
b59bdf3b 5532 struct alc_spec *spec = codec->spec;
a23b688f
TI
5533 static struct snd_kcontrol_new *caps[2][3] = {
5534 { alc_capture_mixer_nosrc1,
5535 alc_capture_mixer_nosrc2,
5536 alc_capture_mixer_nosrc3 },
5537 { alc_capture_mixer1,
5538 alc_capture_mixer2,
5539 alc_capture_mixer3 },
f9e336f6 5540 };
a23b688f 5541 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5542 int mux = 0;
840b64c0
TI
5543 int num_adcs = spec->num_adc_nids;
5544 if (spec->dual_adc_switch)
5545 fixup_dual_adc_switch(codec);
5546 else if (spec->auto_mic)
b59bdf3b 5547 fixup_automic_adc(codec);
eaa9b3a7
TI
5548 else if (spec->input_mux) {
5549 if (spec->input_mux->num_items > 1)
5550 mux = 1;
5551 else if (spec->input_mux->num_items == 1)
5552 fixup_single_adc(codec);
5553 }
840b64c0
TI
5554 if (spec->dual_adc_switch)
5555 num_adcs = 1;
5556 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5557 }
f9e336f6
TI
5558}
5559
6694635d
TI
5560/* fill adc_nids (and capsrc_nids) containing all active input pins */
5561static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5562 int num_nids)
5563{
5564 struct alc_spec *spec = codec->spec;
66ceeb6b 5565 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5566 int n;
5567 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5568
5569 for (n = 0; n < num_nids; n++) {
5570 hda_nid_t adc, cap;
5571 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5572 int nconns, i, j;
5573
5574 adc = nids[n];
5575 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5576 continue;
5577 cap = adc;
5578 nconns = snd_hda_get_connections(codec, cap, conn,
5579 ARRAY_SIZE(conn));
5580 if (nconns == 1) {
5581 cap = conn[0];
5582 nconns = snd_hda_get_connections(codec, cap, conn,
5583 ARRAY_SIZE(conn));
5584 }
5585 if (nconns <= 0)
5586 continue;
5587 if (!fallback_adc) {
5588 fallback_adc = adc;
5589 fallback_cap = cap;
5590 }
66ceeb6b
TI
5591 for (i = 0; i < cfg->num_inputs; i++) {
5592 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5593 for (j = 0; j < nconns; j++) {
5594 if (conn[j] == nid)
5595 break;
5596 }
5597 if (j >= nconns)
5598 break;
5599 }
66ceeb6b 5600 if (i >= cfg->num_inputs) {
6694635d
TI
5601 int num_adcs = spec->num_adc_nids;
5602 spec->private_adc_nids[num_adcs] = adc;
5603 spec->private_capsrc_nids[num_adcs] = cap;
5604 spec->num_adc_nids++;
5605 spec->adc_nids = spec->private_adc_nids;
5606 if (adc != cap)
5607 spec->capsrc_nids = spec->private_capsrc_nids;
5608 }
5609 }
5610 if (!spec->num_adc_nids) {
5611 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5612 " using fallback 0x%x\n",
5613 codec->chip_name, fallback_adc);
6694635d
TI
5614 spec->private_adc_nids[0] = fallback_adc;
5615 spec->adc_nids = spec->private_adc_nids;
5616 if (fallback_adc != fallback_cap) {
5617 spec->private_capsrc_nids[0] = fallback_cap;
5618 spec->capsrc_nids = spec->private_adc_nids;
5619 }
5620 }
5621}
5622
67d634c0 5623#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5624#define set_beep_amp(spec, nid, idx, dir) \
5625 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5626
5627static struct snd_pci_quirk beep_white_list[] = {
5628 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5629 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5630 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5631 {}
5632};
5633
5634static inline int has_cdefine_beep(struct hda_codec *codec)
5635{
5636 struct alc_spec *spec = codec->spec;
5637 const struct snd_pci_quirk *q;
5638 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5639 if (q)
5640 return q->value;
5641 return spec->cdefine.enable_pcbeep;
5642}
67d634c0
TI
5643#else
5644#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5645#define has_cdefine_beep(codec) 0
67d634c0 5646#endif
45bdd1c1
TI
5647
5648/*
5649 * OK, here we have finally the patch for ALC880
5650 */
5651
1da177e4
LT
5652static int patch_alc880(struct hda_codec *codec)
5653{
5654 struct alc_spec *spec;
5655 int board_config;
df694daa 5656 int err;
1da177e4 5657
e560d8d8 5658 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5659 if (spec == NULL)
5660 return -ENOMEM;
5661
5662 codec->spec = spec;
5663
f5fcc13c
TI
5664 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5665 alc880_models,
5666 alc880_cfg_tbl);
5667 if (board_config < 0) {
9a11f1aa
TI
5668 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5669 codec->chip_name);
e9edcee0 5670 board_config = ALC880_AUTO;
1da177e4 5671 }
1da177e4 5672
e9edcee0
TI
5673 if (board_config == ALC880_AUTO) {
5674 /* automatic parse from the BIOS config */
5675 err = alc880_parse_auto_config(codec);
5676 if (err < 0) {
5677 alc_free(codec);
5678 return err;
f12ab1e0 5679 } else if (!err) {
9c7f852e
TI
5680 printk(KERN_INFO
5681 "hda_codec: Cannot set up configuration "
5682 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5683 board_config = ALC880_3ST;
5684 }
1da177e4
LT
5685 }
5686
680cd536
KK
5687 err = snd_hda_attach_beep_device(codec, 0x1);
5688 if (err < 0) {
5689 alc_free(codec);
5690 return err;
5691 }
5692
df694daa 5693 if (board_config != ALC880_AUTO)
e9c364c0 5694 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5695
1da177e4
LT
5696 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5697 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5698 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5699
1da177e4
LT
5700 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5701 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5702
f12ab1e0 5703 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5704 /* check whether NID 0x07 is valid */
54d17403 5705 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5706 /* get type */
a22d543a 5707 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5708 if (wcap != AC_WID_AUD_IN) {
5709 spec->adc_nids = alc880_adc_nids_alt;
5710 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5711 } else {
5712 spec->adc_nids = alc880_adc_nids;
5713 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5714 }
5715 }
b59bdf3b 5716 set_capture_mixer(codec);
45bdd1c1 5717 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5718
2134ea4f
TI
5719 spec->vmaster_nid = 0x0c;
5720
1da177e4 5721 codec->patch_ops = alc_patch_ops;
e9edcee0 5722 if (board_config == ALC880_AUTO)
ae6b813a 5723 spec->init_hook = alc880_auto_init;
cb53c626
TI
5724#ifdef CONFIG_SND_HDA_POWER_SAVE
5725 if (!spec->loopback.amplist)
5726 spec->loopback.amplist = alc880_loopbacks;
5727#endif
1da177e4
LT
5728
5729 return 0;
5730}
5731
e9edcee0 5732
1da177e4
LT
5733/*
5734 * ALC260 support
5735 */
5736
e9edcee0
TI
5737static hda_nid_t alc260_dac_nids[1] = {
5738 /* front */
5739 0x02,
5740};
5741
5742static hda_nid_t alc260_adc_nids[1] = {
5743 /* ADC0 */
5744 0x04,
5745};
5746
df694daa 5747static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5748 /* ADC1 */
5749 0x05,
5750};
5751
d57fdac0
JW
5752/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5753 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5754 */
5755static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5756 /* ADC0, ADC1 */
5757 0x04, 0x05
5758};
5759
e9edcee0
TI
5760#define ALC260_DIGOUT_NID 0x03
5761#define ALC260_DIGIN_NID 0x06
5762
5763static struct hda_input_mux alc260_capture_source = {
5764 .num_items = 4,
5765 .items = {
5766 { "Mic", 0x0 },
5767 { "Front Mic", 0x1 },
5768 { "Line", 0x2 },
5769 { "CD", 0x4 },
5770 },
5771};
5772
17e7aec6 5773/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5774 * headphone jack and the internal CD lines since these are the only pins at
5775 * which audio can appear. For flexibility, also allow the option of
5776 * recording the mixer output on the second ADC (ADC0 doesn't have a
5777 * connection to the mixer output).
a9430dd8 5778 */
a1e8d2da
JW
5779static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5780 {
5781 .num_items = 3,
5782 .items = {
5783 { "Mic/Line", 0x0 },
5784 { "CD", 0x4 },
5785 { "Headphone", 0x2 },
5786 },
a9430dd8 5787 },
a1e8d2da
JW
5788 {
5789 .num_items = 4,
5790 .items = {
5791 { "Mic/Line", 0x0 },
5792 { "CD", 0x4 },
5793 { "Headphone", 0x2 },
5794 { "Mixer", 0x5 },
5795 },
5796 },
5797
a9430dd8
JW
5798};
5799
a1e8d2da
JW
5800/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5801 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5802 */
a1e8d2da
JW
5803static struct hda_input_mux alc260_acer_capture_sources[2] = {
5804 {
5805 .num_items = 4,
5806 .items = {
5807 { "Mic", 0x0 },
5808 { "Line", 0x2 },
5809 { "CD", 0x4 },
5810 { "Headphone", 0x5 },
5811 },
5812 },
5813 {
5814 .num_items = 5,
5815 .items = {
5816 { "Mic", 0x0 },
5817 { "Line", 0x2 },
5818 { "CD", 0x4 },
5819 { "Headphone", 0x6 },
5820 { "Mixer", 0x5 },
5821 },
0bfc90e9
JW
5822 },
5823};
cc959489
MS
5824
5825/* Maxdata Favorit 100XS */
5826static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5827 {
5828 .num_items = 2,
5829 .items = {
5830 { "Line/Mic", 0x0 },
5831 { "CD", 0x4 },
5832 },
5833 },
5834 {
5835 .num_items = 3,
5836 .items = {
5837 { "Line/Mic", 0x0 },
5838 { "CD", 0x4 },
5839 { "Mixer", 0x5 },
5840 },
5841 },
5842};
5843
1da177e4
LT
5844/*
5845 * This is just place-holder, so there's something for alc_build_pcms to look
5846 * at when it calculates the maximum number of channels. ALC260 has no mixer
5847 * element which allows changing the channel mode, so the verb list is
5848 * never used.
5849 */
d2a6d7dc 5850static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5851 { 2, NULL },
5852};
5853
df694daa
KY
5854
5855/* Mixer combinations
5856 *
5857 * basic: base_output + input + pc_beep + capture
5858 * HP: base_output + input + capture_alt
5859 * HP_3013: hp_3013 + input + capture
5860 * fujitsu: fujitsu + capture
0bfc90e9 5861 * acer: acer + capture
df694daa
KY
5862 */
5863
5864static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5865 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5866 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5867 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5868 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5869 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5870 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5871 { } /* end */
f12ab1e0 5872};
1da177e4 5873
df694daa 5874static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5875 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5876 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5877 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5878 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5879 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5880 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5881 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5882 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5883 { } /* end */
5884};
5885
bec15c3a
TI
5886/* update HP, line and mono out pins according to the master switch */
5887static void alc260_hp_master_update(struct hda_codec *codec,
5888 hda_nid_t hp, hda_nid_t line,
5889 hda_nid_t mono)
5890{
5891 struct alc_spec *spec = codec->spec;
5892 unsigned int val = spec->master_sw ? PIN_HP : 0;
5893 /* change HP and line-out pins */
30cde0aa 5894 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5895 val);
30cde0aa 5896 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5897 val);
5898 /* mono (speaker) depending on the HP jack sense */
5899 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5900 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5901 val);
5902}
5903
5904static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5905 struct snd_ctl_elem_value *ucontrol)
5906{
5907 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5908 struct alc_spec *spec = codec->spec;
5909 *ucontrol->value.integer.value = spec->master_sw;
5910 return 0;
5911}
5912
5913static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5914 struct snd_ctl_elem_value *ucontrol)
5915{
5916 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5917 struct alc_spec *spec = codec->spec;
5918 int val = !!*ucontrol->value.integer.value;
5919 hda_nid_t hp, line, mono;
5920
5921 if (val == spec->master_sw)
5922 return 0;
5923 spec->master_sw = val;
5924 hp = (kcontrol->private_value >> 16) & 0xff;
5925 line = (kcontrol->private_value >> 8) & 0xff;
5926 mono = kcontrol->private_value & 0xff;
5927 alc260_hp_master_update(codec, hp, line, mono);
5928 return 1;
5929}
5930
5931static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5932 {
5933 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5934 .name = "Master Playback Switch",
5b0cb1d8 5935 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5936 .info = snd_ctl_boolean_mono_info,
5937 .get = alc260_hp_master_sw_get,
5938 .put = alc260_hp_master_sw_put,
5939 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5940 },
5941 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5942 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5943 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5944 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5945 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5946 HDA_OUTPUT),
5947 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5948 { } /* end */
5949};
5950
5951static struct hda_verb alc260_hp_unsol_verbs[] = {
5952 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5953 {},
5954};
5955
5956static void alc260_hp_automute(struct hda_codec *codec)
5957{
5958 struct alc_spec *spec = codec->spec;
bec15c3a 5959
864f92be 5960 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5961 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5962}
5963
5964static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5965{
5966 if ((res >> 26) == ALC880_HP_EVENT)
5967 alc260_hp_automute(codec);
5968}
5969
df694daa 5970static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5971 {
5972 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5973 .name = "Master Playback Switch",
5b0cb1d8 5974 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5975 .info = snd_ctl_boolean_mono_info,
5976 .get = alc260_hp_master_sw_get,
5977 .put = alc260_hp_master_sw_put,
30cde0aa 5978 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5979 },
df694daa
KY
5980 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5981 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5982 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5983 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5984 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5985 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5986 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5987 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5988 { } /* end */
5989};
5990
3f878308
KY
5991static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5992 .ops = &snd_hda_bind_vol,
5993 .values = {
5994 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5995 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5996 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5997 0
5998 },
5999};
6000
6001static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6002 .ops = &snd_hda_bind_sw,
6003 .values = {
6004 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6005 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6006 0
6007 },
6008};
6009
6010static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6011 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6012 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6013 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6014 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6015 { } /* end */
6016};
6017
bec15c3a
TI
6018static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6019 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6020 {},
6021};
6022
6023static void alc260_hp_3013_automute(struct hda_codec *codec)
6024{
6025 struct alc_spec *spec = codec->spec;
bec15c3a 6026
864f92be 6027 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 6028 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
6029}
6030
6031static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6032 unsigned int res)
6033{
6034 if ((res >> 26) == ALC880_HP_EVENT)
6035 alc260_hp_3013_automute(codec);
6036}
6037
3f878308
KY
6038static void alc260_hp_3012_automute(struct hda_codec *codec)
6039{
864f92be 6040 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 6041
3f878308
KY
6042 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6043 bits);
6044 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6045 bits);
6046 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6047 bits);
6048}
6049
6050static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6051 unsigned int res)
6052{
6053 if ((res >> 26) == ALC880_HP_EVENT)
6054 alc260_hp_3012_automute(codec);
6055}
6056
6057/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6058 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6059 */
c8b6bf9b 6060static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6061 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6062 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6063 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6064 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6065 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6066 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6067 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6068 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6069 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6070 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6071 { } /* end */
6072};
6073
a1e8d2da
JW
6074/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6075 * versions of the ALC260 don't act on requests to enable mic bias from NID
6076 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6077 * datasheet doesn't mention this restriction. At this stage it's not clear
6078 * whether this behaviour is intentional or is a hardware bug in chip
6079 * revisions available in early 2006. Therefore for now allow the
6080 * "Headphone Jack Mode" control to span all choices, but if it turns out
6081 * that the lack of mic bias for this NID is intentional we could change the
6082 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6083 *
6084 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6085 * don't appear to make the mic bias available from the "line" jack, even
6086 * though the NID used for this jack (0x14) can supply it. The theory is
6087 * that perhaps Acer have included blocking capacitors between the ALC260
6088 * and the output jack. If this turns out to be the case for all such
6089 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6090 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6091 *
6092 * The C20x Tablet series have a mono internal speaker which is controlled
6093 * via the chip's Mono sum widget and pin complex, so include the necessary
6094 * controls for such models. On models without a "mono speaker" the control
6095 * won't do anything.
a1e8d2da 6096 */
0bfc90e9
JW
6097static struct snd_kcontrol_new alc260_acer_mixer[] = {
6098 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6099 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6100 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6101 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6102 HDA_OUTPUT),
31bffaa9 6103 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6104 HDA_INPUT),
0bfc90e9
JW
6105 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6106 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6107 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6108 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6109 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6110 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6111 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6112 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6113 { } /* end */
6114};
6115
cc959489
MS
6116/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6117 */
6118static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6119 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6120 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6121 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6122 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6123 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6124 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6125 { } /* end */
6126};
6127
bc9f98a9
KY
6128/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6129 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6130 */
6131static struct snd_kcontrol_new alc260_will_mixer[] = {
6132 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6133 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6134 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6135 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6136 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6137 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6138 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6139 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6140 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6141 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6142 { } /* end */
6143};
6144
6145/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6146 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6147 */
6148static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6149 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6150 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6151 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6152 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6153 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6154 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6155 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6156 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6157 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6158 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6159 { } /* end */
6160};
6161
df694daa
KY
6162/*
6163 * initialization verbs
6164 */
1da177e4
LT
6165static struct hda_verb alc260_init_verbs[] = {
6166 /* Line In pin widget for input */
05acb863 6167 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6168 /* CD pin widget for input */
05acb863 6169 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6170 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6171 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6172 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6173 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6174 /* LINE-2 is used for line-out in rear */
05acb863 6175 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6176 /* select line-out */
fd56f2db 6177 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6178 /* LINE-OUT pin */
05acb863 6179 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6180 /* enable HP */
05acb863 6181 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6182 /* enable Mono */
05acb863
TI
6183 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6184 /* mute capture amp left and right */
16ded525 6185 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6186 /* set connection select to line in (default select for this ADC) */
6187 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6188 /* mute capture amp left and right */
6189 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6190 /* set connection select to line in (default select for this ADC) */
6191 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6192 /* set vol=0 Line-Out mixer amp left and right */
6193 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6194 /* unmute pin widget amp left and right (no gain on this amp) */
6195 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6196 /* set vol=0 HP mixer amp left and right */
6197 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6198 /* unmute pin widget amp left and right (no gain on this amp) */
6199 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6200 /* set vol=0 Mono mixer amp left and right */
6201 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6202 /* unmute pin widget amp left and right (no gain on this amp) */
6203 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6204 /* unmute LINE-2 out pin */
6205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6206 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6207 * Line In 2 = 0x03
6208 */
cb53c626
TI
6209 /* mute analog inputs */
6210 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6211 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6212 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6214 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6215 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6216 /* mute Front out path */
6217 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6218 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6219 /* mute Headphone out path */
6220 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6221 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6222 /* mute Mono out path */
6223 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6224 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6225 { }
6226};
6227
474167d6 6228#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6229static struct hda_verb alc260_hp_init_verbs[] = {
6230 /* Headphone and output */
6231 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6232 /* mono output */
6233 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6234 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6235 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6236 /* Mic2 (front panel) pin widget for input and vref at 80% */
6237 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6238 /* Line In pin widget for input */
6239 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6240 /* Line-2 pin widget for output */
6241 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6242 /* CD pin widget for input */
6243 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6244 /* unmute amp left and right */
6245 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6246 /* set connection select to line in (default select for this ADC) */
6247 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6248 /* unmute Line-Out mixer amp left and right (volume = 0) */
6249 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6250 /* mute pin widget amp left and right (no gain on this amp) */
6251 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6252 /* unmute HP mixer amp left and right (volume = 0) */
6253 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6254 /* mute pin widget amp left and right (no gain on this amp) */
6255 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6256 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6257 * Line In 2 = 0x03
6258 */
cb53c626
TI
6259 /* mute analog inputs */
6260 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6261 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6262 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6264 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6265 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6266 /* Unmute Front out path */
6267 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6268 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6269 /* Unmute Headphone out path */
6270 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6271 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6272 /* Unmute Mono out path */
6273 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6274 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6275 { }
6276};
474167d6 6277#endif
df694daa
KY
6278
6279static struct hda_verb alc260_hp_3013_init_verbs[] = {
6280 /* Line out and output */
6281 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6282 /* mono output */
6283 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6284 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6285 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6286 /* Mic2 (front panel) pin widget for input and vref at 80% */
6287 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6288 /* Line In pin widget for input */
6289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6290 /* Headphone pin widget for output */
6291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6292 /* CD pin widget for input */
6293 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6294 /* unmute amp left and right */
6295 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6296 /* set connection select to line in (default select for this ADC) */
6297 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6298 /* unmute Line-Out mixer amp left and right (volume = 0) */
6299 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6300 /* mute pin widget amp left and right (no gain on this amp) */
6301 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6302 /* unmute HP mixer amp left and right (volume = 0) */
6303 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6304 /* mute pin widget amp left and right (no gain on this amp) */
6305 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6306 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6307 * Line In 2 = 0x03
6308 */
cb53c626
TI
6309 /* mute analog inputs */
6310 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6311 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6312 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6313 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6314 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6315 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6316 /* Unmute Front out path */
6317 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6318 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6319 /* Unmute Headphone out path */
6320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6321 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6322 /* Unmute Mono out path */
6323 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6324 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6325 { }
6326};
6327
a9430dd8 6328/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6329 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6330 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6331 */
6332static struct hda_verb alc260_fujitsu_init_verbs[] = {
6333 /* Disable all GPIOs */
6334 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6335 /* Internal speaker is connected to headphone pin */
6336 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6337 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6339 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6340 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6341 /* Ensure all other unused pins are disabled and muted. */
6342 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6343 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6344 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6345 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6346 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6347 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6348 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6349 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6350
6351 /* Disable digital (SPDIF) pins */
6352 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6353 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6354
ea1fb29a 6355 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6356 * when acting as an output.
6357 */
6358 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6359
f7ace40d 6360 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6361 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6362 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6363 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6364 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6365 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6366 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6367 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6368 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6369 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6370
f7ace40d
JW
6371 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6372 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6373 /* Unmute Line1 pin widget output buffer since it starts as an output.
6374 * If the pin mode is changed by the user the pin mode control will
6375 * take care of enabling the pin's input/output buffers as needed.
6376 * Therefore there's no need to enable the input buffer at this
6377 * stage.
cdcd9268 6378 */
f7ace40d 6379 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6380 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6381 * mixer ctrl)
6382 */
f7ace40d
JW
6383 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6384
6385 /* Mute capture amp left and right */
6386 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6387 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6388 * in (on mic1 pin)
6389 */
6390 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6391
6392 /* Do the same for the second ADC: mute capture input amp and
6393 * set ADC connection to line in (on mic1 pin)
6394 */
6395 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6396 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6397
6398 /* Mute all inputs to mixer widget (even unconnected ones) */
6399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6400 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6401 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6402 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6403 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6404 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6405 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6406 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6407
6408 { }
a9430dd8
JW
6409};
6410
0bfc90e9
JW
6411/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6412 * similar laptops (adapted from Fujitsu init verbs).
6413 */
6414static struct hda_verb alc260_acer_init_verbs[] = {
6415 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6416 * the headphone jack. Turn this on and rely on the standard mute
6417 * methods whenever the user wants to turn these outputs off.
6418 */
6419 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6420 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6421 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6422 /* Internal speaker/Headphone jack is connected to Line-out pin */
6423 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6424 /* Internal microphone/Mic jack is connected to Mic1 pin */
6425 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6426 /* Line In jack is connected to Line1 pin */
6427 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6428 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6429 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6430 /* Ensure all other unused pins are disabled and muted. */
6431 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6432 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6433 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6434 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6435 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6436 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6437 /* Disable digital (SPDIF) pins */
6438 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6439 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6440
ea1fb29a 6441 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6442 * bus when acting as outputs.
6443 */
6444 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6445 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6446
6447 /* Start with output sum widgets muted and their output gains at min */
6448 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6449 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6450 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6451 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6452 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6453 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6454 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6455 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6456 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6457
f12ab1e0
TI
6458 /* Unmute Line-out pin widget amp left and right
6459 * (no equiv mixer ctrl)
6460 */
0bfc90e9 6461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6462 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6463 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6464 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6465 * inputs. If the pin mode is changed by the user the pin mode control
6466 * will take care of enabling the pin's input/output buffers as needed.
6467 * Therefore there's no need to enable the input buffer at this
6468 * stage.
6469 */
6470 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6471 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6472
6473 /* Mute capture amp left and right */
6474 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6475 /* Set ADC connection select to match default mixer setting - mic
6476 * (on mic1 pin)
6477 */
6478 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6479
6480 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6481 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6482 */
6483 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6484 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6485
6486 /* Mute all inputs to mixer widget (even unconnected ones) */
6487 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6489 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6491 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6492 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6493 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6494 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6495
6496 { }
6497};
6498
cc959489
MS
6499/* Initialisation sequence for Maxdata Favorit 100XS
6500 * (adapted from Acer init verbs).
6501 */
6502static struct hda_verb alc260_favorit100_init_verbs[] = {
6503 /* GPIO 0 enables the output jack.
6504 * Turn this on and rely on the standard mute
6505 * methods whenever the user wants to turn these outputs off.
6506 */
6507 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6508 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6509 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6510 /* Line/Mic input jack is connected to Mic1 pin */
6511 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6512 /* Ensure all other unused pins are disabled and muted. */
6513 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6514 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6515 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6516 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6517 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6518 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6520 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6522 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6523 /* Disable digital (SPDIF) pins */
6524 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6525 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6526
6527 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6528 * bus when acting as outputs.
6529 */
6530 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6531 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6532
6533 /* Start with output sum widgets muted and their output gains at min */
6534 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6535 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6536 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6537 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6538 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6539 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6540 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6541 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6542 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6543
6544 /* Unmute Line-out pin widget amp left and right
6545 * (no equiv mixer ctrl)
6546 */
6547 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6548 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6549 * inputs. If the pin mode is changed by the user the pin mode control
6550 * will take care of enabling the pin's input/output buffers as needed.
6551 * Therefore there's no need to enable the input buffer at this
6552 * stage.
6553 */
6554 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6555
6556 /* Mute capture amp left and right */
6557 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6558 /* Set ADC connection select to match default mixer setting - mic
6559 * (on mic1 pin)
6560 */
6561 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6562
6563 /* Do similar with the second ADC: mute capture input amp and
6564 * set ADC connection to mic to match ALSA's default state.
6565 */
6566 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6567 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6568
6569 /* Mute all inputs to mixer widget (even unconnected ones) */
6570 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6571 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6578
6579 { }
6580};
6581
bc9f98a9
KY
6582static struct hda_verb alc260_will_verbs[] = {
6583 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6584 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6585 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6586 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6587 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6588 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6589 {}
6590};
6591
6592static struct hda_verb alc260_replacer_672v_verbs[] = {
6593 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6594 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6595 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6596
6597 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6598 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6599 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6600
6601 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6602 {}
6603};
6604
6605/* toggle speaker-output according to the hp-jack state */
6606static void alc260_replacer_672v_automute(struct hda_codec *codec)
6607{
6608 unsigned int present;
6609
6610 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6611 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6612 if (present) {
82beb8fd
TI
6613 snd_hda_codec_write_cache(codec, 0x01, 0,
6614 AC_VERB_SET_GPIO_DATA, 1);
6615 snd_hda_codec_write_cache(codec, 0x0f, 0,
6616 AC_VERB_SET_PIN_WIDGET_CONTROL,
6617 PIN_HP);
bc9f98a9 6618 } else {
82beb8fd
TI
6619 snd_hda_codec_write_cache(codec, 0x01, 0,
6620 AC_VERB_SET_GPIO_DATA, 0);
6621 snd_hda_codec_write_cache(codec, 0x0f, 0,
6622 AC_VERB_SET_PIN_WIDGET_CONTROL,
6623 PIN_OUT);
bc9f98a9
KY
6624 }
6625}
6626
6627static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6628 unsigned int res)
6629{
6630 if ((res >> 26) == ALC880_HP_EVENT)
6631 alc260_replacer_672v_automute(codec);
6632}
6633
3f878308
KY
6634static struct hda_verb alc260_hp_dc7600_verbs[] = {
6635 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6636 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6637 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6638 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6639 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6640 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6641 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6642 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6643 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6644 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6645 {}
6646};
6647
7cf51e48
JW
6648/* Test configuration for debugging, modelled after the ALC880 test
6649 * configuration.
6650 */
6651#ifdef CONFIG_SND_DEBUG
6652static hda_nid_t alc260_test_dac_nids[1] = {
6653 0x02,
6654};
6655static hda_nid_t alc260_test_adc_nids[2] = {
6656 0x04, 0x05,
6657};
a1e8d2da 6658/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6659 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6660 * is NID 0x04.
17e7aec6 6661 */
a1e8d2da
JW
6662static struct hda_input_mux alc260_test_capture_sources[2] = {
6663 {
6664 .num_items = 7,
6665 .items = {
6666 { "MIC1 pin", 0x0 },
6667 { "MIC2 pin", 0x1 },
6668 { "LINE1 pin", 0x2 },
6669 { "LINE2 pin", 0x3 },
6670 { "CD pin", 0x4 },
6671 { "LINE-OUT pin", 0x5 },
6672 { "HP-OUT pin", 0x6 },
6673 },
6674 },
6675 {
6676 .num_items = 8,
6677 .items = {
6678 { "MIC1 pin", 0x0 },
6679 { "MIC2 pin", 0x1 },
6680 { "LINE1 pin", 0x2 },
6681 { "LINE2 pin", 0x3 },
6682 { "CD pin", 0x4 },
6683 { "Mixer", 0x5 },
6684 { "LINE-OUT pin", 0x6 },
6685 { "HP-OUT pin", 0x7 },
6686 },
7cf51e48
JW
6687 },
6688};
6689static struct snd_kcontrol_new alc260_test_mixer[] = {
6690 /* Output driver widgets */
6691 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6692 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6693 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6694 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6695 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6696 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6697
a1e8d2da
JW
6698 /* Modes for retasking pin widgets
6699 * Note: the ALC260 doesn't seem to act on requests to enable mic
6700 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6701 * mention this restriction. At this stage it's not clear whether
6702 * this behaviour is intentional or is a hardware bug in chip
6703 * revisions available at least up until early 2006. Therefore for
6704 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6705 * choices, but if it turns out that the lack of mic bias for these
6706 * NIDs is intentional we could change their modes from
6707 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6708 */
7cf51e48
JW
6709 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6710 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6711 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6712 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6713 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6714 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6715
6716 /* Loopback mixer controls */
6717 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6718 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6719 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6720 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6721 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6722 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6723 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6724 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6725 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6726 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6727 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6728 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6729 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6730 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6731
6732 /* Controls for GPIO pins, assuming they are configured as outputs */
6733 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6734 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6735 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6736 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6737
92621f13
JW
6738 /* Switches to allow the digital IO pins to be enabled. The datasheet
6739 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6740 * make this output available should provide clarification.
92621f13
JW
6741 */
6742 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6743 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6744
f8225f6d
JW
6745 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6746 * this output to turn on an external amplifier.
6747 */
6748 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6749 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6750
7cf51e48
JW
6751 { } /* end */
6752};
6753static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6754 /* Enable all GPIOs as outputs with an initial value of 0 */
6755 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6756 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6757 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6758
7cf51e48
JW
6759 /* Enable retasking pins as output, initially without power amp */
6760 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6761 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6763 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6764 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6765 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6766
92621f13
JW
6767 /* Disable digital (SPDIF) pins initially, but users can enable
6768 * them via a mixer switch. In the case of SPDIF-out, this initverb
6769 * payload also sets the generation to 0, output to be in "consumer"
6770 * PCM format, copyright asserted, no pre-emphasis and no validity
6771 * control.
6772 */
7cf51e48
JW
6773 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6774 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6775
ea1fb29a 6776 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6777 * OUT1 sum bus when acting as an output.
6778 */
6779 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6780 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6781 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6782 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6783
6784 /* Start with output sum widgets muted and their output gains at min */
6785 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6786 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6789 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6791 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6792 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6793 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6794
cdcd9268
JW
6795 /* Unmute retasking pin widget output buffers since the default
6796 * state appears to be output. As the pin mode is changed by the
6797 * user the pin mode control will take care of enabling the pin's
6798 * input/output buffers as needed.
6799 */
7cf51e48
JW
6800 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6801 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6803 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6804 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6805 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6806 /* Also unmute the mono-out pin widget */
6807 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6808
7cf51e48
JW
6809 /* Mute capture amp left and right */
6810 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6811 /* Set ADC connection select to match default mixer setting (mic1
6812 * pin)
7cf51e48
JW
6813 */
6814 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6815
6816 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6817 * set ADC connection to mic1 pin
7cf51e48
JW
6818 */
6819 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6820 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6821
6822 /* Mute all inputs to mixer widget (even unconnected ones) */
6823 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6824 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6831
6832 { }
6833};
6834#endif
6835
6330079f
TI
6836#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6837#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6838
a3bcba38
TI
6839#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6840#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6841
df694daa
KY
6842/*
6843 * for BIOS auto-configuration
6844 */
16ded525 6845
df694daa 6846static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6847 const char *pfx, int *vol_bits)
df694daa
KY
6848{
6849 hda_nid_t nid_vol;
6850 unsigned long vol_val, sw_val;
df694daa
KY
6851 int err;
6852
6853 if (nid >= 0x0f && nid < 0x11) {
6854 nid_vol = nid - 0x7;
6855 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6856 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6857 } else if (nid == 0x11) {
6858 nid_vol = nid - 0x7;
6859 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6860 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6861 } else if (nid >= 0x12 && nid <= 0x15) {
6862 nid_vol = 0x08;
6863 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6864 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6865 } else
6866 return 0; /* N/A */
ea1fb29a 6867
863b4518
TI
6868 if (!(*vol_bits & (1 << nid_vol))) {
6869 /* first control for the volume widget */
0afe5f89 6870 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6871 if (err < 0)
6872 return err;
6873 *vol_bits |= (1 << nid_vol);
6874 }
0afe5f89 6875 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6876 if (err < 0)
df694daa
KY
6877 return err;
6878 return 1;
6879}
6880
6881/* add playback controls from the parsed DAC table */
6882static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6883 const struct auto_pin_cfg *cfg)
6884{
6885 hda_nid_t nid;
6886 int err;
863b4518 6887 int vols = 0;
df694daa
KY
6888
6889 spec->multiout.num_dacs = 1;
6890 spec->multiout.dac_nids = spec->private_dac_nids;
6891 spec->multiout.dac_nids[0] = 0x02;
6892
6893 nid = cfg->line_out_pins[0];
6894 if (nid) {
23112d6d
TI
6895 const char *pfx;
6896 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6897 pfx = "Master";
6898 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6899 pfx = "Speaker";
6900 else
6901 pfx = "Front";
6902 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6903 if (err < 0)
6904 return err;
6905 }
6906
82bc955f 6907 nid = cfg->speaker_pins[0];
df694daa 6908 if (nid) {
863b4518 6909 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6910 if (err < 0)
6911 return err;
6912 }
6913
eb06ed8f 6914 nid = cfg->hp_pins[0];
df694daa 6915 if (nid) {
863b4518
TI
6916 err = alc260_add_playback_controls(spec, nid, "Headphone",
6917 &vols);
df694daa
KY
6918 if (err < 0)
6919 return err;
6920 }
f12ab1e0 6921 return 0;
df694daa
KY
6922}
6923
6924/* create playback/capture controls for input pins */
05f5f477 6925static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6926 const struct auto_pin_cfg *cfg)
6927{
05f5f477 6928 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6929}
6930
6931static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6932 hda_nid_t nid, int pin_type,
6933 int sel_idx)
6934{
f6c7e546 6935 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6936 /* need the manual connection? */
6937 if (nid >= 0x12) {
6938 int idx = nid - 0x12;
6939 snd_hda_codec_write(codec, idx + 0x0b, 0,
6940 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6941 }
6942}
6943
6944static void alc260_auto_init_multi_out(struct hda_codec *codec)
6945{
6946 struct alc_spec *spec = codec->spec;
6947 hda_nid_t nid;
6948
f12ab1e0 6949 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6950 if (nid) {
6951 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6952 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6953 }
ea1fb29a 6954
82bc955f 6955 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6956 if (nid)
6957 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6958
eb06ed8f 6959 nid = spec->autocfg.hp_pins[0];
df694daa 6960 if (nid)
baba8ee9 6961 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6962}
df694daa
KY
6963
6964#define ALC260_PIN_CD_NID 0x16
6965static void alc260_auto_init_analog_input(struct hda_codec *codec)
6966{
6967 struct alc_spec *spec = codec->spec;
66ceeb6b 6968 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6969 int i;
6970
66ceeb6b
TI
6971 for (i = 0; i < cfg->num_inputs; i++) {
6972 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6973 if (nid >= 0x12) {
30ea098f 6974 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6975 if (nid != ALC260_PIN_CD_NID &&
6976 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6977 snd_hda_codec_write(codec, nid, 0,
6978 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6979 AMP_OUT_MUTE);
6980 }
6981 }
6982}
6983
7f311a46
TI
6984#define alc260_auto_init_input_src alc880_auto_init_input_src
6985
df694daa
KY
6986/*
6987 * generic initialization of ADC, input mixers and output mixers
6988 */
6989static struct hda_verb alc260_volume_init_verbs[] = {
6990 /*
6991 * Unmute ADC0-1 and set the default input to mic-in
6992 */
6993 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6994 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6995 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6996 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6997
df694daa
KY
6998 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6999 * mixer widget
f12ab1e0
TI
7000 * Note: PASD motherboards uses the Line In 2 as the input for
7001 * front panel mic (mic 2)
df694daa
KY
7002 */
7003 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7004 /* mute analog inputs */
7005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7006 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7007 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7008 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7010
7011 /*
7012 * Set up output mixers (0x08 - 0x0a)
7013 */
7014 /* set vol=0 to output mixers */
7015 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7016 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7017 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7018 /* set up input amps for analog loopback */
7019 /* Amp Indices: DAC = 0, mixer = 1 */
7020 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7021 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7022 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7023 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7024 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7025 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7026
df694daa
KY
7027 { }
7028};
7029
7030static int alc260_parse_auto_config(struct hda_codec *codec)
7031{
7032 struct alc_spec *spec = codec->spec;
df694daa
KY
7033 int err;
7034 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7035
f12ab1e0
TI
7036 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7037 alc260_ignore);
7038 if (err < 0)
df694daa 7039 return err;
f12ab1e0
TI
7040 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7041 if (err < 0)
4a471b7d 7042 return err;
603c4019 7043 if (!spec->kctls.list)
df694daa 7044 return 0; /* can't find valid BIOS pin config */
05f5f477 7045 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7046 if (err < 0)
df694daa
KY
7047 return err;
7048
7049 spec->multiout.max_channels = 2;
7050
0852d7a6 7051 if (spec->autocfg.dig_outs)
df694daa 7052 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7053 if (spec->kctls.list)
d88897ea 7054 add_mixer(spec, spec->kctls.list);
df694daa 7055
d88897ea 7056 add_verb(spec, alc260_volume_init_verbs);
df694daa 7057
a1e8d2da 7058 spec->num_mux_defs = 1;
61b9b9b1 7059 spec->input_mux = &spec->private_imux[0];
df694daa 7060
6227cdce 7061 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7062
df694daa
KY
7063 return 1;
7064}
7065
ae6b813a
TI
7066/* additional initialization for auto-configuration model */
7067static void alc260_auto_init(struct hda_codec *codec)
df694daa 7068{
f6c7e546 7069 struct alc_spec *spec = codec->spec;
df694daa
KY
7070 alc260_auto_init_multi_out(codec);
7071 alc260_auto_init_analog_input(codec);
7f311a46 7072 alc260_auto_init_input_src(codec);
757899ac 7073 alc_auto_init_digital(codec);
f6c7e546 7074 if (spec->unsol_event)
7fb0d78f 7075 alc_inithook(codec);
df694daa
KY
7076}
7077
cb53c626
TI
7078#ifdef CONFIG_SND_HDA_POWER_SAVE
7079static struct hda_amp_list alc260_loopbacks[] = {
7080 { 0x07, HDA_INPUT, 0 },
7081 { 0x07, HDA_INPUT, 1 },
7082 { 0x07, HDA_INPUT, 2 },
7083 { 0x07, HDA_INPUT, 3 },
7084 { 0x07, HDA_INPUT, 4 },
7085 { } /* end */
7086};
7087#endif
7088
fc091769
TI
7089/*
7090 * Pin config fixes
7091 */
7092enum {
7093 PINFIX_HP_DC5750,
7094};
7095
fc091769
TI
7096static const struct alc_fixup alc260_fixups[] = {
7097 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7098 .type = ALC_FIXUP_PINS,
7099 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7100 { 0x11, 0x90130110 }, /* speaker */
7101 { }
7102 }
fc091769
TI
7103 },
7104};
7105
7106static struct snd_pci_quirk alc260_fixup_tbl[] = {
7107 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7108 {}
7109};
7110
df694daa
KY
7111/*
7112 * ALC260 configurations
7113 */
ea734963 7114static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7115 [ALC260_BASIC] = "basic",
7116 [ALC260_HP] = "hp",
7117 [ALC260_HP_3013] = "hp-3013",
2922c9af 7118 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7119 [ALC260_FUJITSU_S702X] = "fujitsu",
7120 [ALC260_ACER] = "acer",
bc9f98a9
KY
7121 [ALC260_WILL] = "will",
7122 [ALC260_REPLACER_672V] = "replacer",
cc959489 7123 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7124#ifdef CONFIG_SND_DEBUG
f5fcc13c 7125 [ALC260_TEST] = "test",
7cf51e48 7126#endif
f5fcc13c
TI
7127 [ALC260_AUTO] = "auto",
7128};
7129
7130static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7131 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7132 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7133 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7134 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7135 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7136 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7137 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7138 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7139 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7140 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7141 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7142 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7143 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7144 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7145 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7146 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7147 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7148 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7149 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7150 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7151 {}
7152};
7153
7154static struct alc_config_preset alc260_presets[] = {
7155 [ALC260_BASIC] = {
7156 .mixers = { alc260_base_output_mixer,
45bdd1c1 7157 alc260_input_mixer },
df694daa
KY
7158 .init_verbs = { alc260_init_verbs },
7159 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7160 .dac_nids = alc260_dac_nids,
f9e336f6 7161 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7162 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7163 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7164 .channel_mode = alc260_modes,
7165 .input_mux = &alc260_capture_source,
7166 },
7167 [ALC260_HP] = {
bec15c3a 7168 .mixers = { alc260_hp_output_mixer,
f9e336f6 7169 alc260_input_mixer },
bec15c3a
TI
7170 .init_verbs = { alc260_init_verbs,
7171 alc260_hp_unsol_verbs },
df694daa
KY
7172 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7173 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7174 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7175 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7176 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7177 .channel_mode = alc260_modes,
7178 .input_mux = &alc260_capture_source,
bec15c3a
TI
7179 .unsol_event = alc260_hp_unsol_event,
7180 .init_hook = alc260_hp_automute,
df694daa 7181 },
3f878308
KY
7182 [ALC260_HP_DC7600] = {
7183 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7184 alc260_input_mixer },
3f878308
KY
7185 .init_verbs = { alc260_init_verbs,
7186 alc260_hp_dc7600_verbs },
7187 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7188 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7189 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7190 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7191 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7192 .channel_mode = alc260_modes,
7193 .input_mux = &alc260_capture_source,
7194 .unsol_event = alc260_hp_3012_unsol_event,
7195 .init_hook = alc260_hp_3012_automute,
7196 },
df694daa
KY
7197 [ALC260_HP_3013] = {
7198 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7199 alc260_input_mixer },
bec15c3a
TI
7200 .init_verbs = { alc260_hp_3013_init_verbs,
7201 alc260_hp_3013_unsol_verbs },
df694daa
KY
7202 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7203 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7204 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7205 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7206 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7207 .channel_mode = alc260_modes,
7208 .input_mux = &alc260_capture_source,
bec15c3a
TI
7209 .unsol_event = alc260_hp_3013_unsol_event,
7210 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7211 },
7212 [ALC260_FUJITSU_S702X] = {
f9e336f6 7213 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7214 .init_verbs = { alc260_fujitsu_init_verbs },
7215 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7216 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7217 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7218 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7219 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7220 .channel_mode = alc260_modes,
a1e8d2da
JW
7221 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7222 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7223 },
0bfc90e9 7224 [ALC260_ACER] = {
f9e336f6 7225 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7226 .init_verbs = { alc260_acer_init_verbs },
7227 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7228 .dac_nids = alc260_dac_nids,
7229 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7230 .adc_nids = alc260_dual_adc_nids,
7231 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7232 .channel_mode = alc260_modes,
a1e8d2da
JW
7233 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7234 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7235 },
cc959489
MS
7236 [ALC260_FAVORIT100] = {
7237 .mixers = { alc260_favorit100_mixer },
7238 .init_verbs = { alc260_favorit100_init_verbs },
7239 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7240 .dac_nids = alc260_dac_nids,
7241 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7242 .adc_nids = alc260_dual_adc_nids,
7243 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7244 .channel_mode = alc260_modes,
7245 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7246 .input_mux = alc260_favorit100_capture_sources,
7247 },
bc9f98a9 7248 [ALC260_WILL] = {
f9e336f6 7249 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7250 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7251 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7252 .dac_nids = alc260_dac_nids,
7253 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7254 .adc_nids = alc260_adc_nids,
7255 .dig_out_nid = ALC260_DIGOUT_NID,
7256 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7257 .channel_mode = alc260_modes,
7258 .input_mux = &alc260_capture_source,
7259 },
7260 [ALC260_REPLACER_672V] = {
f9e336f6 7261 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7262 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7263 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7264 .dac_nids = alc260_dac_nids,
7265 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7266 .adc_nids = alc260_adc_nids,
7267 .dig_out_nid = ALC260_DIGOUT_NID,
7268 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7269 .channel_mode = alc260_modes,
7270 .input_mux = &alc260_capture_source,
7271 .unsol_event = alc260_replacer_672v_unsol_event,
7272 .init_hook = alc260_replacer_672v_automute,
7273 },
7cf51e48
JW
7274#ifdef CONFIG_SND_DEBUG
7275 [ALC260_TEST] = {
f9e336f6 7276 .mixers = { alc260_test_mixer },
7cf51e48
JW
7277 .init_verbs = { alc260_test_init_verbs },
7278 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7279 .dac_nids = alc260_test_dac_nids,
7280 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7281 .adc_nids = alc260_test_adc_nids,
7282 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7283 .channel_mode = alc260_modes,
a1e8d2da
JW
7284 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7285 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7286 },
7287#endif
df694daa
KY
7288};
7289
7290static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7291{
7292 struct alc_spec *spec;
df694daa 7293 int err, board_config;
1da177e4 7294
e560d8d8 7295 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7296 if (spec == NULL)
7297 return -ENOMEM;
7298
7299 codec->spec = spec;
7300
f5fcc13c
TI
7301 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7302 alc260_models,
7303 alc260_cfg_tbl);
7304 if (board_config < 0) {
9a11f1aa 7305 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7306 codec->chip_name);
df694daa 7307 board_config = ALC260_AUTO;
16ded525 7308 }
1da177e4 7309
b5bfbc67
TI
7310 if (board_config == ALC260_AUTO) {
7311 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7312 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7313 }
fc091769 7314
df694daa
KY
7315 if (board_config == ALC260_AUTO) {
7316 /* automatic parse from the BIOS config */
7317 err = alc260_parse_auto_config(codec);
7318 if (err < 0) {
7319 alc_free(codec);
7320 return err;
f12ab1e0 7321 } else if (!err) {
9c7f852e
TI
7322 printk(KERN_INFO
7323 "hda_codec: Cannot set up configuration "
7324 "from BIOS. Using base mode...\n");
df694daa
KY
7325 board_config = ALC260_BASIC;
7326 }
a9430dd8 7327 }
e9edcee0 7328
680cd536
KK
7329 err = snd_hda_attach_beep_device(codec, 0x1);
7330 if (err < 0) {
7331 alc_free(codec);
7332 return err;
7333 }
7334
df694daa 7335 if (board_config != ALC260_AUTO)
e9c364c0 7336 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7337
1da177e4
LT
7338 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7339 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7340 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7341
a3bcba38
TI
7342 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7343 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7344
4ef0ef19
TI
7345 if (!spec->adc_nids && spec->input_mux) {
7346 /* check whether NID 0x04 is valid */
7347 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7348 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7349 /* get type */
7350 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7351 spec->adc_nids = alc260_adc_nids_alt;
7352 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7353 } else {
7354 spec->adc_nids = alc260_adc_nids;
7355 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7356 }
7357 }
b59bdf3b 7358 set_capture_mixer(codec);
45bdd1c1 7359 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7360
b5bfbc67 7361 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7362
2134ea4f
TI
7363 spec->vmaster_nid = 0x08;
7364
1da177e4 7365 codec->patch_ops = alc_patch_ops;
df694daa 7366 if (board_config == ALC260_AUTO)
ae6b813a 7367 spec->init_hook = alc260_auto_init;
cb53c626
TI
7368#ifdef CONFIG_SND_HDA_POWER_SAVE
7369 if (!spec->loopback.amplist)
7370 spec->loopback.amplist = alc260_loopbacks;
7371#endif
1da177e4
LT
7372
7373 return 0;
7374}
7375
e9edcee0 7376
1da177e4 7377/*
4953550a 7378 * ALC882/883/885/888/889 support
1da177e4
LT
7379 *
7380 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7381 * configuration. Each pin widget can choose any input DACs and a mixer.
7382 * Each ADC is connected from a mixer of all inputs. This makes possible
7383 * 6-channel independent captures.
7384 *
7385 * In addition, an independent DAC for the multi-playback (not used in this
7386 * driver yet).
7387 */
df694daa
KY
7388#define ALC882_DIGOUT_NID 0x06
7389#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7390#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7391#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7392#define ALC1200_DIGOUT_NID 0x10
7393
1da177e4 7394
d2a6d7dc 7395static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7396 { 8, NULL }
7397};
7398
4953550a 7399/* DACs */
1da177e4
LT
7400static hda_nid_t alc882_dac_nids[4] = {
7401 /* front, rear, clfe, rear_surr */
7402 0x02, 0x03, 0x04, 0x05
7403};
4953550a 7404#define alc883_dac_nids alc882_dac_nids
1da177e4 7405
4953550a 7406/* ADCs */
df694daa
KY
7407#define alc882_adc_nids alc880_adc_nids
7408#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7409#define alc883_adc_nids alc882_adc_nids_alt
7410static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7411static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7412#define alc889_adc_nids alc880_adc_nids
1da177e4 7413
e1406348
TI
7414static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7415static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7416#define alc883_capsrc_nids alc882_capsrc_nids_alt
7417static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7418#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7419
1da177e4
LT
7420/* input MUX */
7421/* FIXME: should be a matrix-type input source selection */
7422
7423static struct hda_input_mux alc882_capture_source = {
7424 .num_items = 4,
7425 .items = {
7426 { "Mic", 0x0 },
7427 { "Front Mic", 0x1 },
7428 { "Line", 0x2 },
7429 { "CD", 0x4 },
7430 },
7431};
41d5545d 7432
4953550a
TI
7433#define alc883_capture_source alc882_capture_source
7434
87a8c370
JK
7435static struct hda_input_mux alc889_capture_source = {
7436 .num_items = 3,
7437 .items = {
7438 { "Front Mic", 0x0 },
7439 { "Mic", 0x3 },
7440 { "Line", 0x2 },
7441 },
7442};
7443
41d5545d
KS
7444static struct hda_input_mux mb5_capture_source = {
7445 .num_items = 3,
7446 .items = {
7447 { "Mic", 0x1 },
b8f171e7 7448 { "Line", 0x7 },
41d5545d
KS
7449 { "CD", 0x4 },
7450 },
7451};
7452
e458b1fa
LY
7453static struct hda_input_mux macmini3_capture_source = {
7454 .num_items = 2,
7455 .items = {
7456 { "Line", 0x2 },
7457 { "CD", 0x4 },
7458 },
7459};
7460
4953550a
TI
7461static struct hda_input_mux alc883_3stack_6ch_intel = {
7462 .num_items = 4,
7463 .items = {
7464 { "Mic", 0x1 },
7465 { "Front Mic", 0x0 },
7466 { "Line", 0x2 },
7467 { "CD", 0x4 },
7468 },
7469};
7470
7471static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7472 .num_items = 2,
7473 .items = {
7474 { "Mic", 0x1 },
7475 { "Line", 0x2 },
7476 },
7477};
7478
7479static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7480 .num_items = 4,
7481 .items = {
7482 { "Mic", 0x0 },
28c4edb7 7483 { "Internal Mic", 0x1 },
4953550a
TI
7484 { "Line", 0x2 },
7485 { "CD", 0x4 },
7486 },
7487};
7488
7489static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7490 .num_items = 2,
7491 .items = {
7492 { "Mic", 0x0 },
28c4edb7 7493 { "Internal Mic", 0x1 },
4953550a
TI
7494 },
7495};
7496
7497static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7498 .num_items = 3,
7499 .items = {
7500 { "Mic", 0x0 },
7501 { "Front Mic", 0x1 },
7502 { "Line", 0x4 },
7503 },
7504};
7505
7506static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7507 .num_items = 2,
7508 .items = {
7509 { "Mic", 0x0 },
7510 { "Line", 0x2 },
7511 },
7512};
7513
7514static struct hda_input_mux alc889A_mb31_capture_source = {
7515 .num_items = 2,
7516 .items = {
7517 { "Mic", 0x0 },
7518 /* Front Mic (0x01) unused */
7519 { "Line", 0x2 },
7520 /* Line 2 (0x03) unused */
af901ca1 7521 /* CD (0x04) unused? */
4953550a
TI
7522 },
7523};
7524
b7cccc52
JM
7525static struct hda_input_mux alc889A_imac91_capture_source = {
7526 .num_items = 2,
7527 .items = {
7528 { "Mic", 0x01 },
7529 { "Line", 0x2 }, /* Not sure! */
7530 },
7531};
7532
4953550a
TI
7533/*
7534 * 2ch mode
7535 */
7536static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7537 { 2, NULL }
7538};
7539
272a527c
KY
7540/*
7541 * 2ch mode
7542 */
7543static struct hda_verb alc882_3ST_ch2_init[] = {
7544 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7545 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7546 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7547 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7548 { } /* end */
7549};
7550
4953550a
TI
7551/*
7552 * 4ch mode
7553 */
7554static struct hda_verb alc882_3ST_ch4_init[] = {
7555 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7556 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7557 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7558 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7559 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7560 { } /* end */
7561};
7562
272a527c
KY
7563/*
7564 * 6ch mode
7565 */
7566static struct hda_verb alc882_3ST_ch6_init[] = {
7567 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7568 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7569 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7570 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7571 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7572 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7573 { } /* end */
7574};
7575
4953550a 7576static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7577 { 2, alc882_3ST_ch2_init },
4953550a 7578 { 4, alc882_3ST_ch4_init },
272a527c
KY
7579 { 6, alc882_3ST_ch6_init },
7580};
7581
4953550a
TI
7582#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7583
a65cc60f 7584/*
7585 * 2ch mode
7586 */
7587static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7588 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7589 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7590 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7591 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7592 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7593 { } /* end */
7594};
7595
7596/*
7597 * 4ch mode
7598 */
7599static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7600 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7601 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7602 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7603 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7604 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7605 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7606 { } /* end */
7607};
7608
7609/*
7610 * 6ch mode
7611 */
7612static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7613 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7614 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7615 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7616 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7617 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7618 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7619 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7620 { } /* end */
7621};
7622
7623static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7624 { 2, alc883_3ST_ch2_clevo_init },
7625 { 4, alc883_3ST_ch4_clevo_init },
7626 { 6, alc883_3ST_ch6_clevo_init },
7627};
7628
7629
df694daa
KY
7630/*
7631 * 6ch mode
7632 */
7633static struct hda_verb alc882_sixstack_ch6_init[] = {
7634 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7635 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7636 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7637 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7638 { } /* end */
7639};
7640
7641/*
7642 * 8ch mode
7643 */
7644static struct hda_verb alc882_sixstack_ch8_init[] = {
7645 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7646 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7647 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7648 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7649 { } /* end */
7650};
7651
7652static struct hda_channel_mode alc882_sixstack_modes[2] = {
7653 { 6, alc882_sixstack_ch6_init },
7654 { 8, alc882_sixstack_ch8_init },
7655};
7656
76e6f5a9
RH
7657
7658/* Macbook Air 2,1 */
7659
7660static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7661 { 2, NULL },
7662};
7663
87350ad0 7664/*
def319f9 7665 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7666 */
7667
7668/*
7669 * 2ch mode
7670 */
7671static struct hda_verb alc885_mbp_ch2_init[] = {
7672 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7673 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7674 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7675 { } /* end */
7676};
7677
7678/*
a3f730af 7679 * 4ch mode
87350ad0 7680 */
a3f730af 7681static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7682 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7683 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7684 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7685 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7686 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7687 { } /* end */
7688};
7689
a3f730af 7690static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7691 { 2, alc885_mbp_ch2_init },
a3f730af 7692 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7693};
7694
92b9de83
KS
7695/*
7696 * 2ch
7697 * Speakers/Woofer/HP = Front
7698 * LineIn = Input
7699 */
7700static struct hda_verb alc885_mb5_ch2_init[] = {
7701 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7702 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7703 { } /* end */
7704};
7705
7706/*
7707 * 6ch mode
7708 * Speakers/HP = Front
7709 * Woofer = LFE
7710 * LineIn = Surround
7711 */
7712static struct hda_verb alc885_mb5_ch6_init[] = {
7713 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7714 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7715 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7716 { } /* end */
7717};
7718
7719static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7720 { 2, alc885_mb5_ch2_init },
7721 { 6, alc885_mb5_ch6_init },
7722};
87350ad0 7723
d01aecdf 7724#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7725
7726/*
7727 * 2ch mode
7728 */
7729static struct hda_verb alc883_4ST_ch2_init[] = {
7730 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7731 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7732 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7733 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7734 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7735 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7736 { } /* end */
7737};
7738
7739/*
7740 * 4ch mode
7741 */
7742static struct hda_verb alc883_4ST_ch4_init[] = {
7743 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7744 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7745 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7746 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7747 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7748 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7749 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7750 { } /* end */
7751};
7752
7753/*
7754 * 6ch mode
7755 */
7756static struct hda_verb alc883_4ST_ch6_init[] = {
7757 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7758 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7759 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7760 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7761 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7762 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7763 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7764 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7765 { } /* end */
7766};
7767
7768/*
7769 * 8ch mode
7770 */
7771static struct hda_verb alc883_4ST_ch8_init[] = {
7772 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7773 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7774 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7775 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7776 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7777 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7778 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7779 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7780 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7781 { } /* end */
7782};
7783
7784static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7785 { 2, alc883_4ST_ch2_init },
7786 { 4, alc883_4ST_ch4_init },
7787 { 6, alc883_4ST_ch6_init },
7788 { 8, alc883_4ST_ch8_init },
7789};
7790
7791
7792/*
7793 * 2ch mode
7794 */
7795static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7796 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7797 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7798 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7799 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7800 { } /* end */
7801};
7802
7803/*
7804 * 4ch mode
7805 */
7806static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7807 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7808 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7809 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7810 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7811 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7812 { } /* end */
7813};
7814
7815/*
7816 * 6ch mode
7817 */
7818static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7819 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7820 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7821 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7822 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7823 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7824 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7825 { } /* end */
7826};
7827
7828static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7829 { 2, alc883_3ST_ch2_intel_init },
7830 { 4, alc883_3ST_ch4_intel_init },
7831 { 6, alc883_3ST_ch6_intel_init },
7832};
7833
dd7714c9
WF
7834/*
7835 * 2ch mode
7836 */
7837static struct hda_verb alc889_ch2_intel_init[] = {
7838 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7839 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7840 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7841 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7842 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7843 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7844 { } /* end */
7845};
7846
87a8c370
JK
7847/*
7848 * 6ch mode
7849 */
7850static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7851 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7852 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7853 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7854 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7855 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7856 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7857 { } /* end */
7858};
7859
7860/*
7861 * 8ch mode
7862 */
7863static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7864 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7865 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7866 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7867 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7868 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7869 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7870 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7871 { } /* end */
7872};
7873
dd7714c9
WF
7874static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7875 { 2, alc889_ch2_intel_init },
87a8c370
JK
7876 { 6, alc889_ch6_intel_init },
7877 { 8, alc889_ch8_intel_init },
7878};
7879
4953550a
TI
7880/*
7881 * 6ch mode
7882 */
7883static struct hda_verb alc883_sixstack_ch6_init[] = {
7884 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7885 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7886 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7887 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7888 { } /* end */
7889};
7890
7891/*
7892 * 8ch mode
7893 */
7894static struct hda_verb alc883_sixstack_ch8_init[] = {
7895 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7896 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7897 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7898 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7899 { } /* end */
7900};
7901
7902static struct hda_channel_mode alc883_sixstack_modes[2] = {
7903 { 6, alc883_sixstack_ch6_init },
7904 { 8, alc883_sixstack_ch8_init },
7905};
7906
7907
1da177e4
LT
7908/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7909 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7910 */
c8b6bf9b 7911static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7912 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7913 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7914 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7915 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7916 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7917 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7918 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7919 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7920 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7921 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7922 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7923 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7924 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7925 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7926 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7927 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 7928 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
7929 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7930 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 7931 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 7932 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7933 { } /* end */
7934};
7935
76e6f5a9
RH
7936/* Macbook Air 2,1 same control for HP and internal Speaker */
7937
7938static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7939 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7940 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7941 { }
7942};
7943
7944
87350ad0 7945static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7946 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7947 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7948 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7949 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7950 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7951 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7952 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7953 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7954 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
7955 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7956 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
7957 { } /* end */
7958};
41d5545d
KS
7959
7960static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7962 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7963 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7964 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7965 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7966 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7967 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7968 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7970 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7972 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
7973 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7974 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
7975 { } /* end */
7976};
92b9de83 7977
e458b1fa
LY
7978static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7980 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7981 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7982 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7983 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7984 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7985 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7986 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7988 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 7989 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
7990 { } /* end */
7991};
7992
4b7e1803 7993static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7994 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7995 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7996 { } /* end */
7997};
7998
7999
bdd148a3
KY
8000static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8001 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8002 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8003 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8004 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8005 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8006 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8007 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8008 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8009 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8010 { } /* end */
8011};
8012
272a527c
KY
8013static struct snd_kcontrol_new alc882_targa_mixer[] = {
8014 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8015 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8016 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8017 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8018 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8019 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8020 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8022 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8023 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8024 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8025 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8026 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8027 { } /* end */
8028};
8029
8030/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8031 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8032 */
8033static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8034 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8035 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8036 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8037 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8038 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8039 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8040 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8041 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8042 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8043 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8046 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8047 { } /* end */
8048};
8049
914759b7
TI
8050static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8051 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8052 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8053 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8054 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8055 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8056 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8057 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8058 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8059 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8060 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8061 { } /* end */
8062};
8063
df694daa
KY
8064static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8065 {
8066 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8067 .name = "Channel Mode",
8068 .info = alc_ch_mode_info,
8069 .get = alc_ch_mode_get,
8070 .put = alc_ch_mode_put,
8071 },
8072 { } /* end */
8073};
8074
4953550a 8075static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8076 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8077 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8078 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8079 /* Rear mixer */
05acb863
TI
8080 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8081 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8082 /* CLFE mixer */
05acb863
TI
8083 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8084 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8085 /* Side mixer */
05acb863
TI
8086 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8087 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8088
e9edcee0 8089 /* Front Pin: output 0 (0x0c) */
05acb863 8090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8091 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8092 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8093 /* Rear Pin: output 1 (0x0d) */
05acb863 8094 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8095 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8096 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8097 /* CLFE Pin: output 2 (0x0e) */
05acb863 8098 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8099 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8100 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8101 /* Side Pin: output 3 (0x0f) */
05acb863 8102 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8103 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8104 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8105 /* Mic (rear) pin: input vref at 80% */
16ded525 8106 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8107 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8108 /* Front Mic pin: input vref at 80% */
16ded525 8109 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8110 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8111 /* Line In pin: input */
05acb863 8112 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8113 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8114 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8115 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8116 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8117 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8118 /* CD pin widget for input */
05acb863 8119 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8120
8121 /* FIXME: use matrix-type input source selection */
8122 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8123 /* Input mixer2 */
05acb863 8124 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8125 /* Input mixer3 */
05acb863 8126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8127 /* ADC2: mute amp left and right */
8128 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8129 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8130 /* ADC3: mute amp left and right */
8131 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8132 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8133
8134 { }
8135};
8136
4953550a
TI
8137static struct hda_verb alc882_adc1_init_verbs[] = {
8138 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8139 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8140 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8141 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8142 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8143 /* ADC1: mute amp left and right */
8144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8145 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8146 { }
8147};
8148
4b146cb0
TI
8149static struct hda_verb alc882_eapd_verbs[] = {
8150 /* change to EAPD mode */
8151 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8152 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8153 { }
4b146cb0
TI
8154};
8155
87a8c370
JK
8156static struct hda_verb alc889_eapd_verbs[] = {
8157 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8158 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8159 { }
8160};
8161
6732bd0d
WF
8162static struct hda_verb alc_hp15_unsol_verbs[] = {
8163 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8165 {}
8166};
87a8c370
JK
8167
8168static struct hda_verb alc885_init_verbs[] = {
8169 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8170 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8171 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8172 /* Rear mixer */
88102f3f
KY
8173 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8174 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8175 /* CLFE mixer */
88102f3f
KY
8176 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8177 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8178 /* Side mixer */
88102f3f
KY
8179 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8180 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8181
8182 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8183 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8184 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8185 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8186 /* Front Pin: output 0 (0x0c) */
8187 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8188 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8189 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8190 /* Rear Pin: output 1 (0x0d) */
8191 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8192 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8193 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8194 /* CLFE Pin: output 2 (0x0e) */
8195 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8196 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8197 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8198 /* Side Pin: output 3 (0x0f) */
8199 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8200 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8201 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8202 /* Mic (rear) pin: input vref at 80% */
8203 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8204 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8205 /* Front Mic pin: input vref at 80% */
8206 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8207 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8208 /* Line In pin: input */
8209 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8210 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8211
8212 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8213 /* Input mixer1 */
88102f3f 8214 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8215 /* Input mixer2 */
8216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8217 /* Input mixer3 */
88102f3f 8218 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8219 /* ADC2: mute amp left and right */
8220 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8221 /* ADC3: mute amp left and right */
8222 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8223
8224 { }
8225};
8226
8227static struct hda_verb alc885_init_input_verbs[] = {
8228 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8229 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8230 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8231 { }
8232};
8233
8234
8235/* Unmute Selector 24h and set the default input to front mic */
8236static struct hda_verb alc889_init_input_verbs[] = {
8237 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8238 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8239 { }
8240};
8241
8242
4953550a
TI
8243#define alc883_init_verbs alc882_base_init_verbs
8244
9102cd1c
TD
8245/* Mac Pro test */
8246static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8247 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8248 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8249 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8250 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8251 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8252 /* FIXME: this looks suspicious...
d355c82a
JK
8253 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8254 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8255 */
9102cd1c
TD
8256 { } /* end */
8257};
8258
8259static struct hda_verb alc882_macpro_init_verbs[] = {
8260 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8261 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8264 /* Front Pin: output 0 (0x0c) */
8265 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8266 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8268 /* Front Mic pin: input vref at 80% */
8269 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8270 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8271 /* Speaker: output */
8272 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8273 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8274 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8275 /* Headphone output (output 0 - 0x0c) */
8276 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8277 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8278 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8279
8280 /* FIXME: use matrix-type input source selection */
8281 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8282 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8284 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8285 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8286 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8287 /* Input mixer2 */
8288 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8289 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8290 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8291 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8292 /* Input mixer3 */
8293 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8294 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8295 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8296 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8297 /* ADC1: mute amp left and right */
8298 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8299 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8300 /* ADC2: mute amp left and right */
8301 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8302 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8303 /* ADC3: mute amp left and right */
8304 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8305 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8306
8307 { }
8308};
f12ab1e0 8309
41d5545d
KS
8310/* Macbook 5,1 */
8311static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8312 /* DACs */
8313 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8314 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8315 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8316 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8317 /* Front mixer */
41d5545d
KS
8318 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8319 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8320 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8321 /* Surround mixer */
8322 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8323 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8324 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8325 /* LFE mixer */
8326 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8327 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8328 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8329 /* HP mixer */
8330 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8331 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8332 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8333 /* Front Pin (0x0c) */
41d5545d
KS
8334 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8335 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8336 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8337 /* LFE Pin (0x0e) */
8338 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8339 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8340 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8341 /* HP Pin (0x0f) */
41d5545d
KS
8342 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8343 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8344 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8345 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8346 /* Front Mic pin: input vref at 80% */
8347 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8348 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8349 /* Line In pin */
8350 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8351 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8352
b8f171e7
AM
8353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8356 { }
8357};
8358
e458b1fa
LY
8359/* Macmini 3,1 */
8360static struct hda_verb alc885_macmini3_init_verbs[] = {
8361 /* DACs */
8362 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8363 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8364 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8365 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8366 /* Front mixer */
8367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8370 /* Surround mixer */
8371 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8372 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8374 /* LFE mixer */
8375 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8378 /* HP mixer */
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8381 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8382 /* Front Pin (0x0c) */
8383 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8384 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8386 /* LFE Pin (0x0e) */
8387 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8388 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8389 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8390 /* HP Pin (0x0f) */
8391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8392 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8393 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8394 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8395 /* Line In pin */
8396 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8397 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8398
8399 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8400 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8401 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8403 { }
8404};
8405
76e6f5a9
RH
8406
8407static struct hda_verb alc885_mba21_init_verbs[] = {
8408 /*Internal and HP Speaker Mixer*/
8409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8412 /*Internal Speaker Pin (0x0c)*/
8413 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8414 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8415 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8416 /* HP Pin: output 0 (0x0e) */
8417 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8418 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8419 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8420 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8421 /* Line in (is hp when jack connected)*/
8422 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8423 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8424
8425 { }
8426 };
8427
8428
87350ad0
TI
8429/* Macbook Pro rev3 */
8430static struct hda_verb alc885_mbp3_init_verbs[] = {
8431 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8433 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8435 /* Rear mixer */
8436 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8437 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8439 /* HP mixer */
8440 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8441 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8442 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8443 /* Front Pin: output 0 (0x0c) */
8444 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8445 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8446 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8447 /* HP Pin: output 0 (0x0e) */
87350ad0 8448 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8449 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8450 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8451 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8452 /* Mic (rear) pin: input vref at 80% */
8453 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8454 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8455 /* Front Mic pin: input vref at 80% */
8456 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8457 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8458 /* Line In pin: use output 1 when in LineOut mode */
8459 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8460 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8461 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8462
8463 /* FIXME: use matrix-type input source selection */
8464 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8465 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8466 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8467 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8468 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8469 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8470 /* Input mixer2 */
8471 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8472 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8473 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8475 /* Input mixer3 */
8476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8477 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8480 /* ADC1: mute amp left and right */
8481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8482 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 /* ADC2: mute amp left and right */
8484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8485 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8486 /* ADC3: mute amp left and right */
8487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8488 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8489
8490 { }
8491};
8492
4b7e1803
JM
8493/* iMac 9,1 */
8494static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8495 /* Internal Speaker Pin (0x0c) */
8496 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8497 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8498 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8499 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8500 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8501 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8502 /* HP Pin: Rear */
4b7e1803
JM
8503 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8504 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8505 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8506 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8507 /* Line in Rear */
8508 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8509 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8510 /* Front Mic pin: input vref at 80% */
8511 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8513 /* Rear mixer */
8514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8515 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8516 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8517 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8521 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8525 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8526 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8531 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8536 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8538 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8539 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8540 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8541 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8542 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8543 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8544 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8545 { }
8546};
8547
c54728d8
NF
8548/* iMac 24 mixer. */
8549static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8550 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8551 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8552 { } /* end */
8553};
8554
8555/* iMac 24 init verbs. */
8556static struct hda_verb alc885_imac24_init_verbs[] = {
8557 /* Internal speakers: output 0 (0x0c) */
8558 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8559 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8561 /* Internal speakers: output 0 (0x0c) */
8562 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8563 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8564 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8565 /* Headphone: output 0 (0x0c) */
8566 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8567 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8568 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8569 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8570 /* Front Mic: input vref at 80% */
8571 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8572 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8573 { }
8574};
8575
8576/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8577static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8578{
a9fd4f3f 8579 struct alc_spec *spec = codec->spec;
c54728d8 8580
a9fd4f3f
TI
8581 spec->autocfg.hp_pins[0] = 0x14;
8582 spec->autocfg.speaker_pins[0] = 0x18;
8583 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8584}
8585
9d54f08b
TI
8586#define alc885_mb5_setup alc885_imac24_setup
8587#define alc885_macmini3_setup alc885_imac24_setup
8588
76e6f5a9
RH
8589/* Macbook Air 2,1 */
8590static void alc885_mba21_setup(struct hda_codec *codec)
8591{
8592 struct alc_spec *spec = codec->spec;
8593
8594 spec->autocfg.hp_pins[0] = 0x14;
8595 spec->autocfg.speaker_pins[0] = 0x18;
8596}
8597
8598
8599
4f5d1706 8600static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8601{
a9fd4f3f 8602 struct alc_spec *spec = codec->spec;
87350ad0 8603
a9fd4f3f
TI
8604 spec->autocfg.hp_pins[0] = 0x15;
8605 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8606}
8607
9d54f08b 8608static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8609{
9d54f08b 8610 struct alc_spec *spec = codec->spec;
4b7e1803 8611
9d54f08b 8612 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8613 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8614 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8615}
87350ad0 8616
272a527c
KY
8617static struct hda_verb alc882_targa_verbs[] = {
8618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8619 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8620
8621 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8622 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8623
272a527c
KY
8624 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8625 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8626 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8627
8628 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8629 { } /* end */
8630};
8631
8632/* toggle speaker-output according to the hp-jack state */
8633static void alc882_targa_automute(struct hda_codec *codec)
8634{
a9fd4f3f
TI
8635 struct alc_spec *spec = codec->spec;
8636 alc_automute_amp(codec);
82beb8fd 8637 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8638 spec->jack_present ? 1 : 3);
8639}
8640
4f5d1706 8641static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8642{
8643 struct alc_spec *spec = codec->spec;
8644
8645 spec->autocfg.hp_pins[0] = 0x14;
8646 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8647}
8648
8649static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8650{
a9fd4f3f 8651 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8652 alc882_targa_automute(codec);
272a527c
KY
8653}
8654
8655static struct hda_verb alc882_asus_a7j_verbs[] = {
8656 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8658
8659 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8660 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8661 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8662
272a527c
KY
8663 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8664 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8665 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8666
8667 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8668 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8669 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8670 { } /* end */
8671};
8672
914759b7
TI
8673static struct hda_verb alc882_asus_a7m_verbs[] = {
8674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8675 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8676
8677 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8679 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8680
914759b7
TI
8681 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8682 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8683 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8684
8685 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8686 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8687 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8688 { } /* end */
8689};
8690
9102cd1c
TD
8691static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8692{
8693 unsigned int gpiostate, gpiomask, gpiodir;
8694
8695 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8696 AC_VERB_GET_GPIO_DATA, 0);
8697
8698 if (!muted)
8699 gpiostate |= (1 << pin);
8700 else
8701 gpiostate &= ~(1 << pin);
8702
8703 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8704 AC_VERB_GET_GPIO_MASK, 0);
8705 gpiomask |= (1 << pin);
8706
8707 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8708 AC_VERB_GET_GPIO_DIRECTION, 0);
8709 gpiodir |= (1 << pin);
8710
8711
8712 snd_hda_codec_write(codec, codec->afg, 0,
8713 AC_VERB_SET_GPIO_MASK, gpiomask);
8714 snd_hda_codec_write(codec, codec->afg, 0,
8715 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8716
8717 msleep(1);
8718
8719 snd_hda_codec_write(codec, codec->afg, 0,
8720 AC_VERB_SET_GPIO_DATA, gpiostate);
8721}
8722
7debbe51
TI
8723/* set up GPIO at initialization */
8724static void alc885_macpro_init_hook(struct hda_codec *codec)
8725{
8726 alc882_gpio_mute(codec, 0, 0);
8727 alc882_gpio_mute(codec, 1, 0);
8728}
8729
8730/* set up GPIO and update auto-muting at initialization */
8731static void alc885_imac24_init_hook(struct hda_codec *codec)
8732{
8733 alc885_macpro_init_hook(codec);
4f5d1706 8734 alc_automute_amp(codec);
7debbe51
TI
8735}
8736
df694daa
KY
8737/*
8738 * generic initialization of ADC, input mixers and output mixers
8739 */
4953550a 8740static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8741 /*
8742 * Unmute ADC0-2 and set the default input to mic-in
8743 */
4953550a
TI
8744 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8745 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8746 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8747 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8748
4953550a
TI
8749 /*
8750 * Set up output mixers (0x0c - 0x0f)
8751 */
8752 /* set vol=0 to output mixers */
8753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8754 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8755 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8756 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8757 /* set up input amps for analog loopback */
8758 /* Amp Indices: DAC = 0, mixer = 1 */
8759 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8760 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8761 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8762 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8763 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8764 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8765 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8766 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8767 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8768 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8769
4953550a
TI
8770 /* FIXME: use matrix-type input source selection */
8771 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8772 /* Input mixer2 */
88102f3f 8773 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8774 /* Input mixer3 */
88102f3f 8775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8776 { }
9c7f852e
TI
8777};
8778
eb4c41d3
TS
8779/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8780static struct hda_verb alc889A_mb31_ch2_init[] = {
8781 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8782 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8783 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8784 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8785 { } /* end */
8786};
8787
8788/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8789static struct hda_verb alc889A_mb31_ch4_init[] = {
8790 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8791 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8792 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8793 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8794 { } /* end */
8795};
8796
8797/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8798static struct hda_verb alc889A_mb31_ch5_init[] = {
8799 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8800 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8801 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8802 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8803 { } /* end */
8804};
8805
8806/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8807static struct hda_verb alc889A_mb31_ch6_init[] = {
8808 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8809 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8810 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8811 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8812 { } /* end */
8813};
8814
8815static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8816 { 2, alc889A_mb31_ch2_init },
8817 { 4, alc889A_mb31_ch4_init },
8818 { 5, alc889A_mb31_ch5_init },
8819 { 6, alc889A_mb31_ch6_init },
8820};
8821
b373bdeb
AN
8822static struct hda_verb alc883_medion_eapd_verbs[] = {
8823 /* eanable EAPD on medion laptop */
8824 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8825 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8826 { }
8827};
8828
4953550a 8829#define alc883_base_mixer alc882_base_mixer
834be88d 8830
a8848bd6
AS
8831static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8832 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8833 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8834 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8835 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8836 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8837 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8838 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8839 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8840 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8842 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8843 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8844 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8845 { } /* end */
8846};
8847
0c4cc443 8848static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8849 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8850 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8851 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8852 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8854 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8856 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8857 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8858 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8859 { } /* end */
8860};
8861
fb97dc67
J
8862static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8863 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8864 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8865 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8866 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8867 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8868 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8869 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8870 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8871 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8872 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8873 { } /* end */
8874};
8875
9c7f852e
TI
8876static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8877 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8878 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8879 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8880 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8881 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8882 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8883 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8884 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8885 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8886 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8887 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8888 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8889 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8890 { } /* end */
8891};
df694daa 8892
9c7f852e
TI
8893static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8894 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8895 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8896 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8897 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8898 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8899 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8900 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8901 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8902 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8903 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8904 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8905 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8906 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8907 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8908 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8909 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8910 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8911 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8912 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8913 { } /* end */
8914};
8915
17bba1b7
J
8916static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8917 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8918 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8919 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8920 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8921 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8922 HDA_OUTPUT),
8923 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8924 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8925 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8926 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8927 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8928 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8929 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8930 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8931 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8932 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
8933 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8935 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 8936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8937 { } /* end */
8938};
8939
87a8c370
JK
8940static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8941 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8942 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8943 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8944 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8945 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8946 HDA_OUTPUT),
8947 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8948 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8949 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8950 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8951 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8952 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8953 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8954 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8955 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 8956 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
8957 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8958 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8959 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
8960 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8961 { } /* end */
8962};
8963
d1d985f0 8964static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8965 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8966 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8967 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8968 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8969 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8970 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8971 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8972 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8973 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8974 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8975 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8977 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8978 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8979 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
8980 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8981 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8982 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 8983 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8984 { } /* end */
8985};
8986
c259249f 8987static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8988 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8989 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8990 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8991 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8992 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8993 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8994 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8995 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8996 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8997 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8998 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8999 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9000 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9001 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9002 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9003 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9004 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9005 { } /* end */
f12ab1e0 9006};
ccc656ce 9007
c259249f 9008static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9009 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9010 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9012 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9013 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9014 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9016 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9017 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9018 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9019 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9020 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9021 { } /* end */
f12ab1e0 9022};
ccc656ce 9023
b99dba34
TI
9024static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9025 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9026 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9027 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9028 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9029 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9030 { } /* end */
9031};
9032
bc9f98a9
KY
9033static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9034 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9035 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9036 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9037 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9038 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9039 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9040 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9041 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9042 { } /* end */
f12ab1e0 9043};
bc9f98a9 9044
272a527c
KY
9045static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9046 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9047 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9048 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9049 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9050 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9052 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9053 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9054 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9055 { } /* end */
ea1fb29a 9056};
272a527c 9057
7ad7b218
MC
9058static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9059 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9060 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9061 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9062 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9063 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9064 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9065 { } /* end */
9066};
9067
9068static struct hda_verb alc883_medion_wim2160_verbs[] = {
9069 /* Unmute front mixer */
9070 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9071 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9072
9073 /* Set speaker pin to front mixer */
9074 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9075
9076 /* Init headphone pin */
9077 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9078 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9079 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9080 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9081
9082 { } /* end */
9083};
9084
9085/* toggle speaker-output according to the hp-jack state */
9086static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9087{
9088 struct alc_spec *spec = codec->spec;
9089
9090 spec->autocfg.hp_pins[0] = 0x1a;
9091 spec->autocfg.speaker_pins[0] = 0x15;
9092}
9093
2880a867 9094static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9095 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9096 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9097 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9098 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9101 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9103 { } /* end */
d1a991a6 9104};
2880a867 9105
d2fd4b09
TV
9106static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9107 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9108 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9111 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9112 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9114 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9116 { } /* end */
9117};
9118
e2757d5e
KY
9119static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9120 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9121 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9122 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9123 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9124 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9125 0x0d, 1, 0x0, HDA_OUTPUT),
9126 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9127 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9128 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9129 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9130 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9131 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9132 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9133 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9134 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9135 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9136 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9138 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9139 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9140 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9141 { } /* end */
9142};
9143
eb4c41d3
TS
9144static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9145 /* Output mixers */
9146 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9147 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9148 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9149 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9150 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9151 HDA_OUTPUT),
9152 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9153 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9154 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9155 /* Output switches */
9156 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9157 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9158 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9159 /* Boost mixers */
5f99f86a
DH
9160 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9161 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9162 /* Input mixers */
9163 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9164 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9165 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9166 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9167 { } /* end */
9168};
9169
3e1647c5
GG
9170static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9171 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9172 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9173 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9175 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9176 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9177 { } /* end */
9178};
9179
e2757d5e
KY
9180static struct hda_bind_ctls alc883_bind_cap_vol = {
9181 .ops = &snd_hda_bind_vol,
9182 .values = {
9183 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9184 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9185 0
9186 },
9187};
9188
9189static struct hda_bind_ctls alc883_bind_cap_switch = {
9190 .ops = &snd_hda_bind_sw,
9191 .values = {
9192 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9193 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9194 0
9195 },
9196};
9197
9198static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9199 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9200 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9201 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9202 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9203 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9204 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9205 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9206 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9207 { } /* end */
9208};
df694daa 9209
4953550a
TI
9210static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9211 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9212 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9213 {
9214 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9215 /* .name = "Capture Source", */
9216 .name = "Input Source",
9217 .count = 1,
9218 .info = alc_mux_enum_info,
9219 .get = alc_mux_enum_get,
9220 .put = alc_mux_enum_put,
9221 },
9222 { } /* end */
9223};
9c7f852e 9224
4953550a
TI
9225static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9226 {
9227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9228 .name = "Channel Mode",
9229 .info = alc_ch_mode_info,
9230 .get = alc_ch_mode_get,
9231 .put = alc_ch_mode_put,
9232 },
9233 { } /* end */
9c7f852e
TI
9234};
9235
a8848bd6 9236/* toggle speaker-output according to the hp-jack state */
4f5d1706 9237static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9238{
a9fd4f3f 9239 struct alc_spec *spec = codec->spec;
a8848bd6 9240
a9fd4f3f
TI
9241 spec->autocfg.hp_pins[0] = 0x15;
9242 spec->autocfg.speaker_pins[0] = 0x14;
9243 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9244}
9245
a8848bd6
AS
9246static struct hda_verb alc883_mitac_verbs[] = {
9247 /* HP */
9248 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9249 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9250 /* Subwoofer */
9251 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9252 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9253
9254 /* enable unsolicited event */
9255 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9256 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9257
9258 { } /* end */
9259};
9260
a65cc60f 9261static struct hda_verb alc883_clevo_m540r_verbs[] = {
9262 /* HP */
9263 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9264 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9265 /* Int speaker */
9266 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9267
9268 /* enable unsolicited event */
9269 /*
9270 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9271 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9272 */
9273
9274 { } /* end */
9275};
9276
0c4cc443 9277static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9278 /* HP */
9279 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9280 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9281 /* Int speaker */
9282 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9283 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9284
9285 /* enable unsolicited event */
9286 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9287 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9288
9289 { } /* end */
9290};
9291
fb97dc67
J
9292static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9293 /* HP */
9294 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9295 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9296 /* Subwoofer */
9297 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9298 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9299
9300 /* enable unsolicited event */
9301 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9302
9303 { } /* end */
9304};
9305
c259249f 9306static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9307 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9308 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9309
9310 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9311 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9312
64a8be74
DH
9313/* Connect Line-Out side jack (SPDIF) to Side */
9314 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9315 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9316 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9317/* Connect Mic jack to CLFE */
9318 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9319 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9320 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9321/* Connect Line-in jack to Surround */
9322 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9323 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9324 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9325/* Connect HP out jack to Front */
9326 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9327 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9328 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9329
9330 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9331
9332 { } /* end */
9333};
9334
bc9f98a9
KY
9335static struct hda_verb alc883_lenovo_101e_verbs[] = {
9336 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9337 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9338 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9339 { } /* end */
9340};
9341
272a527c
KY
9342static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9343 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9344 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9345 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9346 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9347 { } /* end */
9348};
9349
9350static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9353 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9354 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9355 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9356 { } /* end */
9357};
9358
189609ae
KY
9359static struct hda_verb alc883_haier_w66_verbs[] = {
9360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9362
9363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9364
9365 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9366 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9367 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9368 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9369 { } /* end */
9370};
9371
e2757d5e
KY
9372static struct hda_verb alc888_lenovo_sky_verbs[] = {
9373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9374 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9375 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9377 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9378 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9379 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9380 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9381 { } /* end */
9382};
9383
8718b700
HRK
9384static struct hda_verb alc888_6st_dell_verbs[] = {
9385 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9386 { }
9387};
9388
3e1647c5
GG
9389static struct hda_verb alc883_vaiott_verbs[] = {
9390 /* HP */
9391 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9392 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9393
9394 /* enable unsolicited event */
9395 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9396
9397 { } /* end */
9398};
9399
4f5d1706 9400static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9401{
a9fd4f3f 9402 struct alc_spec *spec = codec->spec;
8718b700 9403
a9fd4f3f
TI
9404 spec->autocfg.hp_pins[0] = 0x1b;
9405 spec->autocfg.speaker_pins[0] = 0x14;
9406 spec->autocfg.speaker_pins[1] = 0x16;
9407 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9408}
9409
4723c022 9410static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9411 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9412 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9413 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9414 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9415 { } /* end */
5795b9e6
CM
9416};
9417
3ea0d7cf
HRK
9418/*
9419 * 2ch mode
9420 */
4723c022 9421static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9422 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9423 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9424 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9425 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9426 { } /* end */
8341de60
CM
9427};
9428
3ea0d7cf
HRK
9429/*
9430 * 4ch mode
9431 */
9432static struct hda_verb alc888_3st_hp_4ch_init[] = {
9433 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9434 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9435 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9436 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9437 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9438 { } /* end */
9439};
9440
9441/*
9442 * 6ch mode
9443 */
4723c022 9444static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9445 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9446 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9447 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9448 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9449 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9450 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9451 { } /* end */
8341de60
CM
9452};
9453
3ea0d7cf 9454static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9455 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9456 { 4, alc888_3st_hp_4ch_init },
4723c022 9457 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9458};
9459
272a527c
KY
9460/* toggle front-jack and RCA according to the hp-jack state */
9461static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9462{
864f92be 9463 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9464
47fd830a
TI
9465 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9466 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9467 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9468 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9469}
9470
9471/* toggle RCA according to the front-jack state */
9472static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9473{
864f92be 9474 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9475
47fd830a
TI
9476 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9477 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9478}
47fd830a 9479
272a527c
KY
9480static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9481 unsigned int res)
9482{
9483 if ((res >> 26) == ALC880_HP_EVENT)
9484 alc888_lenovo_ms7195_front_automute(codec);
9485 if ((res >> 26) == ALC880_FRONT_EVENT)
9486 alc888_lenovo_ms7195_rca_automute(codec);
9487}
9488
272a527c 9489/* toggle speaker-output according to the hp-jack state */
dc427170 9490static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9491{
a9fd4f3f 9492 struct alc_spec *spec = codec->spec;
272a527c 9493
a9fd4f3f
TI
9494 spec->autocfg.hp_pins[0] = 0x14;
9495 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9496}
9497
ccc656ce 9498/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9499#define alc883_targa_init_hook alc882_targa_init_hook
9500#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9501
4f5d1706 9502static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9503{
a9fd4f3f
TI
9504 struct alc_spec *spec = codec->spec;
9505
9506 spec->autocfg.hp_pins[0] = 0x15;
9507 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9508}
9509
9510static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9511{
a9fd4f3f 9512 alc_automute_amp(codec);
eeb43387 9513 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9514}
9515
9516static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9517 unsigned int res)
9518{
0c4cc443 9519 switch (res >> 26) {
0c4cc443 9520 case ALC880_MIC_EVENT:
eeb43387 9521 alc88x_simple_mic_automute(codec);
0c4cc443 9522 break;
a9fd4f3f
TI
9523 default:
9524 alc_automute_amp_unsol_event(codec, res);
9525 break;
0c4cc443 9526 }
368c7a95
J
9527}
9528
fb97dc67 9529/* toggle speaker-output according to the hp-jack state */
4f5d1706 9530static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9531{
a9fd4f3f 9532 struct alc_spec *spec = codec->spec;
fb97dc67 9533
a9fd4f3f
TI
9534 spec->autocfg.hp_pins[0] = 0x14;
9535 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9536}
9537
4f5d1706 9538static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9539{
a9fd4f3f 9540 struct alc_spec *spec = codec->spec;
189609ae 9541
a9fd4f3f
TI
9542 spec->autocfg.hp_pins[0] = 0x1b;
9543 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9544}
9545
bc9f98a9
KY
9546static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9547{
864f92be 9548 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9549
47fd830a
TI
9550 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9551 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9552}
9553
9554static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9555{
864f92be 9556 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9557
47fd830a
TI
9558 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9559 HDA_AMP_MUTE, bits);
9560 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9561 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9562}
9563
9564static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9565 unsigned int res)
9566{
9567 if ((res >> 26) == ALC880_HP_EVENT)
9568 alc883_lenovo_101e_all_automute(codec);
9569 if ((res >> 26) == ALC880_FRONT_EVENT)
9570 alc883_lenovo_101e_ispeaker_automute(codec);
9571}
9572
676a9b53 9573/* toggle speaker-output according to the hp-jack state */
4f5d1706 9574static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9575{
a9fd4f3f 9576 struct alc_spec *spec = codec->spec;
676a9b53 9577
a9fd4f3f
TI
9578 spec->autocfg.hp_pins[0] = 0x14;
9579 spec->autocfg.speaker_pins[0] = 0x15;
9580 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9581}
9582
d1a991a6
KY
9583static struct hda_verb alc883_acer_eapd_verbs[] = {
9584 /* HP Pin: output 0 (0x0c) */
9585 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9587 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9588 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9590 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9591 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9592 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9593 /* eanable EAPD on medion laptop */
9594 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9595 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9596 /* enable unsolicited event */
9597 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9598 { }
9599};
9600
4f5d1706 9601static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9602{
a9fd4f3f 9603 struct alc_spec *spec = codec->spec;
5795b9e6 9604
a9fd4f3f
TI
9605 spec->autocfg.hp_pins[0] = 0x1b;
9606 spec->autocfg.speaker_pins[0] = 0x14;
9607 spec->autocfg.speaker_pins[1] = 0x15;
9608 spec->autocfg.speaker_pins[2] = 0x16;
9609 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9610}
9611
4f5d1706 9612static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9613{
a9fd4f3f 9614 struct alc_spec *spec = codec->spec;
e2757d5e 9615
a9fd4f3f
TI
9616 spec->autocfg.hp_pins[0] = 0x1b;
9617 spec->autocfg.speaker_pins[0] = 0x14;
9618 spec->autocfg.speaker_pins[1] = 0x15;
9619 spec->autocfg.speaker_pins[2] = 0x16;
9620 spec->autocfg.speaker_pins[3] = 0x17;
9621 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9622}
9623
4f5d1706 9624static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9625{
9626 struct alc_spec *spec = codec->spec;
9627
9628 spec->autocfg.hp_pins[0] = 0x15;
9629 spec->autocfg.speaker_pins[0] = 0x14;
9630 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9631}
9632
e2757d5e
KY
9633static struct hda_verb alc888_asus_m90v_verbs[] = {
9634 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9635 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9636 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9637 /* enable unsolicited event */
9638 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9639 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9640 { } /* end */
9641};
9642
4f5d1706 9643static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9644{
a9fd4f3f 9645 struct alc_spec *spec = codec->spec;
e2757d5e 9646
a9fd4f3f
TI
9647 spec->autocfg.hp_pins[0] = 0x1b;
9648 spec->autocfg.speaker_pins[0] = 0x14;
9649 spec->autocfg.speaker_pins[1] = 0x15;
9650 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9651 spec->ext_mic.pin = 0x18;
9652 spec->int_mic.pin = 0x19;
9653 spec->ext_mic.mux_idx = 0;
9654 spec->int_mic.mux_idx = 1;
9655 spec->auto_mic = 1;
e2757d5e
KY
9656}
9657
9658static struct hda_verb alc888_asus_eee1601_verbs[] = {
9659 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9660 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9661 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9662 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9663 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9664 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9665 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9666 /* enable unsolicited event */
9667 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9668 { } /* end */
9669};
9670
e2757d5e
KY
9671static void alc883_eee1601_inithook(struct hda_codec *codec)
9672{
a9fd4f3f
TI
9673 struct alc_spec *spec = codec->spec;
9674
9675 spec->autocfg.hp_pins[0] = 0x14;
9676 spec->autocfg.speaker_pins[0] = 0x1b;
9677 alc_automute_pin(codec);
e2757d5e
KY
9678}
9679
eb4c41d3
TS
9680static struct hda_verb alc889A_mb31_verbs[] = {
9681 /* Init rear pin (used as headphone output) */
9682 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9683 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9684 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9685 /* Init line pin (used as output in 4ch and 6ch mode) */
9686 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9687 /* Init line 2 pin (used as headphone out by default) */
9688 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9689 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9690 { } /* end */
9691};
9692
9693/* Mute speakers according to the headphone jack state */
9694static void alc889A_mb31_automute(struct hda_codec *codec)
9695{
9696 unsigned int present;
9697
9698 /* Mute only in 2ch or 4ch mode */
9699 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9700 == 0x00) {
864f92be 9701 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9702 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9703 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9704 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9705 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9706 }
9707}
9708
9709static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9710{
9711 if ((res >> 26) == ALC880_HP_EVENT)
9712 alc889A_mb31_automute(codec);
9713}
9714
4953550a 9715
cb53c626 9716#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9717#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9718#endif
9719
def319f9 9720/* pcm configuration: identical with ALC880 */
4953550a
TI
9721#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9722#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9723#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9724#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9725
9726static hda_nid_t alc883_slave_dig_outs[] = {
9727 ALC1200_DIGOUT_NID, 0,
9728};
9729
9730static hda_nid_t alc1200_slave_dig_outs[] = {
9731 ALC883_DIGOUT_NID, 0,
9732};
9c7f852e
TI
9733
9734/*
9735 * configuration and preset
9736 */
ea734963 9737static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9738 [ALC882_3ST_DIG] = "3stack-dig",
9739 [ALC882_6ST_DIG] = "6stack-dig",
9740 [ALC882_ARIMA] = "arima",
9741 [ALC882_W2JC] = "w2jc",
9742 [ALC882_TARGA] = "targa",
9743 [ALC882_ASUS_A7J] = "asus-a7j",
9744 [ALC882_ASUS_A7M] = "asus-a7m",
9745 [ALC885_MACPRO] = "macpro",
9746 [ALC885_MB5] = "mb5",
e458b1fa 9747 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9748 [ALC885_MBA21] = "mba21",
4953550a
TI
9749 [ALC885_MBP3] = "mbp3",
9750 [ALC885_IMAC24] = "imac24",
4b7e1803 9751 [ALC885_IMAC91] = "imac91",
4953550a 9752 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9753 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9754 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9755 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9756 [ALC883_TARGA_DIG] = "targa-dig",
9757 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9758 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9759 [ALC883_ACER] = "acer",
2880a867 9760 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9761 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9762 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9763 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9764 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9765 [ALC883_MEDION] = "medion",
7ad7b218 9766 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9767 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9768 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9769 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9770 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9771 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9772 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9773 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9774 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9775 [ALC883_MITAC] = "mitac",
a65cc60f 9776 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9777 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9778 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9779 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9780 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9781 [ALC889A_INTEL] = "intel-alc889a",
9782 [ALC889_INTEL] = "intel-x58",
3ab90935 9783 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9784 [ALC889A_MB31] = "mb31",
3e1647c5 9785 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9786 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9787};
9788
4953550a
TI
9789static struct snd_pci_quirk alc882_cfg_tbl[] = {
9790 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9791
ac3e3741 9792 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9793 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9794 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9795 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9796 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9797 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9798 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9799 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9800 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9801 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9802 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9803 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9804 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9805 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9806 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9807 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9808 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9809 ALC888_ACER_ASPIRE_6530G),
cc374c47 9810 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9811 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9812 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9813 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9814 /* default Acer -- disabled as it causes more problems.
9815 * model=auto should work fine now
9816 */
9817 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9818
5795b9e6 9819 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9820
febe3375 9821 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9822 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9823 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9824 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9825 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9826 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9827
9828 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9829 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9830 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9831 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9832 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9833 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9834 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9835 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9836 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9837 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9838 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9839
9840 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9841 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9842 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9843 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9844 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9845 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9846 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9847 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9848 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9849
6f3bf657 9850 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9851 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9852 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9853 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9854 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9855 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9856 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9857 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9858 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9859 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9860 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9861 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9862 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9863 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9864 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9865 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9866 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9867 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9868 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9869 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9870 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9871 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9872 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9873 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9874 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9875 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9876 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9877 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9878 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9879 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9880 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9881
ac3e3741 9882 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9883 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9884 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9885 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9886 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9887 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9888 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9889 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9890 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9891 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9892 ALC883_FUJITSU_PI2515),
bfb53037 9893 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9894 ALC888_FUJITSU_XA3530),
272a527c 9895 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9896 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9897 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9898 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9899 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9900 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9901 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9902 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9903
17bba1b7
J
9904 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9905 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9906 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9907 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9908 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9909 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9910 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9911
4953550a 9912 {}
f3cd3f5d
WF
9913};
9914
4953550a
TI
9915/* codec SSID table for Intel Mac */
9916static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9917 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9918 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9919 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9920 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9921 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9922 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9923 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9924 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9925 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9926 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9927 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9928 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9929 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9930 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9931 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9932 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9933 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9934 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9935 * so apparently no perfect solution yet
4953550a
TI
9936 */
9937 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9938 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9939 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9940 {} /* terminator */
b25c9da1
WF
9941};
9942
4953550a
TI
9943static struct alc_config_preset alc882_presets[] = {
9944 [ALC882_3ST_DIG] = {
9945 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9946 .init_verbs = { alc882_base_init_verbs,
9947 alc882_adc1_init_verbs },
4953550a
TI
9948 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9949 .dac_nids = alc882_dac_nids,
9950 .dig_out_nid = ALC882_DIGOUT_NID,
9951 .dig_in_nid = ALC882_DIGIN_NID,
9952 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9953 .channel_mode = alc882_ch_modes,
9954 .need_dac_fix = 1,
9955 .input_mux = &alc882_capture_source,
9956 },
9957 [ALC882_6ST_DIG] = {
9958 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9959 .init_verbs = { alc882_base_init_verbs,
9960 alc882_adc1_init_verbs },
4953550a
TI
9961 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9962 .dac_nids = alc882_dac_nids,
9963 .dig_out_nid = ALC882_DIGOUT_NID,
9964 .dig_in_nid = ALC882_DIGIN_NID,
9965 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9966 .channel_mode = alc882_sixstack_modes,
9967 .input_mux = &alc882_capture_source,
9968 },
9969 [ALC882_ARIMA] = {
9970 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9971 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9972 alc882_eapd_verbs },
4953550a
TI
9973 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9974 .dac_nids = alc882_dac_nids,
9975 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9976 .channel_mode = alc882_sixstack_modes,
9977 .input_mux = &alc882_capture_source,
9978 },
9979 [ALC882_W2JC] = {
9980 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9981 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9982 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9983 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9984 .dac_nids = alc882_dac_nids,
9985 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9986 .channel_mode = alc880_threestack_modes,
9987 .need_dac_fix = 1,
9988 .input_mux = &alc882_capture_source,
9989 .dig_out_nid = ALC882_DIGOUT_NID,
9990 },
76e6f5a9
RH
9991 [ALC885_MBA21] = {
9992 .mixers = { alc885_mba21_mixer },
9993 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9994 .num_dacs = 2,
9995 .dac_nids = alc882_dac_nids,
9996 .channel_mode = alc885_mba21_ch_modes,
9997 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9998 .input_mux = &alc882_capture_source,
9999 .unsol_event = alc_automute_amp_unsol_event,
10000 .setup = alc885_mba21_setup,
10001 .init_hook = alc_automute_amp,
10002 },
4953550a
TI
10003 [ALC885_MBP3] = {
10004 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10005 .init_verbs = { alc885_mbp3_init_verbs,
10006 alc880_gpio1_init_verbs },
be0ae923 10007 .num_dacs = 2,
4953550a 10008 .dac_nids = alc882_dac_nids,
be0ae923
TI
10009 .hp_nid = 0x04,
10010 .channel_mode = alc885_mbp_4ch_modes,
10011 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10012 .input_mux = &alc882_capture_source,
10013 .dig_out_nid = ALC882_DIGOUT_NID,
10014 .dig_in_nid = ALC882_DIGIN_NID,
10015 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10016 .setup = alc885_mbp3_setup,
10017 .init_hook = alc_automute_amp,
4953550a
TI
10018 },
10019 [ALC885_MB5] = {
10020 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10021 .init_verbs = { alc885_mb5_init_verbs,
10022 alc880_gpio1_init_verbs },
10023 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10024 .dac_nids = alc882_dac_nids,
10025 .channel_mode = alc885_mb5_6ch_modes,
10026 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10027 .input_mux = &mb5_capture_source,
10028 .dig_out_nid = ALC882_DIGOUT_NID,
10029 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10030 .unsol_event = alc_automute_amp_unsol_event,
10031 .setup = alc885_mb5_setup,
10032 .init_hook = alc_automute_amp,
4953550a 10033 },
e458b1fa
LY
10034 [ALC885_MACMINI3] = {
10035 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10036 .init_verbs = { alc885_macmini3_init_verbs,
10037 alc880_gpio1_init_verbs },
10038 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10039 .dac_nids = alc882_dac_nids,
10040 .channel_mode = alc885_macmini3_6ch_modes,
10041 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10042 .input_mux = &macmini3_capture_source,
10043 .dig_out_nid = ALC882_DIGOUT_NID,
10044 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10045 .unsol_event = alc_automute_amp_unsol_event,
10046 .setup = alc885_macmini3_setup,
10047 .init_hook = alc_automute_amp,
e458b1fa 10048 },
4953550a
TI
10049 [ALC885_MACPRO] = {
10050 .mixers = { alc882_macpro_mixer },
10051 .init_verbs = { alc882_macpro_init_verbs },
10052 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10053 .dac_nids = alc882_dac_nids,
10054 .dig_out_nid = ALC882_DIGOUT_NID,
10055 .dig_in_nid = ALC882_DIGIN_NID,
10056 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10057 .channel_mode = alc882_ch_modes,
10058 .input_mux = &alc882_capture_source,
10059 .init_hook = alc885_macpro_init_hook,
10060 },
10061 [ALC885_IMAC24] = {
10062 .mixers = { alc885_imac24_mixer },
10063 .init_verbs = { alc885_imac24_init_verbs },
10064 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10065 .dac_nids = alc882_dac_nids,
10066 .dig_out_nid = ALC882_DIGOUT_NID,
10067 .dig_in_nid = ALC882_DIGIN_NID,
10068 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10069 .channel_mode = alc882_ch_modes,
10070 .input_mux = &alc882_capture_source,
10071 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 10072 .setup = alc885_imac24_setup,
4953550a
TI
10073 .init_hook = alc885_imac24_init_hook,
10074 },
4b7e1803 10075 [ALC885_IMAC91] = {
b7cccc52 10076 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10077 .init_verbs = { alc885_imac91_init_verbs,
10078 alc880_gpio1_init_verbs },
10079 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10080 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10081 .channel_mode = alc885_mba21_ch_modes,
10082 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10083 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10084 .dig_out_nid = ALC882_DIGOUT_NID,
10085 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10086 .unsol_event = alc_automute_amp_unsol_event,
10087 .setup = alc885_imac91_setup,
10088 .init_hook = alc_automute_amp,
4b7e1803 10089 },
4953550a
TI
10090 [ALC882_TARGA] = {
10091 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10092 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10093 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10094 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10095 .dac_nids = alc882_dac_nids,
10096 .dig_out_nid = ALC882_DIGOUT_NID,
10097 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10098 .adc_nids = alc882_adc_nids,
10099 .capsrc_nids = alc882_capsrc_nids,
10100 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10101 .channel_mode = alc882_3ST_6ch_modes,
10102 .need_dac_fix = 1,
10103 .input_mux = &alc882_capture_source,
10104 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10105 .setup = alc882_targa_setup,
10106 .init_hook = alc882_targa_automute,
4953550a
TI
10107 },
10108 [ALC882_ASUS_A7J] = {
10109 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10110 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10111 alc882_asus_a7j_verbs},
4953550a
TI
10112 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10113 .dac_nids = alc882_dac_nids,
10114 .dig_out_nid = ALC882_DIGOUT_NID,
10115 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10116 .adc_nids = alc882_adc_nids,
10117 .capsrc_nids = alc882_capsrc_nids,
10118 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10119 .channel_mode = alc882_3ST_6ch_modes,
10120 .need_dac_fix = 1,
10121 .input_mux = &alc882_capture_source,
10122 },
10123 [ALC882_ASUS_A7M] = {
10124 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10125 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10126 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10127 alc882_asus_a7m_verbs },
10128 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10129 .dac_nids = alc882_dac_nids,
10130 .dig_out_nid = ALC882_DIGOUT_NID,
10131 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10132 .channel_mode = alc880_threestack_modes,
10133 .need_dac_fix = 1,
10134 .input_mux = &alc882_capture_source,
10135 },
9c7f852e
TI
10136 [ALC883_3ST_2ch_DIG] = {
10137 .mixers = { alc883_3ST_2ch_mixer },
10138 .init_verbs = { alc883_init_verbs },
10139 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10140 .dac_nids = alc883_dac_nids,
10141 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10142 .dig_in_nid = ALC883_DIGIN_NID,
10143 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10144 .channel_mode = alc883_3ST_2ch_modes,
10145 .input_mux = &alc883_capture_source,
10146 },
10147 [ALC883_3ST_6ch_DIG] = {
10148 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10149 .init_verbs = { alc883_init_verbs },
10150 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10151 .dac_nids = alc883_dac_nids,
10152 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10153 .dig_in_nid = ALC883_DIGIN_NID,
10154 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10155 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10156 .need_dac_fix = 1,
9c7f852e 10157 .input_mux = &alc883_capture_source,
f12ab1e0 10158 },
9c7f852e
TI
10159 [ALC883_3ST_6ch] = {
10160 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10161 .init_verbs = { alc883_init_verbs },
10162 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10163 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10164 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10165 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10166 .need_dac_fix = 1,
9c7f852e 10167 .input_mux = &alc883_capture_source,
f12ab1e0 10168 },
17bba1b7
J
10169 [ALC883_3ST_6ch_INTEL] = {
10170 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10171 .init_verbs = { alc883_init_verbs },
10172 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10173 .dac_nids = alc883_dac_nids,
10174 .dig_out_nid = ALC883_DIGOUT_NID,
10175 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10176 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10177 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10178 .channel_mode = alc883_3ST_6ch_intel_modes,
10179 .need_dac_fix = 1,
10180 .input_mux = &alc883_3stack_6ch_intel,
10181 },
87a8c370
JK
10182 [ALC889A_INTEL] = {
10183 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10184 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10185 alc_hp15_unsol_verbs },
87a8c370
JK
10186 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10187 .dac_nids = alc883_dac_nids,
10188 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10189 .adc_nids = alc889_adc_nids,
10190 .dig_out_nid = ALC883_DIGOUT_NID,
10191 .dig_in_nid = ALC883_DIGIN_NID,
10192 .slave_dig_outs = alc883_slave_dig_outs,
10193 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10194 .channel_mode = alc889_8ch_intel_modes,
10195 .capsrc_nids = alc889_capsrc_nids,
10196 .input_mux = &alc889_capture_source,
4f5d1706
TI
10197 .setup = alc889_automute_setup,
10198 .init_hook = alc_automute_amp,
6732bd0d 10199 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10200 .need_dac_fix = 1,
10201 },
10202 [ALC889_INTEL] = {
10203 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10204 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10205 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10206 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10207 .dac_nids = alc883_dac_nids,
10208 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10209 .adc_nids = alc889_adc_nids,
10210 .dig_out_nid = ALC883_DIGOUT_NID,
10211 .dig_in_nid = ALC883_DIGIN_NID,
10212 .slave_dig_outs = alc883_slave_dig_outs,
10213 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10214 .channel_mode = alc889_8ch_intel_modes,
10215 .capsrc_nids = alc889_capsrc_nids,
10216 .input_mux = &alc889_capture_source,
4f5d1706 10217 .setup = alc889_automute_setup,
6732bd0d
WF
10218 .init_hook = alc889_intel_init_hook,
10219 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10220 .need_dac_fix = 1,
10221 },
9c7f852e
TI
10222 [ALC883_6ST_DIG] = {
10223 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10224 .init_verbs = { alc883_init_verbs },
10225 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10226 .dac_nids = alc883_dac_nids,
10227 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10228 .dig_in_nid = ALC883_DIGIN_NID,
10229 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10230 .channel_mode = alc883_sixstack_modes,
10231 .input_mux = &alc883_capture_source,
10232 },
ccc656ce 10233 [ALC883_TARGA_DIG] = {
c259249f 10234 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10235 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10236 alc883_targa_verbs},
ccc656ce
KY
10237 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10238 .dac_nids = alc883_dac_nids,
10239 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10240 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10241 .channel_mode = alc883_3ST_6ch_modes,
10242 .need_dac_fix = 1,
10243 .input_mux = &alc883_capture_source,
c259249f 10244 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10245 .setup = alc882_targa_setup,
10246 .init_hook = alc882_targa_automute,
ccc656ce
KY
10247 },
10248 [ALC883_TARGA_2ch_DIG] = {
c259249f 10249 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10250 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10251 alc883_targa_verbs},
ccc656ce
KY
10252 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10253 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10254 .adc_nids = alc883_adc_nids_alt,
10255 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10256 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10257 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10258 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10259 .channel_mode = alc883_3ST_2ch_modes,
10260 .input_mux = &alc883_capture_source,
c259249f 10261 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10262 .setup = alc882_targa_setup,
10263 .init_hook = alc882_targa_automute,
ccc656ce 10264 },
64a8be74 10265 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10266 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10267 alc883_chmode_mixer },
64a8be74 10268 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10269 alc883_targa_verbs },
64a8be74
DH
10270 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10271 .dac_nids = alc883_dac_nids,
10272 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10273 .adc_nids = alc883_adc_nids_rev,
10274 .capsrc_nids = alc883_capsrc_nids_rev,
10275 .dig_out_nid = ALC883_DIGOUT_NID,
10276 .dig_in_nid = ALC883_DIGIN_NID,
10277 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10278 .channel_mode = alc883_4ST_8ch_modes,
10279 .need_dac_fix = 1,
10280 .input_mux = &alc883_capture_source,
c259249f 10281 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10282 .setup = alc882_targa_setup,
10283 .init_hook = alc882_targa_automute,
64a8be74 10284 },
bab282b9 10285 [ALC883_ACER] = {
676a9b53 10286 .mixers = { alc883_base_mixer },
bab282b9
VA
10287 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10288 * and the headphone jack. Turn this on and rely on the
10289 * standard mute methods whenever the user wants to turn
10290 * these outputs off.
10291 */
10292 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10293 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10294 .dac_nids = alc883_dac_nids,
bab282b9
VA
10295 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10296 .channel_mode = alc883_3ST_2ch_modes,
10297 .input_mux = &alc883_capture_source,
10298 },
2880a867 10299 [ALC883_ACER_ASPIRE] = {
676a9b53 10300 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10301 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10302 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10303 .dac_nids = alc883_dac_nids,
10304 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10305 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10306 .channel_mode = alc883_3ST_2ch_modes,
10307 .input_mux = &alc883_capture_source,
a9fd4f3f 10308 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10309 .setup = alc883_acer_aspire_setup,
10310 .init_hook = alc_automute_amp,
d1a991a6 10311 },
5b2d1eca 10312 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10313 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10314 alc883_chmode_mixer },
10315 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10316 alc888_acer_aspire_4930g_verbs },
10317 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10318 .dac_nids = alc883_dac_nids,
10319 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10320 .adc_nids = alc883_adc_nids_rev,
10321 .capsrc_nids = alc883_capsrc_nids_rev,
10322 .dig_out_nid = ALC883_DIGOUT_NID,
10323 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10324 .channel_mode = alc883_3ST_6ch_modes,
10325 .need_dac_fix = 1,
973b8cb0 10326 .const_channel_count = 6,
5b2d1eca 10327 .num_mux_defs =
ef8ef5fb
VP
10328 ARRAY_SIZE(alc888_2_capture_sources),
10329 .input_mux = alc888_2_capture_sources,
d2fd4b09 10330 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10331 .setup = alc888_acer_aspire_4930g_setup,
10332 .init_hook = alc_automute_amp,
d2fd4b09
TV
10333 },
10334 [ALC888_ACER_ASPIRE_6530G] = {
10335 .mixers = { alc888_acer_aspire_6530_mixer },
10336 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10337 alc888_acer_aspire_6530g_verbs },
10338 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10339 .dac_nids = alc883_dac_nids,
10340 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10341 .adc_nids = alc883_adc_nids_rev,
10342 .capsrc_nids = alc883_capsrc_nids_rev,
10343 .dig_out_nid = ALC883_DIGOUT_NID,
10344 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10345 .channel_mode = alc883_3ST_2ch_modes,
10346 .num_mux_defs =
10347 ARRAY_SIZE(alc888_2_capture_sources),
10348 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10349 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10350 .setup = alc888_acer_aspire_6530g_setup,
10351 .init_hook = alc_automute_amp,
5b2d1eca 10352 },
3b315d70 10353 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10354 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10355 alc883_chmode_mixer },
10356 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10357 alc889_acer_aspire_8930g_verbs,
10358 alc889_eapd_verbs},
3b315d70
HM
10359 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10360 .dac_nids = alc883_dac_nids,
018df418
HM
10361 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10362 .adc_nids = alc889_adc_nids,
10363 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10364 .dig_out_nid = ALC883_DIGOUT_NID,
10365 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10366 .channel_mode = alc883_3ST_6ch_modes,
10367 .need_dac_fix = 1,
10368 .const_channel_count = 6,
10369 .num_mux_defs =
018df418
HM
10370 ARRAY_SIZE(alc889_capture_sources),
10371 .input_mux = alc889_capture_sources,
3b315d70 10372 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10373 .setup = alc889_acer_aspire_8930g_setup,
10374 .init_hook = alc_automute_amp,
f5de24b0 10375#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10376 .power_hook = alc_power_eapd,
f5de24b0 10377#endif
3b315d70 10378 },
fc86f954
DK
10379 [ALC888_ACER_ASPIRE_7730G] = {
10380 .mixers = { alc883_3ST_6ch_mixer,
10381 alc883_chmode_mixer },
10382 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10383 alc888_acer_aspire_7730G_verbs },
10384 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10385 .dac_nids = alc883_dac_nids,
10386 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10387 .adc_nids = alc883_adc_nids_rev,
10388 .capsrc_nids = alc883_capsrc_nids_rev,
10389 .dig_out_nid = ALC883_DIGOUT_NID,
10390 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10391 .channel_mode = alc883_3ST_6ch_modes,
10392 .need_dac_fix = 1,
10393 .const_channel_count = 6,
10394 .input_mux = &alc883_capture_source,
10395 .unsol_event = alc_automute_amp_unsol_event,
d9477207 10396 .setup = alc888_acer_aspire_7730g_setup,
fc86f954
DK
10397 .init_hook = alc_automute_amp,
10398 },
c07584c8
TD
10399 [ALC883_MEDION] = {
10400 .mixers = { alc883_fivestack_mixer,
10401 alc883_chmode_mixer },
10402 .init_verbs = { alc883_init_verbs,
b373bdeb 10403 alc883_medion_eapd_verbs },
c07584c8
TD
10404 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10405 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10406 .adc_nids = alc883_adc_nids_alt,
10407 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10408 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10409 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10410 .channel_mode = alc883_sixstack_modes,
10411 .input_mux = &alc883_capture_source,
b373bdeb 10412 },
7ad7b218
MC
10413 [ALC883_MEDION_WIM2160] = {
10414 .mixers = { alc883_medion_wim2160_mixer },
10415 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10416 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10417 .dac_nids = alc883_dac_nids,
10418 .dig_out_nid = ALC883_DIGOUT_NID,
10419 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10420 .adc_nids = alc883_adc_nids,
10421 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10422 .channel_mode = alc883_3ST_2ch_modes,
10423 .input_mux = &alc883_capture_source,
10424 .unsol_event = alc_automute_amp_unsol_event,
10425 .setup = alc883_medion_wim2160_setup,
10426 .init_hook = alc_automute_amp,
10427 },
b373bdeb 10428 [ALC883_LAPTOP_EAPD] = {
676a9b53 10429 .mixers = { alc883_base_mixer },
b373bdeb
AN
10430 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10431 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10432 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10433 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10434 .channel_mode = alc883_3ST_2ch_modes,
10435 .input_mux = &alc883_capture_source,
10436 },
a65cc60f 10437 [ALC883_CLEVO_M540R] = {
10438 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10439 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10440 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10441 .dac_nids = alc883_dac_nids,
10442 .dig_out_nid = ALC883_DIGOUT_NID,
10443 .dig_in_nid = ALC883_DIGIN_NID,
10444 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10445 .channel_mode = alc883_3ST_6ch_clevo_modes,
10446 .need_dac_fix = 1,
10447 .input_mux = &alc883_capture_source,
10448 /* This machine has the hardware HP auto-muting, thus
10449 * we need no software mute via unsol event
10450 */
10451 },
0c4cc443
HRK
10452 [ALC883_CLEVO_M720] = {
10453 .mixers = { alc883_clevo_m720_mixer },
10454 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10455 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10456 .dac_nids = alc883_dac_nids,
10457 .dig_out_nid = ALC883_DIGOUT_NID,
10458 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10459 .channel_mode = alc883_3ST_2ch_modes,
10460 .input_mux = &alc883_capture_source,
0c4cc443 10461 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10462 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10463 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10464 },
bc9f98a9
KY
10465 [ALC883_LENOVO_101E_2ch] = {
10466 .mixers = { alc883_lenovo_101e_2ch_mixer},
10467 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10468 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10469 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10470 .adc_nids = alc883_adc_nids_alt,
10471 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10472 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10473 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10474 .channel_mode = alc883_3ST_2ch_modes,
10475 .input_mux = &alc883_lenovo_101e_capture_source,
10476 .unsol_event = alc883_lenovo_101e_unsol_event,
10477 .init_hook = alc883_lenovo_101e_all_automute,
10478 },
272a527c
KY
10479 [ALC883_LENOVO_NB0763] = {
10480 .mixers = { alc883_lenovo_nb0763_mixer },
10481 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10482 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10483 .dac_nids = alc883_dac_nids,
272a527c
KY
10484 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10485 .channel_mode = alc883_3ST_2ch_modes,
10486 .need_dac_fix = 1,
10487 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10488 .unsol_event = alc_automute_amp_unsol_event,
dc427170 10489 .setup = alc883_lenovo_nb0763_setup,
4f5d1706 10490 .init_hook = alc_automute_amp,
272a527c
KY
10491 },
10492 [ALC888_LENOVO_MS7195_DIG] = {
10493 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10494 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10495 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10496 .dac_nids = alc883_dac_nids,
10497 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10498 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10499 .channel_mode = alc883_3ST_6ch_modes,
10500 .need_dac_fix = 1,
10501 .input_mux = &alc883_capture_source,
10502 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10503 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10504 },
10505 [ALC883_HAIER_W66] = {
c259249f 10506 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10507 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10508 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10509 .dac_nids = alc883_dac_nids,
10510 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10511 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10512 .channel_mode = alc883_3ST_2ch_modes,
10513 .input_mux = &alc883_capture_source,
a9fd4f3f 10514 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10515 .setup = alc883_haier_w66_setup,
10516 .init_hook = alc_automute_amp,
eea6419e 10517 },
4723c022 10518 [ALC888_3ST_HP] = {
eea6419e 10519 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10520 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10521 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10522 .dac_nids = alc883_dac_nids,
4723c022
CM
10523 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10524 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10525 .need_dac_fix = 1,
10526 .input_mux = &alc883_capture_source,
a9fd4f3f 10527 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10528 .setup = alc888_3st_hp_setup,
10529 .init_hook = alc_automute_amp,
8341de60 10530 },
5795b9e6 10531 [ALC888_6ST_DELL] = {
f24dbdc6 10532 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10533 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10534 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10535 .dac_nids = alc883_dac_nids,
10536 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10537 .dig_in_nid = ALC883_DIGIN_NID,
10538 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10539 .channel_mode = alc883_sixstack_modes,
10540 .input_mux = &alc883_capture_source,
a9fd4f3f 10541 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10542 .setup = alc888_6st_dell_setup,
10543 .init_hook = alc_automute_amp,
5795b9e6 10544 },
a8848bd6
AS
10545 [ALC883_MITAC] = {
10546 .mixers = { alc883_mitac_mixer },
10547 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10548 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10549 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10550 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10551 .channel_mode = alc883_3ST_2ch_modes,
10552 .input_mux = &alc883_capture_source,
a9fd4f3f 10553 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10554 .setup = alc883_mitac_setup,
10555 .init_hook = alc_automute_amp,
a8848bd6 10556 },
fb97dc67
J
10557 [ALC883_FUJITSU_PI2515] = {
10558 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10559 .init_verbs = { alc883_init_verbs,
10560 alc883_2ch_fujitsu_pi2515_verbs},
10561 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10562 .dac_nids = alc883_dac_nids,
10563 .dig_out_nid = ALC883_DIGOUT_NID,
10564 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10565 .channel_mode = alc883_3ST_2ch_modes,
10566 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10567 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10568 .setup = alc883_2ch_fujitsu_pi2515_setup,
10569 .init_hook = alc_automute_amp,
fb97dc67 10570 },
ef8ef5fb
VP
10571 [ALC888_FUJITSU_XA3530] = {
10572 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10573 .init_verbs = { alc883_init_verbs,
10574 alc888_fujitsu_xa3530_verbs },
10575 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10576 .dac_nids = alc883_dac_nids,
10577 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10578 .adc_nids = alc883_adc_nids_rev,
10579 .capsrc_nids = alc883_capsrc_nids_rev,
10580 .dig_out_nid = ALC883_DIGOUT_NID,
10581 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10582 .channel_mode = alc888_4ST_8ch_intel_modes,
10583 .num_mux_defs =
10584 ARRAY_SIZE(alc888_2_capture_sources),
10585 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10586 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10587 .setup = alc888_fujitsu_xa3530_setup,
10588 .init_hook = alc_automute_amp,
ef8ef5fb 10589 },
e2757d5e
KY
10590 [ALC888_LENOVO_SKY] = {
10591 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10592 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10593 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10594 .dac_nids = alc883_dac_nids,
10595 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10596 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10597 .channel_mode = alc883_sixstack_modes,
10598 .need_dac_fix = 1,
10599 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10600 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10601 .setup = alc888_lenovo_sky_setup,
10602 .init_hook = alc_automute_amp,
e2757d5e
KY
10603 },
10604 [ALC888_ASUS_M90V] = {
10605 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10606 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10607 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10608 .dac_nids = alc883_dac_nids,
10609 .dig_out_nid = ALC883_DIGOUT_NID,
10610 .dig_in_nid = ALC883_DIGIN_NID,
10611 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10612 .channel_mode = alc883_3ST_6ch_modes,
10613 .need_dac_fix = 1,
10614 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10615 .unsol_event = alc_sku_unsol_event,
10616 .setup = alc883_mode2_setup,
10617 .init_hook = alc_inithook,
e2757d5e
KY
10618 },
10619 [ALC888_ASUS_EEE1601] = {
10620 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10621 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10622 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10623 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10624 .dac_nids = alc883_dac_nids,
10625 .dig_out_nid = ALC883_DIGOUT_NID,
10626 .dig_in_nid = ALC883_DIGIN_NID,
10627 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10628 .channel_mode = alc883_3ST_2ch_modes,
10629 .need_dac_fix = 1,
10630 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10631 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10632 .init_hook = alc883_eee1601_inithook,
10633 },
3ab90935
WF
10634 [ALC1200_ASUS_P5Q] = {
10635 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10636 .init_verbs = { alc883_init_verbs },
10637 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10638 .dac_nids = alc883_dac_nids,
10639 .dig_out_nid = ALC1200_DIGOUT_NID,
10640 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10641 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10642 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10643 .channel_mode = alc883_sixstack_modes,
10644 .input_mux = &alc883_capture_source,
10645 },
eb4c41d3
TS
10646 [ALC889A_MB31] = {
10647 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10648 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10649 alc880_gpio1_init_verbs },
10650 .adc_nids = alc883_adc_nids,
10651 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10652 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10653 .dac_nids = alc883_dac_nids,
10654 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10655 .channel_mode = alc889A_mb31_6ch_modes,
10656 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10657 .input_mux = &alc889A_mb31_capture_source,
10658 .dig_out_nid = ALC883_DIGOUT_NID,
10659 .unsol_event = alc889A_mb31_unsol_event,
10660 .init_hook = alc889A_mb31_automute,
10661 },
3e1647c5
GG
10662 [ALC883_SONY_VAIO_TT] = {
10663 .mixers = { alc883_vaiott_mixer },
10664 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10665 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10666 .dac_nids = alc883_dac_nids,
10667 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10668 .channel_mode = alc883_3ST_2ch_modes,
10669 .input_mux = &alc883_capture_source,
10670 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10671 .setup = alc883_vaiott_setup,
10672 .init_hook = alc_automute_amp,
3e1647c5 10673 },
9c7f852e
TI
10674};
10675
10676
4953550a
TI
10677/*
10678 * Pin config fixes
10679 */
10680enum {
954a29c8 10681 PINFIX_ABIT_AW9D_MAX,
32eea388 10682 PINFIX_LENOVO_Y530,
954a29c8 10683 PINFIX_PB_M5210,
c3d226ab 10684 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10685};
10686
f8f25ba3
TI
10687static const struct alc_fixup alc882_fixups[] = {
10688 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10689 .type = ALC_FIXUP_PINS,
10690 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10691 { 0x15, 0x01080104 }, /* side */
10692 { 0x16, 0x01011012 }, /* rear */
10693 { 0x17, 0x01016011 }, /* clfe */
10694 { }
10695 }
f8f25ba3 10696 },
32eea388
DH
10697 [PINFIX_LENOVO_Y530] = {
10698 .type = ALC_FIXUP_PINS,
10699 .v.pins = (const struct alc_pincfg[]) {
10700 { 0x15, 0x99130112 }, /* rear int speakers */
10701 { 0x16, 0x99130111 }, /* subwoofer */
10702 { }
10703 }
10704 },
954a29c8 10705 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10706 .type = ALC_FIXUP_VERBS,
10707 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10708 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10709 {}
10710 }
954a29c8 10711 },
c3d226ab 10712 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10713 .type = ALC_FIXUP_SKU,
10714 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10715 },
4953550a
TI
10716};
10717
f8f25ba3 10718static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10719 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10720 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10721 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10722 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10723 {}
10724};
10725
9c7f852e
TI
10726/*
10727 * BIOS auto configuration
10728 */
05f5f477
TI
10729static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10730 const struct auto_pin_cfg *cfg)
10731{
10732 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10733}
10734
4953550a 10735static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10736 hda_nid_t nid, int pin_type,
489008cd 10737 hda_nid_t dac)
9c7f852e 10738{
f12ab1e0
TI
10739 int idx;
10740
489008cd 10741 /* set as output */
f6c7e546 10742 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10743
10744 if (dac == 0x25)
9c7f852e 10745 idx = 4;
489008cd
TI
10746 else if (dac >= 0x02 && dac <= 0x05)
10747 idx = dac - 2;
f9700d5a 10748 else
489008cd 10749 return;
9c7f852e 10750 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10751}
10752
4953550a 10753static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10754{
10755 struct alc_spec *spec = codec->spec;
10756 int i;
10757
10758 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10759 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10760 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10761 if (nid)
4953550a 10762 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10763 spec->multiout.dac_nids[i]);
9c7f852e
TI
10764 }
10765}
10766
4953550a 10767static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10768{
10769 struct alc_spec *spec = codec->spec;
489008cd 10770 hda_nid_t pin, dac;
5855fb80 10771 int i;
9c7f852e 10772
5855fb80
TI
10773 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10774 pin = spec->autocfg.hp_pins[i];
10775 if (!pin)
10776 break;
489008cd
TI
10777 dac = spec->multiout.hp_nid;
10778 if (!dac)
10779 dac = spec->multiout.dac_nids[0]; /* to front */
10780 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10781 }
5855fb80
TI
10782 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10783 pin = spec->autocfg.speaker_pins[i];
10784 if (!pin)
10785 break;
489008cd
TI
10786 dac = spec->multiout.extra_out_nid[0];
10787 if (!dac)
10788 dac = spec->multiout.dac_nids[0]; /* to front */
10789 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10790 }
9c7f852e
TI
10791}
10792
4953550a 10793static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10794{
10795 struct alc_spec *spec = codec->spec;
66ceeb6b 10796 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10797 int i;
10798
66ceeb6b
TI
10799 for (i = 0; i < cfg->num_inputs; i++) {
10800 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10801 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10802 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10803 snd_hda_codec_write(codec, nid, 0,
10804 AC_VERB_SET_AMP_GAIN_MUTE,
10805 AMP_OUT_MUTE);
10806 }
10807}
10808
10809static void alc882_auto_init_input_src(struct hda_codec *codec)
10810{
10811 struct alc_spec *spec = codec->spec;
10812 int c;
10813
10814 for (c = 0; c < spec->num_adc_nids; c++) {
10815 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10816 hda_nid_t nid = spec->capsrc_nids[c];
10817 unsigned int mux_idx;
10818 const struct hda_input_mux *imux;
10819 int conns, mute, idx, item;
10820
10821 conns = snd_hda_get_connections(codec, nid, conn_list,
10822 ARRAY_SIZE(conn_list));
10823 if (conns < 0)
10824 continue;
10825 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10826 imux = &spec->input_mux[mux_idx];
5311114d
TI
10827 if (!imux->num_items && mux_idx > 0)
10828 imux = &spec->input_mux[0];
4953550a
TI
10829 for (idx = 0; idx < conns; idx++) {
10830 /* if the current connection is the selected one,
10831 * unmute it as default - otherwise mute it
10832 */
10833 mute = AMP_IN_MUTE(idx);
10834 for (item = 0; item < imux->num_items; item++) {
10835 if (imux->items[item].index == idx) {
10836 if (spec->cur_mux[c] == item)
10837 mute = AMP_IN_UNMUTE(idx);
10838 break;
10839 }
10840 }
10841 /* check if we have a selector or mixer
10842 * we could check for the widget type instead, but
10843 * just check for Amp-In presence (in case of mixer
10844 * without amp-in there is something wrong, this
10845 * function shouldn't be used or capsrc nid is wrong)
10846 */
10847 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10848 snd_hda_codec_write(codec, nid, 0,
10849 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10850 mute);
10851 else if (mute != AMP_IN_MUTE(idx))
10852 snd_hda_codec_write(codec, nid, 0,
10853 AC_VERB_SET_CONNECT_SEL,
10854 idx);
9c7f852e
TI
10855 }
10856 }
10857}
10858
4953550a
TI
10859/* add mic boosts if needed */
10860static int alc_auto_add_mic_boost(struct hda_codec *codec)
10861{
10862 struct alc_spec *spec = codec->spec;
66ceeb6b 10863 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10864 int i, err;
53e8c323 10865 int type_idx = 0;
4953550a 10866 hda_nid_t nid;
5322bf27 10867 const char *prev_label = NULL;
4953550a 10868
66ceeb6b 10869 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10870 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10871 break;
10872 nid = cfg->inputs[i].pin;
10873 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10874 const char *label;
10875 char boost_label[32];
10876
10877 label = hda_get_autocfg_input_label(codec, cfg, i);
10878 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10879 type_idx++;
10880 else
10881 type_idx = 0;
5322bf27
DH
10882 prev_label = label;
10883
10884 snprintf(boost_label, sizeof(boost_label),
10885 "%s Boost Volume", label);
10886 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10887 boost_label, type_idx,
4953550a 10888 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10889 if (err < 0)
10890 return err;
10891 }
4953550a
TI
10892 }
10893 return 0;
10894}
f511b01c 10895
9c7f852e 10896/* almost identical with ALC880 parser... */
4953550a 10897static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10898{
10899 struct alc_spec *spec = codec->spec;
05f5f477 10900 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10901 int err;
9c7f852e 10902
05f5f477
TI
10903 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10904 alc882_ignore);
9c7f852e
TI
10905 if (err < 0)
10906 return err;
05f5f477
TI
10907 if (!spec->autocfg.line_outs)
10908 return 0; /* can't find valid BIOS pin config */
776e184e 10909
05f5f477
TI
10910 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10911 if (err < 0)
10912 return err;
569ed348 10913 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10914 if (err < 0)
10915 return err;
10916 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10917 "Headphone");
05f5f477
TI
10918 if (err < 0)
10919 return err;
10920 err = alc880_auto_create_extra_out(spec,
10921 spec->autocfg.speaker_pins[0],
10922 "Speaker");
10923 if (err < 0)
10924 return err;
05f5f477 10925 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10926 if (err < 0)
10927 return err;
10928
05f5f477
TI
10929 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10930
757899ac 10931 alc_auto_parse_digital(codec);
05f5f477
TI
10932
10933 if (spec->kctls.list)
10934 add_mixer(spec, spec->kctls.list);
10935
10936 add_verb(spec, alc883_auto_init_verbs);
4953550a 10937 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10938 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10939 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10940
05f5f477
TI
10941 spec->num_mux_defs = 1;
10942 spec->input_mux = &spec->private_imux[0];
10943
6227cdce 10944 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10945
10946 err = alc_auto_add_mic_boost(codec);
10947 if (err < 0)
10948 return err;
61b9b9b1 10949
776e184e 10950 return 1; /* config found */
9c7f852e
TI
10951}
10952
10953/* additional initialization for auto-configuration model */
4953550a 10954static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10955{
f6c7e546 10956 struct alc_spec *spec = codec->spec;
4953550a
TI
10957 alc882_auto_init_multi_out(codec);
10958 alc882_auto_init_hp_out(codec);
10959 alc882_auto_init_analog_input(codec);
10960 alc882_auto_init_input_src(codec);
757899ac 10961 alc_auto_init_digital(codec);
f6c7e546 10962 if (spec->unsol_event)
7fb0d78f 10963 alc_inithook(codec);
9c7f852e
TI
10964}
10965
4953550a 10966static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10967{
10968 struct alc_spec *spec;
10969 int err, board_config;
10970
10971 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10972 if (spec == NULL)
10973 return -ENOMEM;
10974
10975 codec->spec = spec;
10976
4953550a
TI
10977 switch (codec->vendor_id) {
10978 case 0x10ec0882:
10979 case 0x10ec0885:
10980 break;
10981 default:
10982 /* ALC883 and variants */
10983 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10984 break;
10985 }
2c3bf9ab 10986
4953550a
TI
10987 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10988 alc882_models,
10989 alc882_cfg_tbl);
10990
10991 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10992 board_config = snd_hda_check_board_codec_sid_config(codec,
10993 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10994
10995 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10996 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10997 codec->chip_name);
10998 board_config = ALC882_AUTO;
9c7f852e
TI
10999 }
11000
b5bfbc67
TI
11001 if (board_config == ALC882_AUTO) {
11002 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11003 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11004 }
4953550a 11005
90622917
DH
11006 alc_auto_parse_customize_define(codec);
11007
4953550a 11008 if (board_config == ALC882_AUTO) {
9c7f852e 11009 /* automatic parse from the BIOS config */
4953550a 11010 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11011 if (err < 0) {
11012 alc_free(codec);
11013 return err;
f12ab1e0 11014 } else if (!err) {
9c7f852e
TI
11015 printk(KERN_INFO
11016 "hda_codec: Cannot set up configuration "
11017 "from BIOS. Using base mode...\n");
4953550a 11018 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11019 }
11020 }
11021
dc1eae25 11022 if (has_cdefine_beep(codec)) {
8af2591d
TI
11023 err = snd_hda_attach_beep_device(codec, 0x1);
11024 if (err < 0) {
11025 alc_free(codec);
11026 return err;
11027 }
680cd536
KK
11028 }
11029
4953550a 11030 if (board_config != ALC882_AUTO)
e9c364c0 11031 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11032
4953550a
TI
11033 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11034 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11035 /* FIXME: setup DAC5 */
11036 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11037 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11038
11039 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11040 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11041
4953550a 11042 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11043 int i, j;
4953550a
TI
11044 spec->num_adc_nids = 0;
11045 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11046 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11047 hda_nid_t cap;
d11f74c6 11048 hda_nid_t items[16];
4953550a
TI
11049 hda_nid_t nid = alc882_adc_nids[i];
11050 unsigned int wcap = get_wcaps(codec, nid);
11051 /* get type */
a22d543a 11052 wcap = get_wcaps_type(wcap);
4953550a
TI
11053 if (wcap != AC_WID_AUD_IN)
11054 continue;
11055 spec->private_adc_nids[spec->num_adc_nids] = nid;
11056 err = snd_hda_get_connections(codec, nid, &cap, 1);
11057 if (err < 0)
11058 continue;
d11f74c6
TI
11059 err = snd_hda_get_connections(codec, cap, items,
11060 ARRAY_SIZE(items));
11061 if (err < 0)
11062 continue;
11063 for (j = 0; j < imux->num_items; j++)
11064 if (imux->items[j].index >= err)
11065 break;
11066 if (j < imux->num_items)
11067 continue;
4953550a
TI
11068 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11069 spec->num_adc_nids++;
61b9b9b1 11070 }
4953550a
TI
11071 spec->adc_nids = spec->private_adc_nids;
11072 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11073 }
11074
b59bdf3b 11075 set_capture_mixer(codec);
da00c244 11076
dc1eae25 11077 if (has_cdefine_beep(codec))
da00c244 11078 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11079
b5bfbc67 11080 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11081
2134ea4f
TI
11082 spec->vmaster_nid = 0x0c;
11083
9c7f852e 11084 codec->patch_ops = alc_patch_ops;
4953550a
TI
11085 if (board_config == ALC882_AUTO)
11086 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11087
11088 alc_init_jacks(codec);
cb53c626
TI
11089#ifdef CONFIG_SND_HDA_POWER_SAVE
11090 if (!spec->loopback.amplist)
4953550a 11091 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11092#endif
9c7f852e
TI
11093
11094 return 0;
11095}
11096
4953550a 11097
9c7f852e
TI
11098/*
11099 * ALC262 support
11100 */
11101
11102#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11103#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11104
11105#define alc262_dac_nids alc260_dac_nids
11106#define alc262_adc_nids alc882_adc_nids
11107#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11108#define alc262_capsrc_nids alc882_capsrc_nids
11109#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11110
11111#define alc262_modes alc260_modes
11112#define alc262_capture_source alc882_capture_source
11113
4e555fe5
KY
11114static hda_nid_t alc262_dmic_adc_nids[1] = {
11115 /* ADC0 */
11116 0x09
11117};
11118
11119static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11120
9c7f852e
TI
11121static struct snd_kcontrol_new alc262_base_mixer[] = {
11122 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11123 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11124 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11125 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11126 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11127 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11129 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11130 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11131 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11132 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11133 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11134 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11135 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11136 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11137 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11138 { } /* end */
11139};
11140
ce875f07
TI
11141/* update HP, line and mono-out pins according to the master switch */
11142static void alc262_hp_master_update(struct hda_codec *codec)
11143{
11144 struct alc_spec *spec = codec->spec;
11145 int val = spec->master_sw;
11146
11147 /* HP & line-out */
11148 snd_hda_codec_write_cache(codec, 0x1b, 0,
11149 AC_VERB_SET_PIN_WIDGET_CONTROL,
11150 val ? PIN_HP : 0);
11151 snd_hda_codec_write_cache(codec, 0x15, 0,
11152 AC_VERB_SET_PIN_WIDGET_CONTROL,
11153 val ? PIN_HP : 0);
11154 /* mono (speaker) depending on the HP jack sense */
11155 val = val && !spec->jack_present;
11156 snd_hda_codec_write_cache(codec, 0x16, 0,
11157 AC_VERB_SET_PIN_WIDGET_CONTROL,
11158 val ? PIN_OUT : 0);
11159}
11160
11161static void alc262_hp_bpc_automute(struct hda_codec *codec)
11162{
11163 struct alc_spec *spec = codec->spec;
864f92be
WF
11164
11165 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11166 alc262_hp_master_update(codec);
11167}
11168
11169static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11170{
11171 if ((res >> 26) != ALC880_HP_EVENT)
11172 return;
11173 alc262_hp_bpc_automute(codec);
11174}
11175
11176static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11177{
11178 struct alc_spec *spec = codec->spec;
864f92be
WF
11179
11180 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11181 alc262_hp_master_update(codec);
11182}
11183
11184static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11185 unsigned int res)
11186{
11187 if ((res >> 26) != ALC880_HP_EVENT)
11188 return;
11189 alc262_hp_wildwest_automute(codec);
11190}
11191
b72519b5 11192#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11193
11194static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11195 struct snd_ctl_elem_value *ucontrol)
11196{
11197 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11198 struct alc_spec *spec = codec->spec;
11199 int val = !!*ucontrol->value.integer.value;
11200
11201 if (val == spec->master_sw)
11202 return 0;
11203 spec->master_sw = val;
11204 alc262_hp_master_update(codec);
11205 return 1;
11206}
11207
b72519b5
TI
11208#define ALC262_HP_MASTER_SWITCH \
11209 { \
11210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11211 .name = "Master Playback Switch", \
11212 .info = snd_ctl_boolean_mono_info, \
11213 .get = alc262_hp_master_sw_get, \
11214 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11215 }, \
11216 { \
11217 .iface = NID_MAPPING, \
11218 .name = "Master Playback Switch", \
11219 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11220 }
11221
5b0cb1d8 11222
9c7f852e 11223static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11224 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11225 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11226 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11227 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11228 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11229 HDA_OUTPUT),
11230 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11231 HDA_OUTPUT),
9c7f852e
TI
11232 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11233 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11235 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11236 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11237 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11238 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11239 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11240 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11241 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11242 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11243 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11244 { } /* end */
11245};
11246
cd7509a4 11247static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11248 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11249 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11250 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11251 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11252 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11253 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11254 HDA_OUTPUT),
11255 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11256 HDA_OUTPUT),
cd7509a4
KY
11257 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11258 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11259 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11260 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11261 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11262 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11263 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11264 { } /* end */
11265};
11266
11267static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11268 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11269 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11270 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11271 { } /* end */
11272};
11273
66d2a9d6 11274/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11275static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11276{
11277 struct alc_spec *spec = codec->spec;
66d2a9d6 11278
a9fd4f3f 11279 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11280 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11281}
11282
66d2a9d6 11283static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11284 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11285 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11286 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11287 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11288 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11289 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11290 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11291 { } /* end */
11292};
11293
11294static struct hda_verb alc262_hp_t5735_verbs[] = {
11295 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11296 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11297
11298 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11299 { }
11300};
11301
8c427226 11302static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11303 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11304 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11305 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11306 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11307 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11308 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11309 { } /* end */
11310};
11311
11312static struct hda_verb alc262_hp_rp5700_verbs[] = {
11313 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11314 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11315 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11316 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11317 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11318 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11321 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11322 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11323 {}
11324};
11325
11326static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11327 .num_items = 1,
11328 .items = {
11329 { "Line", 0x1 },
11330 },
11331};
11332
42171c17
TI
11333/* bind hp and internal speaker mute (with plug check) as master switch */
11334static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11335{
42171c17
TI
11336 struct alc_spec *spec = codec->spec;
11337 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11338 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11339 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11340 unsigned int mute;
0724ea2a 11341
42171c17
TI
11342 /* HP */
11343 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11344 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11345 HDA_AMP_MUTE, mute);
11346 /* mute internal speaker per jack sense */
11347 if (spec->jack_present)
11348 mute = HDA_AMP_MUTE;
11349 if (line_nid)
11350 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11351 HDA_AMP_MUTE, mute);
11352 if (speaker_nid && speaker_nid != line_nid)
11353 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11354 HDA_AMP_MUTE, mute);
42171c17
TI
11355}
11356
11357#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11358
11359static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11360 struct snd_ctl_elem_value *ucontrol)
11361{
11362 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11363 struct alc_spec *spec = codec->spec;
11364 int val = !!*ucontrol->value.integer.value;
11365
11366 if (val == spec->master_sw)
11367 return 0;
11368 spec->master_sw = val;
11369 alc262_hippo_master_update(codec);
11370 return 1;
11371}
11372
11373#define ALC262_HIPPO_MASTER_SWITCH \
11374 { \
11375 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11376 .name = "Master Playback Switch", \
11377 .info = snd_ctl_boolean_mono_info, \
11378 .get = alc262_hippo_master_sw_get, \
11379 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11380 }, \
11381 { \
11382 .iface = NID_MAPPING, \
11383 .name = "Master Playback Switch", \
11384 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11385 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11386 }
42171c17
TI
11387
11388static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11389 ALC262_HIPPO_MASTER_SWITCH,
11390 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11391 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11392 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11393 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11394 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11395 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11396 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11397 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11398 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11399 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11400 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11401 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11402 { } /* end */
11403};
11404
11405static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11406 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11407 ALC262_HIPPO_MASTER_SWITCH,
11408 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11409 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11410 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11411 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11413 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11414 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11415 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11416 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11417 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11418 { } /* end */
11419};
11420
11421/* mute/unmute internal speaker according to the hp jack and mute state */
11422static void alc262_hippo_automute(struct hda_codec *codec)
11423{
11424 struct alc_spec *spec = codec->spec;
11425 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11426
864f92be 11427 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11428 alc262_hippo_master_update(codec);
0724ea2a 11429}
5b31954e 11430
42171c17
TI
11431static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11432{
11433 if ((res >> 26) != ALC880_HP_EVENT)
11434 return;
11435 alc262_hippo_automute(codec);
11436}
11437
4f5d1706 11438static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11439{
11440 struct alc_spec *spec = codec->spec;
11441
11442 spec->autocfg.hp_pins[0] = 0x15;
11443 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11444}
11445
4f5d1706 11446static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11447{
11448 struct alc_spec *spec = codec->spec;
11449
11450 spec->autocfg.hp_pins[0] = 0x1b;
11451 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11452}
11453
11454
272a527c 11455static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11456 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11457 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11460 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11461 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11462 { } /* end */
11463};
11464
83c34218 11465static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11466 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11467 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11468 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11469 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11470 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11471 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11472 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11473 { } /* end */
11474};
272a527c 11475
ba340e82
TV
11476static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11477 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11478 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11479 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11480 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11485 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11486 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11487 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11488 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11489 { } /* end */
11490};
11491
11492static struct hda_verb alc262_tyan_verbs[] = {
11493 /* Headphone automute */
11494 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11496 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11497
11498 /* P11 AUX_IN, white 4-pin connector */
11499 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11500 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11501 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11502 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11503
11504 {}
11505};
11506
11507/* unsolicited event for HP jack sensing */
4f5d1706 11508static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11509{
a9fd4f3f 11510 struct alc_spec *spec = codec->spec;
ba340e82 11511
a9fd4f3f
TI
11512 spec->autocfg.hp_pins[0] = 0x1b;
11513 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11514}
11515
ba340e82 11516
9c7f852e
TI
11517#define alc262_capture_mixer alc882_capture_mixer
11518#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11519
11520/*
11521 * generic initialization of ADC, input mixers and output mixers
11522 */
11523static struct hda_verb alc262_init_verbs[] = {
11524 /*
11525 * Unmute ADC0-2 and set the default input to mic-in
11526 */
11527 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11529 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11531 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11533
cb53c626 11534 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11535 * mixer widget
f12ab1e0
TI
11536 * Note: PASD motherboards uses the Line In 2 as the input for
11537 * front panel mic (mic 2)
9c7f852e
TI
11538 */
11539 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11545
11546 /*
df694daa
KY
11547 * Set up output mixers (0x0c - 0x0e)
11548 */
11549 /* set vol=0 to output mixers */
11550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11551 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11552 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11553 /* set up input amps for analog loopback */
11554 /* Amp Indices: DAC = 0, mixer = 1 */
11555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11557 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11559 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11561
11562 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11563 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11564 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11565 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11566 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11567 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11568
11569 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11570 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11571 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11572 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11573 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11574
df694daa
KY
11575 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11576 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11577
df694daa
KY
11578 /* FIXME: use matrix-type input source selection */
11579 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11580 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11581 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11582 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11583 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11584 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11585 /* Input mixer2 */
11586 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11587 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11588 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11589 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11590 /* Input mixer3 */
11591 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11592 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11593 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11594 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11595
11596 { }
11597};
1da177e4 11598
4e555fe5
KY
11599static struct hda_verb alc262_eapd_verbs[] = {
11600 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11601 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11602 { }
11603};
11604
ccc656ce
KY
11605static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11606 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11607 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11608 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11609
11610 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11611 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11612 {}
11613};
11614
272a527c
KY
11615static struct hda_verb alc262_sony_unsol_verbs[] = {
11616 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11617 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11618 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11619
11620 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11621 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11622 {}
272a527c
KY
11623};
11624
4e555fe5
KY
11625static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11626 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11627 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11628 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11631 { } /* end */
11632};
11633
11634static struct hda_verb alc262_toshiba_s06_verbs[] = {
11635 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11636 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11638 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11639 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11640 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11641 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11642 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11643 {}
11644};
11645
4f5d1706 11646static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11647{
a9fd4f3f
TI
11648 struct alc_spec *spec = codec->spec;
11649
11650 spec->autocfg.hp_pins[0] = 0x15;
11651 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11652 spec->ext_mic.pin = 0x18;
11653 spec->ext_mic.mux_idx = 0;
11654 spec->int_mic.pin = 0x12;
11655 spec->int_mic.mux_idx = 9;
11656 spec->auto_mic = 1;
4e555fe5
KY
11657}
11658
e8f9ae2a
PT
11659/*
11660 * nec model
11661 * 0x15 = headphone
11662 * 0x16 = internal speaker
11663 * 0x18 = external mic
11664 */
11665
11666static struct snd_kcontrol_new alc262_nec_mixer[] = {
11667 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11668 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11669
11670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11671 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11672 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11673
11674 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11675 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11676 { } /* end */
11677};
11678
11679static struct hda_verb alc262_nec_verbs[] = {
11680 /* Unmute Speaker */
11681 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11682
11683 /* Headphone */
11684 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11685 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11686
11687 /* External mic to headphone */
11688 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11689 /* External mic to speaker */
11690 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11691 {}
11692};
11693
834be88d
TI
11694/*
11695 * fujitsu model
5d9fab2d
TV
11696 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11697 * 0x1b = port replicator headphone out
834be88d
TI
11698 */
11699
11700#define ALC_HP_EVENT 0x37
11701
11702static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11703 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11704 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11705 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11706 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11707 {}
11708};
11709
0e31daf7
J
11710static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11711 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11712 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11713 {}
11714};
11715
e2595322
DC
11716static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11717 /* Front Mic pin: input vref at 50% */
11718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11719 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11720 {}
11721};
11722
834be88d 11723static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11724 .num_items = 3,
834be88d
TI
11725 .items = {
11726 { "Mic", 0x0 },
28c4edb7 11727 { "Internal Mic", 0x1 },
834be88d
TI
11728 { "CD", 0x4 },
11729 },
11730};
11731
9c7f852e
TI
11732static struct hda_input_mux alc262_HP_capture_source = {
11733 .num_items = 5,
11734 .items = {
11735 { "Mic", 0x0 },
accbe498 11736 { "Front Mic", 0x1 },
9c7f852e
TI
11737 { "Line", 0x2 },
11738 { "CD", 0x4 },
11739 { "AUX IN", 0x6 },
11740 },
11741};
11742
accbe498 11743static struct hda_input_mux alc262_HP_D7000_capture_source = {
11744 .num_items = 4,
11745 .items = {
11746 { "Mic", 0x0 },
11747 { "Front Mic", 0x2 },
11748 { "Line", 0x1 },
11749 { "CD", 0x4 },
11750 },
11751};
11752
ebc7a406 11753/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11754static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11755{
11756 struct alc_spec *spec = codec->spec;
11757 unsigned int mute;
11758
f12ab1e0 11759 if (force || !spec->sense_updated) {
864f92be
WF
11760 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11761 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11762 spec->sense_updated = 1;
11763 }
ebc7a406
TI
11764 /* unmute internal speaker only if both HPs are unplugged and
11765 * master switch is on
11766 */
11767 if (spec->jack_present)
11768 mute = HDA_AMP_MUTE;
11769 else
834be88d 11770 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11771 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11772 HDA_AMP_MUTE, mute);
834be88d
TI
11773}
11774
11775/* unsolicited event for HP jack sensing */
11776static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11777 unsigned int res)
11778{
11779 if ((res >> 26) != ALC_HP_EVENT)
11780 return;
11781 alc262_fujitsu_automute(codec, 1);
11782}
11783
ebc7a406
TI
11784static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11785{
11786 alc262_fujitsu_automute(codec, 1);
11787}
11788
834be88d 11789/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11790static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11791 .ops = &snd_hda_bind_vol,
11792 .values = {
11793 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11794 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11795 0
11796 },
11797};
834be88d 11798
0e31daf7
J
11799/* mute/unmute internal speaker according to the hp jack and mute state */
11800static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11801{
11802 struct alc_spec *spec = codec->spec;
11803 unsigned int mute;
11804
11805 if (force || !spec->sense_updated) {
864f92be 11806 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11807 spec->sense_updated = 1;
11808 }
11809 if (spec->jack_present) {
11810 /* mute internal speaker */
11811 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11812 HDA_AMP_MUTE, HDA_AMP_MUTE);
11813 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11814 HDA_AMP_MUTE, HDA_AMP_MUTE);
11815 } else {
11816 /* unmute internal speaker if necessary */
11817 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11818 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11819 HDA_AMP_MUTE, mute);
11820 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11821 HDA_AMP_MUTE, mute);
11822 }
11823}
11824
11825/* unsolicited event for HP jack sensing */
11826static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11827 unsigned int res)
11828{
11829 if ((res >> 26) != ALC_HP_EVENT)
11830 return;
11831 alc262_lenovo_3000_automute(codec, 1);
11832}
11833
8de56b7d
TI
11834static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11835 int dir, int idx, long *valp)
11836{
11837 int i, change = 0;
11838
11839 for (i = 0; i < 2; i++, valp++)
11840 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11841 HDA_AMP_MUTE,
11842 *valp ? 0 : HDA_AMP_MUTE);
11843 return change;
11844}
11845
834be88d
TI
11846/* bind hp and internal speaker mute (with plug check) */
11847static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11848 struct snd_ctl_elem_value *ucontrol)
11849{
11850 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11851 long *valp = ucontrol->value.integer.value;
11852 int change;
11853
8de56b7d
TI
11854 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11855 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11856 if (change)
11857 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11858 return change;
11859}
11860
11861static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11862 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11863 {
11864 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11865 .name = "Master Playback Switch",
5e26dfd0 11866 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11867 .info = snd_hda_mixer_amp_switch_info,
11868 .get = snd_hda_mixer_amp_switch_get,
11869 .put = alc262_fujitsu_master_sw_put,
11870 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11871 },
5b0cb1d8
JK
11872 {
11873 .iface = NID_MAPPING,
11874 .name = "Master Playback Switch",
11875 .private_value = 0x1b,
11876 },
834be88d
TI
11877 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11878 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11879 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11882 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11883 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11884 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11885 { } /* end */
11886};
11887
0e31daf7
J
11888/* bind hp and internal speaker mute (with plug check) */
11889static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11890 struct snd_ctl_elem_value *ucontrol)
11891{
11892 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11893 long *valp = ucontrol->value.integer.value;
11894 int change;
11895
8de56b7d 11896 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11897 if (change)
11898 alc262_lenovo_3000_automute(codec, 0);
11899 return change;
11900}
11901
11902static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11903 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11904 {
11905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11906 .name = "Master Playback Switch",
5e26dfd0 11907 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11908 .info = snd_hda_mixer_amp_switch_info,
11909 .get = snd_hda_mixer_amp_switch_get,
11910 .put = alc262_lenovo_3000_master_sw_put,
11911 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11912 },
11913 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11914 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11915 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11916 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11917 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11918 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11919 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11920 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11921 { } /* end */
11922};
11923
9f99a638
HM
11924static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11925 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11926 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11927 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11928 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11929 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11930 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11931 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11932 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11933 { } /* end */
11934};
11935
304dcaac
TI
11936/* additional init verbs for Benq laptops */
11937static struct hda_verb alc262_EAPD_verbs[] = {
11938 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11939 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11940 {}
11941};
11942
83c34218
KY
11943static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11944 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11945 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11946
11947 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11948 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11949 {}
11950};
11951
f651b50b
TD
11952/* Samsung Q1 Ultra Vista model setup */
11953static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11954 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11955 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11956 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11957 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11958 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11959 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11960 { } /* end */
11961};
11962
11963static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11964 /* output mixer */
11965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11967 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11968 /* speaker */
11969 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11970 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11971 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11972 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11973 /* HP */
f651b50b 11974 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11975 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11976 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11977 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11978 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11979 /* internal mic */
11980 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11981 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11982 /* ADC, choose mic */
11983 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11984 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11985 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11986 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11987 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11988 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11989 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11990 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11991 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11993 {}
11994};
11995
f651b50b
TD
11996/* mute/unmute internal speaker according to the hp jack and mute state */
11997static void alc262_ultra_automute(struct hda_codec *codec)
11998{
11999 struct alc_spec *spec = codec->spec;
12000 unsigned int mute;
f651b50b 12001
bb9f76cd
TI
12002 mute = 0;
12003 /* auto-mute only when HP is used as HP */
12004 if (!spec->cur_mux[0]) {
864f92be 12005 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12006 if (spec->jack_present)
12007 mute = HDA_AMP_MUTE;
f651b50b 12008 }
bb9f76cd
TI
12009 /* mute/unmute internal speaker */
12010 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12011 HDA_AMP_MUTE, mute);
12012 /* mute/unmute HP */
12013 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12014 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12015}
12016
12017/* unsolicited event for HP jack sensing */
12018static void alc262_ultra_unsol_event(struct hda_codec *codec,
12019 unsigned int res)
12020{
12021 if ((res >> 26) != ALC880_HP_EVENT)
12022 return;
12023 alc262_ultra_automute(codec);
12024}
12025
bb9f76cd
TI
12026static struct hda_input_mux alc262_ultra_capture_source = {
12027 .num_items = 2,
12028 .items = {
12029 { "Mic", 0x1 },
12030 { "Headphone", 0x7 },
12031 },
12032};
12033
12034static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12035 struct snd_ctl_elem_value *ucontrol)
12036{
12037 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12038 struct alc_spec *spec = codec->spec;
12039 int ret;
12040
54cbc9ab 12041 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12042 if (!ret)
12043 return 0;
12044 /* reprogram the HP pin as mic or HP according to the input source */
12045 snd_hda_codec_write_cache(codec, 0x15, 0,
12046 AC_VERB_SET_PIN_WIDGET_CONTROL,
12047 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12048 alc262_ultra_automute(codec); /* mute/unmute HP */
12049 return ret;
12050}
12051
12052static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12053 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12054 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12055 {
12056 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12057 .name = "Capture Source",
54cbc9ab
TI
12058 .info = alc_mux_enum_info,
12059 .get = alc_mux_enum_get,
bb9f76cd
TI
12060 .put = alc262_ultra_mux_enum_put,
12061 },
5b0cb1d8
JK
12062 {
12063 .iface = NID_MAPPING,
12064 .name = "Capture Source",
12065 .private_value = 0x15,
12066 },
bb9f76cd
TI
12067 { } /* end */
12068};
12069
c3fc1f50
TI
12070/* We use two mixers depending on the output pin; 0x16 is a mono output
12071 * and thus it's bound with a different mixer.
12072 * This function returns which mixer amp should be used.
12073 */
12074static int alc262_check_volbit(hda_nid_t nid)
12075{
12076 if (!nid)
12077 return 0;
12078 else if (nid == 0x16)
12079 return 2;
12080 else
12081 return 1;
12082}
12083
12084static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12085 const char *pfx, int *vbits, int idx)
c3fc1f50 12086{
c3fc1f50
TI
12087 unsigned long val;
12088 int vbit;
12089
12090 vbit = alc262_check_volbit(nid);
12091 if (!vbit)
12092 return 0;
12093 if (*vbits & vbit) /* a volume control for this mixer already there */
12094 return 0;
12095 *vbits |= vbit;
c3fc1f50
TI
12096 if (vbit == 2)
12097 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12098 else
12099 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12100 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12101}
12102
12103static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12104 const char *pfx, int idx)
c3fc1f50 12105{
c3fc1f50
TI
12106 unsigned long val;
12107
12108 if (!nid)
12109 return 0;
c3fc1f50
TI
12110 if (nid == 0x16)
12111 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12112 else
12113 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12114 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12115}
12116
df694daa 12117/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12118static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12119 const struct auto_pin_cfg *cfg)
df694daa 12120{
c3fc1f50
TI
12121 const char *pfx;
12122 int vbits;
033688a5 12123 int i, err;
df694daa
KY
12124
12125 spec->multiout.num_dacs = 1; /* only use one dac */
12126 spec->multiout.dac_nids = spec->private_dac_nids;
12127 spec->multiout.dac_nids[0] = 2;
12128
bcb2f0f5
TI
12129 pfx = alc_get_line_out_pfx(cfg, true);
12130 if (!pfx)
c3fc1f50 12131 pfx = "Front";
033688a5
TI
12132 for (i = 0; i < 2; i++) {
12133 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12134 if (err < 0)
12135 return err;
12136 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12137 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12138 "Speaker", i);
12139 if (err < 0)
12140 return err;
12141 }
12142 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12143 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12144 "Headphone", i);
12145 if (err < 0)
12146 return err;
12147 }
12148 }
df694daa 12149
c3fc1f50
TI
12150 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12151 alc262_check_volbit(cfg->speaker_pins[0]) |
12152 alc262_check_volbit(cfg->hp_pins[0]);
12153 if (vbits == 1 || vbits == 2)
12154 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12155 vbits = 0;
033688a5
TI
12156 for (i = 0; i < 2; i++) {
12157 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12158 &vbits, i);
12159 if (err < 0)
12160 return err;
12161 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12162 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12163 "Speaker", &vbits, i);
12164 if (err < 0)
12165 return err;
12166 }
12167 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12168 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12169 "Headphone", &vbits, i);
12170 if (err < 0)
12171 return err;
12172 }
12173 }
f12ab1e0 12174 return 0;
df694daa
KY
12175}
12176
05f5f477 12177#define alc262_auto_create_input_ctls \
eaa9b3a7 12178 alc882_auto_create_input_ctls
df694daa
KY
12179
12180/*
12181 * generic initialization of ADC, input mixers and output mixers
12182 */
12183static struct hda_verb alc262_volume_init_verbs[] = {
12184 /*
12185 * Unmute ADC0-2 and set the default input to mic-in
12186 */
12187 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12189 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12190 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12191 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12192 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12193
cb53c626 12194 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12195 * mixer widget
f12ab1e0
TI
12196 * Note: PASD motherboards uses the Line In 2 as the input for
12197 * front panel mic (mic 2)
df694daa
KY
12198 */
12199 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12200 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12201 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12202 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12203 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12204 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12205
12206 /*
12207 * Set up output mixers (0x0c - 0x0f)
12208 */
12209 /* set vol=0 to output mixers */
12210 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12211 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12212 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12213
df694daa
KY
12214 /* set up input amps for analog loopback */
12215 /* Amp Indices: DAC = 0, mixer = 1 */
12216 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12218 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12219 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12220 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12222
12223 /* FIXME: use matrix-type input source selection */
12224 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12225 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12226 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12227 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12228 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12229 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12230 /* Input mixer2 */
12231 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12232 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12233 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12234 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12235 /* Input mixer3 */
12236 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12237 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12238 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12239 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12240
12241 { }
12242};
12243
9c7f852e
TI
12244static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12245 /*
12246 * Unmute ADC0-2 and set the default input to mic-in
12247 */
12248 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12249 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12250 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12251 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12252 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12253 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12254
cb53c626 12255 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12256 * mixer widget
f12ab1e0
TI
12257 * Note: PASD motherboards uses the Line In 2 as the input for
12258 * front panel mic (mic 2)
9c7f852e
TI
12259 */
12260 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12261 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12262 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12263 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12264 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12265 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12266 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12267 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12268
9c7f852e
TI
12269 /*
12270 * Set up output mixers (0x0c - 0x0e)
12271 */
12272 /* set vol=0 to output mixers */
12273 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12274 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12275 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12276
12277 /* set up input amps for analog loopback */
12278 /* Amp Indices: DAC = 0, mixer = 1 */
12279 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12280 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12281 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12282 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12283 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12284 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12285
ce875f07 12286 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12287 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12288 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12289
12290 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12292
12293 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12294 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12295
12296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12297 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12298 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12299 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12300 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12301
0e4835c1 12302 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12303 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12304 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12305 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12306 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12307 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12308
12309
12310 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12311 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12312 /* Input mixer1: only unmute Mic */
9c7f852e 12313 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12316 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12318 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12319 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12321 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12322 /* Input mixer2 */
12323 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12324 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12325 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12326 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12327 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12328 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12329 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12330 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12331 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12332 /* Input mixer3 */
12333 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12334 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12335 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12336 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12339 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12340 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12341 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12342
ce875f07
TI
12343 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12344
9c7f852e
TI
12345 { }
12346};
12347
cd7509a4
KY
12348static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12349 /*
12350 * Unmute ADC0-2 and set the default input to mic-in
12351 */
12352 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12353 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12354 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12355 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12356 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12357 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12358
cb53c626 12359 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12360 * mixer widget
12361 * Note: PASD motherboards uses the Line In 2 as the input for front
12362 * panel mic (mic 2)
12363 */
12364 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12365 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12366 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12367 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12368 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12372 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12373 /*
12374 * Set up output mixers (0x0c - 0x0e)
12375 */
12376 /* set vol=0 to output mixers */
12377 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12378 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12380
12381 /* set up input amps for analog loopback */
12382 /* Amp Indices: DAC = 0, mixer = 1 */
12383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12384 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12386 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12387 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12389
12390
12391 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12392 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12393 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12394 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12395 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12396 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12397 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12398
12399 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12400 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12401
12402 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12403 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12404
12405 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12406 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12407 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12408 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12409 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12410 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12411
12412 /* FIXME: use matrix-type input source selection */
12413 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12414 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12415 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12416 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12417 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12418 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12419 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12420 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12421 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12422 /* Input mixer2 */
12423 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12424 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12425 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12426 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12427 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12428 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12430 /* Input mixer3 */
12431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12432 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12433 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12434 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12435 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12436 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12438
ce875f07
TI
12439 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12440
cd7509a4
KY
12441 { }
12442};
12443
9f99a638
HM
12444static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12445
12446 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12447 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12448 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12449
12450 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12451 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12453 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12454
12455 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12456 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12457 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12458 {}
12459};
12460
18675e42
TI
12461/*
12462 * Pin config fixes
12463 */
12464enum {
12465 PINFIX_FSC_H270,
12466};
12467
12468static const struct alc_fixup alc262_fixups[] = {
12469 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12470 .type = ALC_FIXUP_PINS,
12471 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12472 { 0x14, 0x99130110 }, /* speaker */
12473 { 0x15, 0x0221142f }, /* front HP */
12474 { 0x1b, 0x0121141f }, /* rear HP */
12475 { }
12476 }
12477 },
18675e42
TI
12478};
12479
12480static struct snd_pci_quirk alc262_fixup_tbl[] = {
12481 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12482 {}
12483};
12484
9f99a638 12485
cb53c626
TI
12486#ifdef CONFIG_SND_HDA_POWER_SAVE
12487#define alc262_loopbacks alc880_loopbacks
12488#endif
12489
def319f9 12490/* pcm configuration: identical with ALC880 */
df694daa
KY
12491#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12492#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12493#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12494#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12495
12496/*
12497 * BIOS auto configuration
12498 */
12499static int alc262_parse_auto_config(struct hda_codec *codec)
12500{
12501 struct alc_spec *spec = codec->spec;
12502 int err;
12503 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12504
f12ab1e0
TI
12505 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12506 alc262_ignore);
12507 if (err < 0)
df694daa 12508 return err;
e64f14f4 12509 if (!spec->autocfg.line_outs) {
0852d7a6 12510 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12511 spec->multiout.max_channels = 2;
12512 spec->no_analog = 1;
12513 goto dig_only;
12514 }
df694daa 12515 return 0; /* can't find valid BIOS pin config */
e64f14f4 12516 }
f12ab1e0
TI
12517 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12518 if (err < 0)
12519 return err;
05f5f477 12520 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12521 if (err < 0)
df694daa
KY
12522 return err;
12523
12524 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12525
e64f14f4 12526 dig_only:
757899ac 12527 alc_auto_parse_digital(codec);
df694daa 12528
603c4019 12529 if (spec->kctls.list)
d88897ea 12530 add_mixer(spec, spec->kctls.list);
df694daa 12531
d88897ea 12532 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12533 spec->num_mux_defs = 1;
61b9b9b1 12534 spec->input_mux = &spec->private_imux[0];
df694daa 12535
776e184e
TI
12536 err = alc_auto_add_mic_boost(codec);
12537 if (err < 0)
12538 return err;
12539
6227cdce 12540 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12541
df694daa
KY
12542 return 1;
12543}
12544
12545#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12546#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12547#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12548#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12549
12550
12551/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12552static void alc262_auto_init(struct hda_codec *codec)
df694daa 12553{
f6c7e546 12554 struct alc_spec *spec = codec->spec;
df694daa
KY
12555 alc262_auto_init_multi_out(codec);
12556 alc262_auto_init_hp_out(codec);
12557 alc262_auto_init_analog_input(codec);
f511b01c 12558 alc262_auto_init_input_src(codec);
757899ac 12559 alc_auto_init_digital(codec);
f6c7e546 12560 if (spec->unsol_event)
7fb0d78f 12561 alc_inithook(codec);
df694daa
KY
12562}
12563
12564/*
12565 * configuration and preset
12566 */
ea734963 12567static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12568 [ALC262_BASIC] = "basic",
12569 [ALC262_HIPPO] = "hippo",
12570 [ALC262_HIPPO_1] = "hippo_1",
12571 [ALC262_FUJITSU] = "fujitsu",
12572 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12573 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12574 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12575 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12576 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12577 [ALC262_BENQ_T31] = "benq-t31",
12578 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12579 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12580 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12581 [ALC262_ULTRA] = "ultra",
0e31daf7 12582 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12583 [ALC262_NEC] = "nec",
ba340e82 12584 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12585 [ALC262_AUTO] = "auto",
12586};
12587
12588static struct snd_pci_quirk alc262_cfg_tbl[] = {
12589 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12590 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12591 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12592 ALC262_HP_BPC),
12593 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12594 ALC262_HP_BPC),
5734a07c
TI
12595 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12596 ALC262_HP_BPC),
53eff7e1
TI
12597 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12598 ALC262_HP_BPC),
cd7509a4 12599 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12600 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12601 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12602 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12603 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12604 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12605 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12606 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12607 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12608 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12609 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12610 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12611 ALC262_HP_TC_T5735),
8c427226 12612 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12613 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12614 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12615 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12616 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12617 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12618 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12619 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12620#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12621 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12622 ALC262_SONY_ASSAMD),
c5b5165c 12623#endif
36ca6e13 12624 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12625 ALC262_TOSHIBA_RX1),
80ffe869 12626 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12627 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12628 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12629 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12630 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12631 ALC262_ULTRA),
3e420e78 12632 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12633 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12634 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12635 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12636 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12637 {}
12638};
12639
12640static struct alc_config_preset alc262_presets[] = {
12641 [ALC262_BASIC] = {
12642 .mixers = { alc262_base_mixer },
12643 .init_verbs = { alc262_init_verbs },
12644 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12645 .dac_nids = alc262_dac_nids,
12646 .hp_nid = 0x03,
12647 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12648 .channel_mode = alc262_modes,
a3bcba38 12649 .input_mux = &alc262_capture_source,
df694daa 12650 },
ccc656ce 12651 [ALC262_HIPPO] = {
42171c17 12652 .mixers = { alc262_hippo_mixer },
6732bd0d 12653 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12654 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12655 .dac_nids = alc262_dac_nids,
12656 .hp_nid = 0x03,
12657 .dig_out_nid = ALC262_DIGOUT_NID,
12658 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12659 .channel_mode = alc262_modes,
12660 .input_mux = &alc262_capture_source,
12661 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12662 .setup = alc262_hippo_setup,
12663 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12664 },
12665 [ALC262_HIPPO_1] = {
12666 .mixers = { alc262_hippo1_mixer },
12667 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12668 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12669 .dac_nids = alc262_dac_nids,
12670 .hp_nid = 0x02,
12671 .dig_out_nid = ALC262_DIGOUT_NID,
12672 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12673 .channel_mode = alc262_modes,
12674 .input_mux = &alc262_capture_source,
42171c17 12675 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12676 .setup = alc262_hippo1_setup,
12677 .init_hook = alc262_hippo_automute,
ccc656ce 12678 },
834be88d
TI
12679 [ALC262_FUJITSU] = {
12680 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12681 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12682 alc262_fujitsu_unsol_verbs },
834be88d
TI
12683 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12684 .dac_nids = alc262_dac_nids,
12685 .hp_nid = 0x03,
12686 .dig_out_nid = ALC262_DIGOUT_NID,
12687 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12688 .channel_mode = alc262_modes,
12689 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12690 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12691 .init_hook = alc262_fujitsu_init_hook,
834be88d 12692 },
9c7f852e
TI
12693 [ALC262_HP_BPC] = {
12694 .mixers = { alc262_HP_BPC_mixer },
12695 .init_verbs = { alc262_HP_BPC_init_verbs },
12696 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12697 .dac_nids = alc262_dac_nids,
12698 .hp_nid = 0x03,
12699 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12700 .channel_mode = alc262_modes,
12701 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12702 .unsol_event = alc262_hp_bpc_unsol_event,
12703 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12704 },
cd7509a4
KY
12705 [ALC262_HP_BPC_D7000_WF] = {
12706 .mixers = { alc262_HP_BPC_WildWest_mixer },
12707 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12708 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12709 .dac_nids = alc262_dac_nids,
12710 .hp_nid = 0x03,
12711 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12712 .channel_mode = alc262_modes,
accbe498 12713 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12714 .unsol_event = alc262_hp_wildwest_unsol_event,
12715 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12716 },
cd7509a4
KY
12717 [ALC262_HP_BPC_D7000_WL] = {
12718 .mixers = { alc262_HP_BPC_WildWest_mixer,
12719 alc262_HP_BPC_WildWest_option_mixer },
12720 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12721 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12722 .dac_nids = alc262_dac_nids,
12723 .hp_nid = 0x03,
12724 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12725 .channel_mode = alc262_modes,
accbe498 12726 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12727 .unsol_event = alc262_hp_wildwest_unsol_event,
12728 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12729 },
66d2a9d6
KY
12730 [ALC262_HP_TC_T5735] = {
12731 .mixers = { alc262_hp_t5735_mixer },
12732 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12733 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12734 .dac_nids = alc262_dac_nids,
12735 .hp_nid = 0x03,
12736 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12737 .channel_mode = alc262_modes,
12738 .input_mux = &alc262_capture_source,
dc99be47 12739 .unsol_event = alc_sku_unsol_event,
4f5d1706 12740 .setup = alc262_hp_t5735_setup,
dc99be47 12741 .init_hook = alc_inithook,
8c427226
KY
12742 },
12743 [ALC262_HP_RP5700] = {
12744 .mixers = { alc262_hp_rp5700_mixer },
12745 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12746 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12747 .dac_nids = alc262_dac_nids,
12748 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12749 .channel_mode = alc262_modes,
12750 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12751 },
304dcaac
TI
12752 [ALC262_BENQ_ED8] = {
12753 .mixers = { alc262_base_mixer },
12754 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12755 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12756 .dac_nids = alc262_dac_nids,
12757 .hp_nid = 0x03,
12758 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12759 .channel_mode = alc262_modes,
12760 .input_mux = &alc262_capture_source,
f12ab1e0 12761 },
272a527c
KY
12762 [ALC262_SONY_ASSAMD] = {
12763 .mixers = { alc262_sony_mixer },
12764 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12765 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12766 .dac_nids = alc262_dac_nids,
12767 .hp_nid = 0x02,
12768 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12769 .channel_mode = alc262_modes,
12770 .input_mux = &alc262_capture_source,
12771 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12772 .setup = alc262_hippo_setup,
12773 .init_hook = alc262_hippo_automute,
83c34218
KY
12774 },
12775 [ALC262_BENQ_T31] = {
12776 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12777 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12778 alc_hp15_unsol_verbs },
83c34218
KY
12779 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12780 .dac_nids = alc262_dac_nids,
12781 .hp_nid = 0x03,
12782 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12783 .channel_mode = alc262_modes,
12784 .input_mux = &alc262_capture_source,
12785 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12786 .setup = alc262_hippo_setup,
12787 .init_hook = alc262_hippo_automute,
ea1fb29a 12788 },
f651b50b 12789 [ALC262_ULTRA] = {
f9e336f6
TI
12790 .mixers = { alc262_ultra_mixer },
12791 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12792 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12793 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12794 .dac_nids = alc262_dac_nids,
f651b50b
TD
12795 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12796 .channel_mode = alc262_modes,
12797 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12798 .adc_nids = alc262_adc_nids, /* ADC0 */
12799 .capsrc_nids = alc262_capsrc_nids,
12800 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12801 .unsol_event = alc262_ultra_unsol_event,
12802 .init_hook = alc262_ultra_automute,
12803 },
0e31daf7
J
12804 [ALC262_LENOVO_3000] = {
12805 .mixers = { alc262_lenovo_3000_mixer },
12806 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12807 alc262_lenovo_3000_unsol_verbs,
12808 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12809 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12810 .dac_nids = alc262_dac_nids,
12811 .hp_nid = 0x03,
12812 .dig_out_nid = ALC262_DIGOUT_NID,
12813 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12814 .channel_mode = alc262_modes,
12815 .input_mux = &alc262_fujitsu_capture_source,
12816 .unsol_event = alc262_lenovo_3000_unsol_event,
12817 },
e8f9ae2a
PT
12818 [ALC262_NEC] = {
12819 .mixers = { alc262_nec_mixer },
12820 .init_verbs = { alc262_nec_verbs },
12821 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12822 .dac_nids = alc262_dac_nids,
12823 .hp_nid = 0x03,
12824 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12825 .channel_mode = alc262_modes,
12826 .input_mux = &alc262_capture_source,
12827 },
4e555fe5
KY
12828 [ALC262_TOSHIBA_S06] = {
12829 .mixers = { alc262_toshiba_s06_mixer },
12830 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12831 alc262_eapd_verbs },
12832 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12833 .capsrc_nids = alc262_dmic_capsrc_nids,
12834 .dac_nids = alc262_dac_nids,
12835 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12836 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12837 .dig_out_nid = ALC262_DIGOUT_NID,
12838 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12839 .channel_mode = alc262_modes,
4f5d1706
TI
12840 .unsol_event = alc_sku_unsol_event,
12841 .setup = alc262_toshiba_s06_setup,
12842 .init_hook = alc_inithook,
4e555fe5 12843 },
9f99a638
HM
12844 [ALC262_TOSHIBA_RX1] = {
12845 .mixers = { alc262_toshiba_rx1_mixer },
12846 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12847 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12848 .dac_nids = alc262_dac_nids,
12849 .hp_nid = 0x03,
12850 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12851 .channel_mode = alc262_modes,
12852 .input_mux = &alc262_capture_source,
12853 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12854 .setup = alc262_hippo_setup,
12855 .init_hook = alc262_hippo_automute,
9f99a638 12856 },
ba340e82
TV
12857 [ALC262_TYAN] = {
12858 .mixers = { alc262_tyan_mixer },
12859 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12860 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12861 .dac_nids = alc262_dac_nids,
12862 .hp_nid = 0x02,
12863 .dig_out_nid = ALC262_DIGOUT_NID,
12864 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12865 .channel_mode = alc262_modes,
12866 .input_mux = &alc262_capture_source,
a9fd4f3f 12867 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12868 .setup = alc262_tyan_setup,
12869 .init_hook = alc_automute_amp,
ba340e82 12870 },
df694daa
KY
12871};
12872
12873static int patch_alc262(struct hda_codec *codec)
12874{
12875 struct alc_spec *spec;
12876 int board_config;
12877 int err;
12878
dc041e0b 12879 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12880 if (spec == NULL)
12881 return -ENOMEM;
12882
12883 codec->spec = spec;
12884#if 0
f12ab1e0
TI
12885 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12886 * under-run
12887 */
df694daa
KY
12888 {
12889 int tmp;
12890 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12891 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12892 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12893 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12894 }
12895#endif
da00c244 12896 alc_auto_parse_customize_define(codec);
df694daa 12897
2c3bf9ab
TI
12898 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12899
f5fcc13c
TI
12900 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12901 alc262_models,
12902 alc262_cfg_tbl);
cd7509a4 12903
f5fcc13c 12904 if (board_config < 0) {
9a11f1aa
TI
12905 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12906 codec->chip_name);
df694daa
KY
12907 board_config = ALC262_AUTO;
12908 }
12909
b5bfbc67
TI
12910 if (board_config == ALC262_AUTO) {
12911 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12912 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12913 }
18675e42 12914
df694daa
KY
12915 if (board_config == ALC262_AUTO) {
12916 /* automatic parse from the BIOS config */
12917 err = alc262_parse_auto_config(codec);
12918 if (err < 0) {
12919 alc_free(codec);
12920 return err;
f12ab1e0 12921 } else if (!err) {
9c7f852e
TI
12922 printk(KERN_INFO
12923 "hda_codec: Cannot set up configuration "
12924 "from BIOS. Using base mode...\n");
df694daa
KY
12925 board_config = ALC262_BASIC;
12926 }
12927 }
12928
dc1eae25 12929 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12930 err = snd_hda_attach_beep_device(codec, 0x1);
12931 if (err < 0) {
12932 alc_free(codec);
12933 return err;
12934 }
680cd536
KK
12935 }
12936
df694daa 12937 if (board_config != ALC262_AUTO)
e9c364c0 12938 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12939
df694daa
KY
12940 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12941 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12942
df694daa
KY
12943 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12944 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12945
f12ab1e0 12946 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12947 int i;
12948 /* check whether the digital-mic has to be supported */
12949 for (i = 0; i < spec->input_mux->num_items; i++) {
12950 if (spec->input_mux->items[i].index >= 9)
12951 break;
12952 }
12953 if (i < spec->input_mux->num_items) {
12954 /* use only ADC0 */
12955 spec->adc_nids = alc262_dmic_adc_nids;
12956 spec->num_adc_nids = 1;
12957 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12958 } else {
8c927b4a
TI
12959 /* all analog inputs */
12960 /* check whether NID 0x07 is valid */
12961 unsigned int wcap = get_wcaps(codec, 0x07);
12962
12963 /* get type */
a22d543a 12964 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12965 if (wcap != AC_WID_AUD_IN) {
12966 spec->adc_nids = alc262_adc_nids_alt;
12967 spec->num_adc_nids =
12968 ARRAY_SIZE(alc262_adc_nids_alt);
12969 spec->capsrc_nids = alc262_capsrc_nids_alt;
12970 } else {
12971 spec->adc_nids = alc262_adc_nids;
12972 spec->num_adc_nids =
12973 ARRAY_SIZE(alc262_adc_nids);
12974 spec->capsrc_nids = alc262_capsrc_nids;
12975 }
df694daa
KY
12976 }
12977 }
e64f14f4 12978 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12979 set_capture_mixer(codec);
dc1eae25 12980 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12981 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12982
b5bfbc67 12983 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 12984
2134ea4f
TI
12985 spec->vmaster_nid = 0x0c;
12986
df694daa
KY
12987 codec->patch_ops = alc_patch_ops;
12988 if (board_config == ALC262_AUTO)
ae6b813a 12989 spec->init_hook = alc262_auto_init;
bf1b0225
KY
12990
12991 alc_init_jacks(codec);
cb53c626
TI
12992#ifdef CONFIG_SND_HDA_POWER_SAVE
12993 if (!spec->loopback.amplist)
12994 spec->loopback.amplist = alc262_loopbacks;
12995#endif
ea1fb29a 12996
df694daa
KY
12997 return 0;
12998}
12999
a361d84b
KY
13000/*
13001 * ALC268 channel source setting (2 channel)
13002 */
13003#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13004#define alc268_modes alc260_modes
ea1fb29a 13005
a361d84b
KY
13006static hda_nid_t alc268_dac_nids[2] = {
13007 /* front, hp */
13008 0x02, 0x03
13009};
13010
13011static hda_nid_t alc268_adc_nids[2] = {
13012 /* ADC0-1 */
13013 0x08, 0x07
13014};
13015
13016static hda_nid_t alc268_adc_nids_alt[1] = {
13017 /* ADC0 */
13018 0x08
13019};
13020
e1406348
TI
13021static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13022
a361d84b
KY
13023static struct snd_kcontrol_new alc268_base_mixer[] = {
13024 /* output mixer control */
13025 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13026 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13027 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13028 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13029 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13030 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13031 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13032 { }
13033};
13034
42171c17
TI
13035static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13036 /* output mixer control */
13037 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13038 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13039 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13040 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13041 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13042 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13043 { }
13044};
13045
aef9d318
TI
13046/* bind Beep switches of both NID 0x0f and 0x10 */
13047static struct hda_bind_ctls alc268_bind_beep_sw = {
13048 .ops = &snd_hda_bind_sw,
13049 .values = {
13050 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13051 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13052 0
13053 },
13054};
13055
13056static struct snd_kcontrol_new alc268_beep_mixer[] = {
13057 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13058 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13059 { }
13060};
13061
d1a991a6
KY
13062static struct hda_verb alc268_eapd_verbs[] = {
13063 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13064 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13065 { }
13066};
13067
d273809e 13068/* Toshiba specific */
d273809e
TI
13069static struct hda_verb alc268_toshiba_verbs[] = {
13070 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13071 { } /* end */
13072};
13073
13074/* Acer specific */
889c4395 13075/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13076static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13077 .ops = &snd_hda_bind_vol,
13078 .values = {
13079 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13080 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13081 0
13082 },
13083};
13084
889c4395
TI
13085/* mute/unmute internal speaker according to the hp jack and mute state */
13086static void alc268_acer_automute(struct hda_codec *codec, int force)
13087{
13088 struct alc_spec *spec = codec->spec;
13089 unsigned int mute;
13090
13091 if (force || !spec->sense_updated) {
864f92be 13092 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
13093 spec->sense_updated = 1;
13094 }
13095 if (spec->jack_present)
13096 mute = HDA_AMP_MUTE; /* mute internal speaker */
13097 else /* unmute internal speaker if necessary */
13098 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13099 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13100 HDA_AMP_MUTE, mute);
13101}
13102
13103
13104/* bind hp and internal speaker mute (with plug check) */
13105static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13106 struct snd_ctl_elem_value *ucontrol)
13107{
13108 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13109 long *valp = ucontrol->value.integer.value;
13110 int change;
13111
8de56b7d 13112 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13113 if (change)
13114 alc268_acer_automute(codec, 0);
13115 return change;
13116}
d273809e 13117
8ef355da
KY
13118static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13119 /* output mixer control */
13120 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13121 {
13122 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13123 .name = "Master Playback Switch",
5e26dfd0 13124 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13125 .info = snd_hda_mixer_amp_switch_info,
13126 .get = snd_hda_mixer_amp_switch_get,
13127 .put = alc268_acer_master_sw_put,
13128 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13129 },
13130 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13131 { }
13132};
13133
d273809e
TI
13134static struct snd_kcontrol_new alc268_acer_mixer[] = {
13135 /* output mixer control */
13136 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13137 {
13138 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13139 .name = "Master Playback Switch",
5e26dfd0 13140 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13141 .info = snd_hda_mixer_amp_switch_info,
13142 .get = snd_hda_mixer_amp_switch_get,
13143 .put = alc268_acer_master_sw_put,
13144 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13145 },
5f99f86a
DH
13146 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13147 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13148 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13149 { }
13150};
13151
c238b4f4
TI
13152static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13153 /* output mixer control */
13154 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13155 {
13156 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13157 .name = "Master Playback Switch",
5e26dfd0 13158 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13159 .info = snd_hda_mixer_amp_switch_info,
13160 .get = snd_hda_mixer_amp_switch_get,
13161 .put = alc268_acer_master_sw_put,
13162 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13163 },
5f99f86a
DH
13164 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13165 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13166 { }
13167};
13168
8ef355da
KY
13169static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13170 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13171 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13172 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13173 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13174 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13175 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13176 { }
13177};
13178
d273809e 13179static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13180 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13181 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13182 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13183 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13184 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13185 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13187 { }
13188};
13189
13190/* unsolicited event for HP jack sensing */
42171c17 13191#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13192#define alc268_toshiba_setup alc262_hippo_setup
13193#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13194
13195static void alc268_acer_unsol_event(struct hda_codec *codec,
13196 unsigned int res)
13197{
889c4395 13198 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13199 return;
13200 alc268_acer_automute(codec, 1);
13201}
13202
889c4395
TI
13203static void alc268_acer_init_hook(struct hda_codec *codec)
13204{
13205 alc268_acer_automute(codec, 1);
13206}
13207
8ef355da
KY
13208/* toggle speaker-output according to the hp-jack state */
13209static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13210{
13211 unsigned int present;
13212 unsigned char bits;
13213
864f92be 13214 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13215 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13216 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13217 HDA_AMP_MUTE, bits);
8ef355da 13218 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13219 HDA_AMP_MUTE, bits);
8ef355da
KY
13220}
13221
8ef355da
KY
13222static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13223 unsigned int res)
13224{
4f5d1706
TI
13225 switch (res >> 26) {
13226 case ALC880_HP_EVENT:
8ef355da 13227 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13228 break;
13229 case ALC880_MIC_EVENT:
13230 alc_mic_automute(codec);
13231 break;
13232 }
13233}
13234
13235static void alc268_acer_lc_setup(struct hda_codec *codec)
13236{
13237 struct alc_spec *spec = codec->spec;
13238 spec->ext_mic.pin = 0x18;
13239 spec->ext_mic.mux_idx = 0;
13240 spec->int_mic.pin = 0x12;
13241 spec->int_mic.mux_idx = 6;
13242 spec->auto_mic = 1;
8ef355da
KY
13243}
13244
13245static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13246{
13247 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13248 alc_mic_automute(codec);
8ef355da
KY
13249}
13250
3866f0b0
TI
13251static struct snd_kcontrol_new alc268_dell_mixer[] = {
13252 /* output mixer control */
13253 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13254 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13255 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13256 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13257 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13258 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13259 { }
13260};
13261
13262static struct hda_verb alc268_dell_verbs[] = {
13263 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13264 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13265 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13266 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13267 { }
13268};
13269
13270/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13271static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13272{
a9fd4f3f 13273 struct alc_spec *spec = codec->spec;
3866f0b0 13274
a9fd4f3f
TI
13275 spec->autocfg.hp_pins[0] = 0x15;
13276 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13277 spec->ext_mic.pin = 0x18;
13278 spec->ext_mic.mux_idx = 0;
13279 spec->int_mic.pin = 0x19;
13280 spec->int_mic.mux_idx = 1;
13281 spec->auto_mic = 1;
3866f0b0
TI
13282}
13283
eb5a6621
HRK
13284static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13285 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13286 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13287 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13288 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13289 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13290 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13291 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13292 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13293 { }
13294};
13295
13296static struct hda_verb alc267_quanta_il1_verbs[] = {
13297 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13298 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13299 { }
13300};
13301
4f5d1706 13302static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13303{
a9fd4f3f 13304 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13305 spec->autocfg.hp_pins[0] = 0x15;
13306 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13307 spec->ext_mic.pin = 0x18;
13308 spec->ext_mic.mux_idx = 0;
13309 spec->int_mic.pin = 0x19;
13310 spec->int_mic.mux_idx = 1;
13311 spec->auto_mic = 1;
eb5a6621
HRK
13312}
13313
a361d84b
KY
13314/*
13315 * generic initialization of ADC, input mixers and output mixers
13316 */
13317static struct hda_verb alc268_base_init_verbs[] = {
13318 /* Unmute DAC0-1 and set vol = 0 */
13319 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13320 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13321
13322 /*
13323 * Set up output mixers (0x0c - 0x0e)
13324 */
13325 /* set vol=0 to output mixers */
13326 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13327 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13328
13329 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13330 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13331
13332 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13333 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13334 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13335 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13336 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13337 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13338 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13339 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13340
13341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13342 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13343 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13344 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13345 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13346
13347 /* set PCBEEP vol = 0, mute connections */
13348 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13349 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13350 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13351
a9b3aa8a 13352 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13353
a9b3aa8a
JZ
13354 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13355 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13356 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13358
a361d84b
KY
13359 { }
13360};
13361
13362/*
13363 * generic initialization of ADC, input mixers and output mixers
13364 */
13365static struct hda_verb alc268_volume_init_verbs[] = {
13366 /* set output DAC */
4cfb91c6
TI
13367 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13368 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13369
13370 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13371 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13372 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13373 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13374 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13375
a361d84b 13376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13377 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13378 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13379
13380 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13381 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13382
aef9d318
TI
13383 /* set PCBEEP vol = 0, mute connections */
13384 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13385 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13386 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13387
13388 { }
13389};
13390
fdbc6626
TI
13391static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13392 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13393 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13394 { } /* end */
13395};
13396
a361d84b
KY
13397static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13398 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13399 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13400 _DEFINE_CAPSRC(1),
a361d84b
KY
13401 { } /* end */
13402};
13403
13404static struct snd_kcontrol_new alc268_capture_mixer[] = {
13405 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13406 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13407 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13408 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13409 _DEFINE_CAPSRC(2),
a361d84b
KY
13410 { } /* end */
13411};
13412
13413static struct hda_input_mux alc268_capture_source = {
13414 .num_items = 4,
13415 .items = {
13416 { "Mic", 0x0 },
13417 { "Front Mic", 0x1 },
13418 { "Line", 0x2 },
13419 { "CD", 0x3 },
13420 },
13421};
13422
0ccb541c 13423static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13424 .num_items = 3,
13425 .items = {
13426 { "Mic", 0x0 },
13427 { "Internal Mic", 0x1 },
13428 { "Line", 0x2 },
13429 },
13430};
13431
13432static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13433 .num_items = 3,
13434 .items = {
13435 { "Mic", 0x0 },
13436 { "Internal Mic", 0x6 },
13437 { "Line", 0x2 },
13438 },
13439};
13440
86c53bd2
JW
13441#ifdef CONFIG_SND_DEBUG
13442static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13443 /* Volume widgets */
13444 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13445 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13446 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13447 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13448 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13449 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13450 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13451 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13452 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13453 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13454 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13455 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13456 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13457 /* The below appears problematic on some hardwares */
13458 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13459 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13460 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13461 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13462 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13463
13464 /* Modes for retasking pin widgets */
13465 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13466 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13467 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13468 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13469
13470 /* Controls for GPIO pins, assuming they are configured as outputs */
13471 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13472 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13473 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13474 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13475
13476 /* Switches to allow the digital SPDIF output pin to be enabled.
13477 * The ALC268 does not have an SPDIF input.
13478 */
13479 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13480
13481 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13482 * this output to turn on an external amplifier.
13483 */
13484 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13485 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13486
13487 { } /* end */
13488};
13489#endif
13490
a361d84b
KY
13491/* create input playback/capture controls for the given pin */
13492static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13493 const char *ctlname, int idx)
13494{
3f3b7c1a 13495 hda_nid_t dac;
a361d84b
KY
13496 int err;
13497
3f3b7c1a
TI
13498 switch (nid) {
13499 case 0x14:
13500 case 0x16:
13501 dac = 0x02;
13502 break;
13503 case 0x15:
b08b1637
TI
13504 case 0x1a: /* ALC259/269 only */
13505 case 0x1b: /* ALC259/269 only */
531d8791 13506 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13507 dac = 0x03;
13508 break;
13509 default:
c7a9434d
TI
13510 snd_printd(KERN_WARNING "hda_codec: "
13511 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13512 return 0;
13513 }
13514 if (spec->multiout.dac_nids[0] != dac &&
13515 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13516 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13517 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13518 HDA_OUTPUT));
13519 if (err < 0)
13520 return err;
3f3b7c1a
TI
13521 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13522 }
13523
3f3b7c1a 13524 if (nid != 0x16)
0afe5f89 13525 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13526 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13527 else /* mono */
0afe5f89 13528 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13529 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13530 if (err < 0)
13531 return err;
13532 return 0;
13533}
13534
13535/* add playback controls from the parsed DAC table */
13536static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13537 const struct auto_pin_cfg *cfg)
13538{
13539 hda_nid_t nid;
13540 int err;
13541
a361d84b 13542 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13543
13544 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13545 if (nid) {
13546 const char *name;
13547 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13548 name = "Speaker";
13549 else
13550 name = "Front";
13551 err = alc268_new_analog_output(spec, nid, name, 0);
13552 if (err < 0)
13553 return err;
13554 }
a361d84b
KY
13555
13556 nid = cfg->speaker_pins[0];
13557 if (nid == 0x1d) {
0afe5f89 13558 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13559 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13560 if (err < 0)
13561 return err;
7bfb9c03 13562 } else if (nid) {
3f3b7c1a
TI
13563 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13564 if (err < 0)
13565 return err;
a361d84b
KY
13566 }
13567 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13568 if (nid) {
13569 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13570 if (err < 0)
13571 return err;
13572 }
a361d84b
KY
13573
13574 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13575 if (nid == 0x16) {
0afe5f89 13576 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13577 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13578 if (err < 0)
13579 return err;
13580 }
ea1fb29a 13581 return 0;
a361d84b
KY
13582}
13583
13584/* create playback/capture controls for input pins */
05f5f477 13585static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13586 const struct auto_pin_cfg *cfg)
13587{
05f5f477 13588 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13589}
13590
e9af4f36
TI
13591static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13592 hda_nid_t nid, int pin_type)
13593{
13594 int idx;
13595
13596 alc_set_pin_output(codec, nid, pin_type);
13597 if (nid == 0x14 || nid == 0x16)
13598 idx = 0;
13599 else
13600 idx = 1;
13601 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13602}
13603
13604static void alc268_auto_init_multi_out(struct hda_codec *codec)
13605{
13606 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13607 int i;
13608
13609 for (i = 0; i < spec->autocfg.line_outs; i++) {
13610 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13611 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13612 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13613 }
13614}
13615
13616static void alc268_auto_init_hp_out(struct hda_codec *codec)
13617{
13618 struct alc_spec *spec = codec->spec;
13619 hda_nid_t pin;
e1ca7b4e 13620 int i;
e9af4f36 13621
e1ca7b4e
TI
13622 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13623 pin = spec->autocfg.hp_pins[i];
e9af4f36 13624 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13625 }
13626 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13627 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13628 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13629 }
13630 if (spec->autocfg.mono_out_pin)
13631 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13632 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13633}
13634
a361d84b
KY
13635static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13636{
13637 struct alc_spec *spec = codec->spec;
13638 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13639 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13640 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13641 unsigned int dac_vol1, dac_vol2;
13642
e9af4f36 13643 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13644 snd_hda_codec_write(codec, speaker_nid, 0,
13645 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13646 /* mute mixer inputs from 0x1d */
a361d84b
KY
13647 snd_hda_codec_write(codec, 0x0f, 0,
13648 AC_VERB_SET_AMP_GAIN_MUTE,
13649 AMP_IN_UNMUTE(1));
13650 snd_hda_codec_write(codec, 0x10, 0,
13651 AC_VERB_SET_AMP_GAIN_MUTE,
13652 AMP_IN_UNMUTE(1));
13653 } else {
e9af4f36 13654 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13655 snd_hda_codec_write(codec, 0x0f, 0,
13656 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13657 snd_hda_codec_write(codec, 0x10, 0,
13658 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13659 }
13660
13661 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13662 if (line_nid == 0x14)
a361d84b
KY
13663 dac_vol2 = AMP_OUT_ZERO;
13664 else if (line_nid == 0x15)
13665 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13666 if (hp_nid == 0x14)
a361d84b
KY
13667 dac_vol2 = AMP_OUT_ZERO;
13668 else if (hp_nid == 0x15)
13669 dac_vol1 = AMP_OUT_ZERO;
13670 if (line_nid != 0x16 || hp_nid != 0x16 ||
13671 spec->autocfg.line_out_pins[1] != 0x16 ||
13672 spec->autocfg.line_out_pins[2] != 0x16)
13673 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13674
13675 snd_hda_codec_write(codec, 0x02, 0,
13676 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13677 snd_hda_codec_write(codec, 0x03, 0,
13678 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13679}
13680
def319f9 13681/* pcm configuration: identical with ALC880 */
a361d84b
KY
13682#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13683#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13684#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13685#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13686
13687/*
13688 * BIOS auto configuration
13689 */
13690static int alc268_parse_auto_config(struct hda_codec *codec)
13691{
13692 struct alc_spec *spec = codec->spec;
13693 int err;
13694 static hda_nid_t alc268_ignore[] = { 0 };
13695
13696 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13697 alc268_ignore);
13698 if (err < 0)
13699 return err;
7e0e44d4
TI
13700 if (!spec->autocfg.line_outs) {
13701 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13702 spec->multiout.max_channels = 2;
13703 spec->no_analog = 1;
13704 goto dig_only;
13705 }
a361d84b 13706 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13707 }
a361d84b
KY
13708 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13709 if (err < 0)
13710 return err;
05f5f477 13711 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13712 if (err < 0)
13713 return err;
13714
13715 spec->multiout.max_channels = 2;
13716
7e0e44d4 13717 dig_only:
a361d84b 13718 /* digital only support output */
757899ac 13719 alc_auto_parse_digital(codec);
603c4019 13720 if (spec->kctls.list)
d88897ea 13721 add_mixer(spec, spec->kctls.list);
a361d84b 13722
892981ff 13723 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13724 add_mixer(spec, alc268_beep_mixer);
aef9d318 13725
d88897ea 13726 add_verb(spec, alc268_volume_init_verbs);
5908589f 13727 spec->num_mux_defs = 2;
61b9b9b1 13728 spec->input_mux = &spec->private_imux[0];
a361d84b 13729
776e184e
TI
13730 err = alc_auto_add_mic_boost(codec);
13731 if (err < 0)
13732 return err;
13733
6227cdce 13734 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13735
a361d84b
KY
13736 return 1;
13737}
13738
a361d84b
KY
13739#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13740
13741/* init callback for auto-configuration model -- overriding the default init */
13742static void alc268_auto_init(struct hda_codec *codec)
13743{
f6c7e546 13744 struct alc_spec *spec = codec->spec;
a361d84b
KY
13745 alc268_auto_init_multi_out(codec);
13746 alc268_auto_init_hp_out(codec);
13747 alc268_auto_init_mono_speaker_out(codec);
13748 alc268_auto_init_analog_input(codec);
757899ac 13749 alc_auto_init_digital(codec);
f6c7e546 13750 if (spec->unsol_event)
7fb0d78f 13751 alc_inithook(codec);
a361d84b
KY
13752}
13753
13754/*
13755 * configuration and preset
13756 */
ea734963 13757static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13758 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13759 [ALC268_3ST] = "3stack",
983f8ae4 13760 [ALC268_TOSHIBA] = "toshiba",
d273809e 13761 [ALC268_ACER] = "acer",
c238b4f4 13762 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13763 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13764 [ALC268_DELL] = "dell",
f12462c5 13765 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13766#ifdef CONFIG_SND_DEBUG
13767 [ALC268_TEST] = "test",
13768#endif
a361d84b
KY
13769 [ALC268_AUTO] = "auto",
13770};
13771
13772static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13773 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13774 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13775 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13776 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13777 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13778 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13779 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13780 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13781 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13782 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13783 /* almost compatible with toshiba but with optional digital outs;
13784 * auto-probing seems working fine
13785 */
8871e5b9 13786 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13787 ALC268_AUTO),
a361d84b 13788 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13789 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13790 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13791 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13792 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13793 {}
13794};
13795
3abf2f36
TI
13796/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13797static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13798 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13799 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13800 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13801 ALC268_TOSHIBA),
13802 {}
13803};
13804
a361d84b 13805static struct alc_config_preset alc268_presets[] = {
eb5a6621 13806 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13807 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13808 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13809 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13810 alc267_quanta_il1_verbs },
13811 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13812 .dac_nids = alc268_dac_nids,
13813 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13814 .adc_nids = alc268_adc_nids_alt,
13815 .hp_nid = 0x03,
13816 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13817 .channel_mode = alc268_modes,
4f5d1706
TI
13818 .unsol_event = alc_sku_unsol_event,
13819 .setup = alc267_quanta_il1_setup,
13820 .init_hook = alc_inithook,
eb5a6621 13821 },
a361d84b 13822 [ALC268_3ST] = {
aef9d318
TI
13823 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13824 alc268_beep_mixer },
a361d84b
KY
13825 .init_verbs = { alc268_base_init_verbs },
13826 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13827 .dac_nids = alc268_dac_nids,
13828 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13829 .adc_nids = alc268_adc_nids_alt,
e1406348 13830 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13831 .hp_nid = 0x03,
13832 .dig_out_nid = ALC268_DIGOUT_NID,
13833 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13834 .channel_mode = alc268_modes,
13835 .input_mux = &alc268_capture_source,
13836 },
d1a991a6 13837 [ALC268_TOSHIBA] = {
42171c17 13838 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13839 alc268_beep_mixer },
d273809e
TI
13840 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13841 alc268_toshiba_verbs },
d1a991a6
KY
13842 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13843 .dac_nids = alc268_dac_nids,
13844 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13845 .adc_nids = alc268_adc_nids_alt,
e1406348 13846 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13847 .hp_nid = 0x03,
13848 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13849 .channel_mode = alc268_modes,
13850 .input_mux = &alc268_capture_source,
d273809e 13851 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13852 .setup = alc268_toshiba_setup,
13853 .init_hook = alc268_toshiba_automute,
d273809e
TI
13854 },
13855 [ALC268_ACER] = {
432fd133 13856 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13857 alc268_beep_mixer },
d273809e
TI
13858 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13859 alc268_acer_verbs },
13860 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13861 .dac_nids = alc268_dac_nids,
13862 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13863 .adc_nids = alc268_adc_nids_alt,
e1406348 13864 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13865 .hp_nid = 0x02,
13866 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13867 .channel_mode = alc268_modes,
0ccb541c 13868 .input_mux = &alc268_acer_capture_source,
d273809e 13869 .unsol_event = alc268_acer_unsol_event,
889c4395 13870 .init_hook = alc268_acer_init_hook,
d1a991a6 13871 },
c238b4f4
TI
13872 [ALC268_ACER_DMIC] = {
13873 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13874 alc268_beep_mixer },
13875 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13876 alc268_acer_verbs },
13877 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13878 .dac_nids = alc268_dac_nids,
13879 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13880 .adc_nids = alc268_adc_nids_alt,
13881 .capsrc_nids = alc268_capsrc_nids,
13882 .hp_nid = 0x02,
13883 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13884 .channel_mode = alc268_modes,
13885 .input_mux = &alc268_acer_dmic_capture_source,
13886 .unsol_event = alc268_acer_unsol_event,
13887 .init_hook = alc268_acer_init_hook,
13888 },
8ef355da
KY
13889 [ALC268_ACER_ASPIRE_ONE] = {
13890 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13891 alc268_beep_mixer,
fdbc6626 13892 alc268_capture_nosrc_mixer },
8ef355da
KY
13893 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13894 alc268_acer_aspire_one_verbs },
13895 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13896 .dac_nids = alc268_dac_nids,
13897 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13898 .adc_nids = alc268_adc_nids_alt,
13899 .capsrc_nids = alc268_capsrc_nids,
13900 .hp_nid = 0x03,
13901 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13902 .channel_mode = alc268_modes,
8ef355da 13903 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13904 .setup = alc268_acer_lc_setup,
8ef355da
KY
13905 .init_hook = alc268_acer_lc_init_hook,
13906 },
3866f0b0 13907 [ALC268_DELL] = {
fdbc6626
TI
13908 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13909 alc268_capture_nosrc_mixer },
3866f0b0
TI
13910 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13911 alc268_dell_verbs },
13912 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13913 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13914 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13915 .adc_nids = alc268_adc_nids_alt,
13916 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13917 .hp_nid = 0x02,
13918 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13919 .channel_mode = alc268_modes,
a9fd4f3f 13920 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13921 .setup = alc268_dell_setup,
13922 .init_hook = alc_inithook,
3866f0b0 13923 },
f12462c5 13924 [ALC268_ZEPTO] = {
aef9d318
TI
13925 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13926 alc268_beep_mixer },
f12462c5
MT
13927 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13928 alc268_toshiba_verbs },
13929 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13930 .dac_nids = alc268_dac_nids,
13931 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13932 .adc_nids = alc268_adc_nids_alt,
e1406348 13933 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13934 .hp_nid = 0x03,
13935 .dig_out_nid = ALC268_DIGOUT_NID,
13936 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13937 .channel_mode = alc268_modes,
13938 .input_mux = &alc268_capture_source,
4f5d1706
TI
13939 .setup = alc268_toshiba_setup,
13940 .init_hook = alc268_toshiba_automute,
f12462c5 13941 },
86c53bd2
JW
13942#ifdef CONFIG_SND_DEBUG
13943 [ALC268_TEST] = {
13944 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13945 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13946 alc268_volume_init_verbs },
13947 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13948 .dac_nids = alc268_dac_nids,
13949 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13950 .adc_nids = alc268_adc_nids_alt,
e1406348 13951 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13952 .hp_nid = 0x03,
13953 .dig_out_nid = ALC268_DIGOUT_NID,
13954 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13955 .channel_mode = alc268_modes,
13956 .input_mux = &alc268_capture_source,
13957 },
13958#endif
a361d84b
KY
13959};
13960
13961static int patch_alc268(struct hda_codec *codec)
13962{
13963 struct alc_spec *spec;
13964 int board_config;
22971e3a 13965 int i, has_beep, err;
a361d84b 13966
ef86f581 13967 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13968 if (spec == NULL)
13969 return -ENOMEM;
13970
13971 codec->spec = spec;
13972
13973 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13974 alc268_models,
13975 alc268_cfg_tbl);
13976
3abf2f36
TI
13977 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13978 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13979 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13980
a361d84b 13981 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13982 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13983 codec->chip_name);
a361d84b
KY
13984 board_config = ALC268_AUTO;
13985 }
13986
13987 if (board_config == ALC268_AUTO) {
13988 /* automatic parse from the BIOS config */
13989 err = alc268_parse_auto_config(codec);
13990 if (err < 0) {
13991 alc_free(codec);
13992 return err;
13993 } else if (!err) {
13994 printk(KERN_INFO
13995 "hda_codec: Cannot set up configuration "
13996 "from BIOS. Using base mode...\n");
13997 board_config = ALC268_3ST;
13998 }
13999 }
14000
14001 if (board_config != ALC268_AUTO)
e9c364c0 14002 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14003
a361d84b
KY
14004 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14005 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14006 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14007
a361d84b
KY
14008 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14009
22971e3a
TI
14010 has_beep = 0;
14011 for (i = 0; i < spec->num_mixers; i++) {
14012 if (spec->mixers[i] == alc268_beep_mixer) {
14013 has_beep = 1;
14014 break;
14015 }
14016 }
14017
14018 if (has_beep) {
14019 err = snd_hda_attach_beep_device(codec, 0x1);
14020 if (err < 0) {
14021 alc_free(codec);
14022 return err;
14023 }
14024 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14025 /* override the amp caps for beep generator */
14026 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14027 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14028 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14029 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14030 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14031 }
aef9d318 14032
7e0e44d4 14033 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14034 /* check whether NID 0x07 is valid */
14035 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 14036 int i;
3866f0b0 14037
defb5ab2 14038 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14039 /* get type */
a22d543a 14040 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14041 if (spec->auto_mic ||
14042 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14043 spec->adc_nids = alc268_adc_nids_alt;
14044 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14045 if (spec->auto_mic)
14046 fixup_automic_adc(codec);
fdbc6626
TI
14047 if (spec->auto_mic || spec->input_mux->num_items == 1)
14048 add_mixer(spec, alc268_capture_nosrc_mixer);
14049 else
14050 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14051 } else {
14052 spec->adc_nids = alc268_adc_nids;
14053 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14054 add_mixer(spec, alc268_capture_mixer);
a361d84b 14055 }
85860c06
TI
14056 /* set default input source */
14057 for (i = 0; i < spec->num_adc_nids; i++)
14058 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14059 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
14060 i < spec->num_mux_defs ?
14061 spec->input_mux[i].items[0].index :
85860c06 14062 spec->input_mux->items[0].index);
a361d84b 14063 }
2134ea4f
TI
14064
14065 spec->vmaster_nid = 0x02;
14066
a361d84b
KY
14067 codec->patch_ops = alc_patch_ops;
14068 if (board_config == ALC268_AUTO)
14069 spec->init_hook = alc268_auto_init;
ea1fb29a 14070
bf1b0225
KY
14071 alc_init_jacks(codec);
14072
a361d84b
KY
14073 return 0;
14074}
14075
f6a92248
KY
14076/*
14077 * ALC269 channel source setting (2 channel)
14078 */
14079#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14080
14081#define alc269_dac_nids alc260_dac_nids
14082
14083static hda_nid_t alc269_adc_nids[1] = {
14084 /* ADC1 */
f53281e6
KY
14085 0x08,
14086};
14087
e01bf509
TI
14088static hda_nid_t alc269_capsrc_nids[1] = {
14089 0x23,
14090};
14091
84898e87
KY
14092static hda_nid_t alc269vb_adc_nids[1] = {
14093 /* ADC1 */
14094 0x09,
14095};
14096
14097static hda_nid_t alc269vb_capsrc_nids[1] = {
14098 0x22,
14099};
14100
6694635d
TI
14101static hda_nid_t alc269_adc_candidates[] = {
14102 0x08, 0x09, 0x07,
14103};
e01bf509 14104
f6a92248
KY
14105#define alc269_modes alc260_modes
14106#define alc269_capture_source alc880_lg_lw_capture_source
14107
14108static struct snd_kcontrol_new alc269_base_mixer[] = {
14109 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14110 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14111 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14112 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14114 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14116 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14117 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14118 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14119 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14120 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14121 { } /* end */
14122};
14123
60db6b53
KY
14124static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14125 /* output mixer control */
14126 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14127 {
14128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14129 .name = "Master Playback Switch",
5e26dfd0 14130 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14131 .info = snd_hda_mixer_amp_switch_info,
14132 .get = snd_hda_mixer_amp_switch_get,
14133 .put = alc268_acer_master_sw_put,
14134 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14135 },
14136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14138 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14139 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14140 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14141 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14142 { }
14143};
14144
64154835
TV
14145static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14146 /* output mixer control */
14147 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14148 {
14149 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14150 .name = "Master Playback Switch",
5e26dfd0 14151 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14152 .info = snd_hda_mixer_amp_switch_info,
14153 .get = snd_hda_mixer_amp_switch_get,
14154 .put = alc268_acer_master_sw_put,
14155 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14156 },
14157 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14159 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14160 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14161 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14162 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14163 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14164 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14165 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14166 { }
14167};
14168
84898e87 14169static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14170 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14171 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14172 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14173 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14174 { } /* end */
14175};
14176
84898e87
KY
14177static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14178 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14179 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14180 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14181 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14182 { } /* end */
14183};
14184
fe3eb0a7
KY
14185static struct snd_kcontrol_new alc269_asus_mixer[] = {
14186 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14187 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14188 { } /* end */
14189};
14190
f53281e6 14191/* capture mixer elements */
84898e87
KY
14192static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14193 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14194 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14195 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14196 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14197 { } /* end */
14198};
14199
14200static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14201 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14202 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14203 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14204 { } /* end */
14205};
14206
84898e87
KY
14207static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14208 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14209 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14210 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14211 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14212 { } /* end */
14213};
14214
14215static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14216 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14217 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14218 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14219 { } /* end */
14220};
14221
26f5df26 14222/* FSC amilo */
84898e87 14223#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14224
60db6b53
KY
14225static struct hda_verb alc269_quanta_fl1_verbs[] = {
14226 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14227 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14228 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14229 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14230 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14231 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14232 { }
14233};
f6a92248 14234
64154835
TV
14235static struct hda_verb alc269_lifebook_verbs[] = {
14236 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14237 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14238 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14239 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14240 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14241 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14242 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14243 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14244 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14245 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14246 { }
14247};
14248
60db6b53
KY
14249/* toggle speaker-output according to the hp-jack state */
14250static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14251{
14252 unsigned int present;
14253 unsigned char bits;
f6a92248 14254
864f92be 14255 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14256 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14257 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14258 HDA_AMP_MUTE, bits);
60db6b53 14259 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14260 HDA_AMP_MUTE, bits);
f6a92248 14261
60db6b53
KY
14262 snd_hda_codec_write(codec, 0x20, 0,
14263 AC_VERB_SET_COEF_INDEX, 0x0c);
14264 snd_hda_codec_write(codec, 0x20, 0,
14265 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14266
60db6b53
KY
14267 snd_hda_codec_write(codec, 0x20, 0,
14268 AC_VERB_SET_COEF_INDEX, 0x0c);
14269 snd_hda_codec_write(codec, 0x20, 0,
14270 AC_VERB_SET_PROC_COEF, 0x480);
14271}
f6a92248 14272
64154835
TV
14273/* toggle speaker-output according to the hp-jacks state */
14274static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14275{
14276 unsigned int present;
14277 unsigned char bits;
14278
14279 /* Check laptop headphone socket */
864f92be 14280 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14281
14282 /* Check port replicator headphone socket */
864f92be 14283 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14284
5dbd5ec6 14285 bits = present ? HDA_AMP_MUTE : 0;
64154835 14286 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14287 HDA_AMP_MUTE, bits);
64154835 14288 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14289 HDA_AMP_MUTE, bits);
64154835
TV
14290
14291 snd_hda_codec_write(codec, 0x20, 0,
14292 AC_VERB_SET_COEF_INDEX, 0x0c);
14293 snd_hda_codec_write(codec, 0x20, 0,
14294 AC_VERB_SET_PROC_COEF, 0x680);
14295
14296 snd_hda_codec_write(codec, 0x20, 0,
14297 AC_VERB_SET_COEF_INDEX, 0x0c);
14298 snd_hda_codec_write(codec, 0x20, 0,
14299 AC_VERB_SET_PROC_COEF, 0x480);
14300}
14301
64154835
TV
14302static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14303{
14304 unsigned int present_laptop;
14305 unsigned int present_dock;
14306
864f92be
WF
14307 present_laptop = snd_hda_jack_detect(codec, 0x18);
14308 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14309
14310 /* Laptop mic port overrides dock mic port, design decision */
14311 if (present_dock)
14312 snd_hda_codec_write(codec, 0x23, 0,
14313 AC_VERB_SET_CONNECT_SEL, 0x3);
14314 if (present_laptop)
14315 snd_hda_codec_write(codec, 0x23, 0,
14316 AC_VERB_SET_CONNECT_SEL, 0x0);
14317 if (!present_dock && !present_laptop)
14318 snd_hda_codec_write(codec, 0x23, 0,
14319 AC_VERB_SET_CONNECT_SEL, 0x1);
14320}
14321
60db6b53
KY
14322static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14323 unsigned int res)
14324{
4f5d1706
TI
14325 switch (res >> 26) {
14326 case ALC880_HP_EVENT:
60db6b53 14327 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14328 break;
14329 case ALC880_MIC_EVENT:
14330 alc_mic_automute(codec);
14331 break;
14332 }
60db6b53 14333}
f6a92248 14334
64154835
TV
14335static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14336 unsigned int res)
14337{
14338 if ((res >> 26) == ALC880_HP_EVENT)
14339 alc269_lifebook_speaker_automute(codec);
14340 if ((res >> 26) == ALC880_MIC_EVENT)
14341 alc269_lifebook_mic_autoswitch(codec);
14342}
14343
4f5d1706
TI
14344static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14345{
14346 struct alc_spec *spec = codec->spec;
20645d70
TI
14347 spec->autocfg.hp_pins[0] = 0x15;
14348 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14349 spec->ext_mic.pin = 0x18;
14350 spec->ext_mic.mux_idx = 0;
14351 spec->int_mic.pin = 0x19;
14352 spec->int_mic.mux_idx = 1;
14353 spec->auto_mic = 1;
14354}
14355
60db6b53
KY
14356static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14357{
14358 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14359 alc_mic_automute(codec);
60db6b53 14360}
f6a92248 14361
64154835
TV
14362static void alc269_lifebook_init_hook(struct hda_codec *codec)
14363{
14364 alc269_lifebook_speaker_automute(codec);
14365 alc269_lifebook_mic_autoswitch(codec);
14366}
14367
84898e87 14368static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14369 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14370 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14371 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14372 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14373 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14374 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14375 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14376 {}
14377};
14378
84898e87 14379static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14380 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14381 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14382 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14383 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14384 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14385 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14386 {}
14387};
14388
84898e87
KY
14389static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14390 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14391 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14392 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14394 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14395 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14396 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14397 {}
14398};
14399
14400static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14401 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14402 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14403 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14404 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14405 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14406 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14407 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14408 {}
14409};
14410
fe3eb0a7
KY
14411static struct hda_verb alc271_acer_dmic_verbs[] = {
14412 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14413 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14414 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14415 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14416 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14417 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14418 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14419 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14420 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14421 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14422 { }
14423};
14424
f53281e6
KY
14425/* toggle speaker-output according to the hp-jack state */
14426static void alc269_speaker_automute(struct hda_codec *codec)
14427{
ebb83eeb
KY
14428 struct alc_spec *spec = codec->spec;
14429 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14430 unsigned int present;
60db6b53 14431 unsigned char bits;
f53281e6 14432
ebb83eeb 14433 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14434 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14435 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14436 HDA_AMP_MUTE, bits);
f53281e6 14437 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14438 HDA_AMP_MUTE, bits);
cd372fb3 14439 snd_hda_input_jack_report(codec, nid);
f53281e6
KY
14440}
14441
f53281e6 14442/* unsolicited event for HP jack sensing */
84898e87 14443static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14444 unsigned int res)
f53281e6 14445{
4f5d1706
TI
14446 switch (res >> 26) {
14447 case ALC880_HP_EVENT:
f53281e6 14448 alc269_speaker_automute(codec);
4f5d1706
TI
14449 break;
14450 case ALC880_MIC_EVENT:
14451 alc_mic_automute(codec);
14452 break;
14453 }
f53281e6
KY
14454}
14455
226b1ec8 14456static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14457{
4f5d1706 14458 struct alc_spec *spec = codec->spec;
20645d70
TI
14459 spec->autocfg.hp_pins[0] = 0x15;
14460 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14461 spec->ext_mic.pin = 0x18;
14462 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14463 spec->int_mic.pin = 0x19;
14464 spec->int_mic.mux_idx = 1;
4f5d1706 14465 spec->auto_mic = 1;
f53281e6
KY
14466}
14467
226b1ec8 14468static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14469{
14470 struct alc_spec *spec = codec->spec;
20645d70
TI
14471 spec->autocfg.hp_pins[0] = 0x15;
14472 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14473 spec->ext_mic.pin = 0x18;
14474 spec->ext_mic.mux_idx = 0;
14475 spec->int_mic.pin = 0x12;
226b1ec8 14476 spec->int_mic.mux_idx = 5;
84898e87
KY
14477 spec->auto_mic = 1;
14478}
14479
226b1ec8 14480static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14481{
4f5d1706 14482 struct alc_spec *spec = codec->spec;
226b1ec8 14483 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14484 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14485 spec->ext_mic.pin = 0x18;
14486 spec->ext_mic.mux_idx = 0;
14487 spec->int_mic.pin = 0x19;
14488 spec->int_mic.mux_idx = 1;
14489 spec->auto_mic = 1;
f53281e6
KY
14490}
14491
226b1ec8
KY
14492static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14493{
14494 struct alc_spec *spec = codec->spec;
14495 spec->autocfg.hp_pins[0] = 0x21;
14496 spec->autocfg.speaker_pins[0] = 0x14;
14497 spec->ext_mic.pin = 0x18;
14498 spec->ext_mic.mux_idx = 0;
14499 spec->int_mic.pin = 0x12;
14500 spec->int_mic.mux_idx = 6;
14501 spec->auto_mic = 1;
14502}
14503
84898e87 14504static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14505{
14506 alc269_speaker_automute(codec);
4f5d1706 14507 alc_mic_automute(codec);
f53281e6
KY
14508}
14509
60db6b53
KY
14510/*
14511 * generic initialization of ADC, input mixers and output mixers
14512 */
14513static struct hda_verb alc269_init_verbs[] = {
14514 /*
14515 * Unmute ADC0 and set the default input to mic-in
14516 */
84898e87 14517 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14518
14519 /*
84898e87 14520 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14521 */
14522 /* set vol=0 to output mixers */
14523 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14524 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14525
14526 /* set up input amps for analog loopback */
14527 /* Amp Indices: DAC = 0, mixer = 1 */
14528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14529 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14530 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14531 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14532 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14533 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14534
14535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14536 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14538 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14539 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14540 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14541 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14542
14543 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14544 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14545
84898e87
KY
14546 /* FIXME: use Mux-type input source selection */
14547 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14548 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14549 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14550
84898e87
KY
14551 /* set EAPD */
14552 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14553 { }
14554};
14555
14556static struct hda_verb alc269vb_init_verbs[] = {
14557 /*
14558 * Unmute ADC0 and set the default input to mic-in
14559 */
14560 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14561
14562 /*
14563 * Set up output mixers (0x02 - 0x03)
14564 */
14565 /* set vol=0 to output mixers */
14566 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14567 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14568
14569 /* set up input amps for analog loopback */
14570 /* Amp Indices: DAC = 0, mixer = 1 */
14571 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14573 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14574 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14575 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14576 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14577
14578 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14579 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14580 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14582 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14583 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14584 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14585
14586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14587 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14588
14589 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14590 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14591 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14592 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14593
14594 /* set EAPD */
14595 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14596 { }
14597};
14598
9d0b71b1
TI
14599#define alc269_auto_create_multi_out_ctls \
14600 alc268_auto_create_multi_out_ctls
05f5f477
TI
14601#define alc269_auto_create_input_ctls \
14602 alc268_auto_create_input_ctls
f6a92248
KY
14603
14604#ifdef CONFIG_SND_HDA_POWER_SAVE
14605#define alc269_loopbacks alc880_loopbacks
14606#endif
14607
def319f9 14608/* pcm configuration: identical with ALC880 */
f6a92248
KY
14609#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14610#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14611#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14612#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14613
f03d3115
TI
14614static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14615 .substreams = 1,
14616 .channels_min = 2,
14617 .channels_max = 8,
14618 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14619 /* NID is set in alc_build_pcms */
14620 .ops = {
14621 .open = alc880_playback_pcm_open,
14622 .prepare = alc880_playback_pcm_prepare,
14623 .cleanup = alc880_playback_pcm_cleanup
14624 },
14625};
14626
14627static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14628 .substreams = 1,
14629 .channels_min = 2,
14630 .channels_max = 2,
14631 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14632 /* NID is set in alc_build_pcms */
14633};
14634
ad35879a
TI
14635#ifdef CONFIG_SND_HDA_POWER_SAVE
14636static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14637{
14638 switch (codec->subsystem_id) {
14639 case 0x103c1586:
14640 return 1;
14641 }
14642 return 0;
14643}
14644
14645static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14646{
14647 /* update mute-LED according to the speaker mute state */
14648 if (nid == 0x01 || nid == 0x14) {
14649 int pinval;
14650 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14651 HDA_AMP_MUTE)
14652 pinval = 0x24;
14653 else
14654 pinval = 0x20;
14655 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14656 snd_hda_codec_update_cache(codec, 0x19, 0,
14657 AC_VERB_SET_PIN_WIDGET_CONTROL,
14658 pinval);
ad35879a
TI
14659 }
14660 return alc_check_power_status(codec, nid);
14661}
14662#endif /* CONFIG_SND_HDA_POWER_SAVE */
14663
840b64c0
TI
14664static int alc275_setup_dual_adc(struct hda_codec *codec)
14665{
14666 struct alc_spec *spec = codec->spec;
14667
14668 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14669 return 0;
14670 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14671 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14672 if (spec->ext_mic.pin <= 0x12) {
14673 spec->private_adc_nids[0] = 0x08;
14674 spec->private_adc_nids[1] = 0x11;
14675 spec->private_capsrc_nids[0] = 0x23;
14676 spec->private_capsrc_nids[1] = 0x22;
14677 } else {
14678 spec->private_adc_nids[0] = 0x11;
14679 spec->private_adc_nids[1] = 0x08;
14680 spec->private_capsrc_nids[0] = 0x22;
14681 spec->private_capsrc_nids[1] = 0x23;
14682 }
14683 spec->adc_nids = spec->private_adc_nids;
14684 spec->capsrc_nids = spec->private_capsrc_nids;
14685 spec->num_adc_nids = 2;
14686 spec->dual_adc_switch = 1;
14687 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14688 spec->adc_nids[0], spec->adc_nids[1]);
14689 return 1;
14690 }
14691 return 0;
14692}
14693
d433a678
TI
14694/* different alc269-variants */
14695enum {
14696 ALC269_TYPE_NORMAL,
48c88e82 14697 ALC269_TYPE_ALC258,
d433a678 14698 ALC269_TYPE_ALC259,
48c88e82
KY
14699 ALC269_TYPE_ALC269VB,
14700 ALC269_TYPE_ALC270,
d433a678
TI
14701 ALC269_TYPE_ALC271X,
14702};
14703
f6a92248
KY
14704/*
14705 * BIOS auto configuration
14706 */
14707static int alc269_parse_auto_config(struct hda_codec *codec)
14708{
14709 struct alc_spec *spec = codec->spec;
cfb9fb55 14710 int err;
f6a92248
KY
14711 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14712
14713 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14714 alc269_ignore);
14715 if (err < 0)
14716 return err;
14717
14718 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14719 if (err < 0)
14720 return err;
f3550d1b
TI
14721 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14722 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14723 else
14724 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14725 0x22, 0);
f6a92248
KY
14726 if (err < 0)
14727 return err;
14728
14729 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14730
757899ac 14731 alc_auto_parse_digital(codec);
f6a92248 14732
603c4019 14733 if (spec->kctls.list)
d88897ea 14734 add_mixer(spec, spec->kctls.list);
f6a92248 14735
d433a678 14736 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14737 add_verb(spec, alc269vb_init_verbs);
6227cdce 14738 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14739 } else {
14740 add_verb(spec, alc269_init_verbs);
6227cdce 14741 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14742 }
14743
f6a92248 14744 spec->num_mux_defs = 1;
61b9b9b1 14745 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14746
14747 if (!alc275_setup_dual_adc(codec))
14748 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14749 sizeof(alc269_adc_candidates));
6694635d 14750
e01bf509 14751 /* set default input source */
840b64c0 14752 if (!spec->dual_adc_switch)
748cce43
TI
14753 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14754 spec->input_mux->items[0].index);
f6a92248
KY
14755
14756 err = alc_auto_add_mic_boost(codec);
14757 if (err < 0)
14758 return err;
14759
7e0e44d4 14760 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14761 set_capture_mixer(codec);
f53281e6 14762
f6a92248
KY
14763 return 1;
14764}
14765
e9af4f36
TI
14766#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14767#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14768#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14769
14770
14771/* init callback for auto-configuration model -- overriding the default init */
14772static void alc269_auto_init(struct hda_codec *codec)
14773{
f6c7e546 14774 struct alc_spec *spec = codec->spec;
f6a92248
KY
14775 alc269_auto_init_multi_out(codec);
14776 alc269_auto_init_hp_out(codec);
14777 alc269_auto_init_analog_input(codec);
757899ac 14778 alc_auto_init_digital(codec);
f6c7e546 14779 if (spec->unsol_event)
7fb0d78f 14780 alc_inithook(codec);
f6a92248
KY
14781}
14782
0ec33d1f
TI
14783#ifdef SND_HDA_NEEDS_RESUME
14784static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14785{
14786 int val = alc_read_coef_idx(codec, 0x04);
14787 if (power_up)
14788 val |= 1 << 11;
14789 else
14790 val &= ~(1 << 11);
14791 alc_write_coef_idx(codec, 0x04, val);
14792}
14793
977ddd6b
KY
14794#ifdef CONFIG_SND_HDA_POWER_SAVE
14795static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14796{
14797 struct alc_spec *spec = codec->spec;
977ddd6b 14798
0ec33d1f
TI
14799 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14800 alc269_toggle_power_output(codec, 0);
977ddd6b 14801 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14802 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14803 msleep(150);
14804 }
14805
14806 alc_shutup(codec);
14807 if (spec && spec->power_hook)
14808 spec->power_hook(codec);
14809 return 0;
14810}
0ec33d1f
TI
14811#endif /* CONFIG_SND_HDA_POWER_SAVE */
14812
977ddd6b
KY
14813static int alc269_resume(struct hda_codec *codec)
14814{
977ddd6b 14815 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14816 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14817 msleep(150);
14818 }
14819
14820 codec->patch_ops.init(codec);
14821
14822 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14823 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14824 msleep(200);
14825 }
14826
0ec33d1f
TI
14827 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14828 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14829
14830 snd_hda_codec_resume_amp(codec);
14831 snd_hda_codec_resume_cache(codec);
9e5341b9 14832 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14833 return 0;
14834}
0ec33d1f 14835#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14836
1a99d4a4 14837static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14838 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14839{
14840 int coef;
14841
58701120 14842 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14843 return;
1a99d4a4
KY
14844 coef = alc_read_coef_idx(codec, 0x1e);
14845 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14846}
14847
ff818c24
TI
14848enum {
14849 ALC269_FIXUP_SONY_VAIO,
74dc8909 14850 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14851 ALC269_FIXUP_DELL_M101Z,
022c92be 14852 ALC269_FIXUP_SKU_IGNORE,
ac612407 14853 ALC269_FIXUP_ASUS_G73JW,
357f915e 14854 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14855 ALC275_FIXUP_SONY_HWEQ,
ff818c24
TI
14856};
14857
ff818c24
TI
14858static const struct alc_fixup alc269_fixups[] = {
14859 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14860 .type = ALC_FIXUP_VERBS,
14861 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14862 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14863 {}
14864 }
ff818c24 14865 },
74dc8909 14866 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14867 .type = ALC_FIXUP_VERBS,
14868 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14869 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14870 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14871 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14872 { }
b5bfbc67
TI
14873 },
14874 .chained = true,
14875 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14876 },
145a902b 14877 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14878 .type = ALC_FIXUP_VERBS,
14879 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14880 /* Enables internal speaker */
14881 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14882 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14883 {}
14884 }
14885 },
022c92be 14886 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14887 .type = ALC_FIXUP_SKU,
14888 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14889 },
ac612407 14890 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14891 .type = ALC_FIXUP_PINS,
14892 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14893 { 0x17, 0x99130111 }, /* subwoofer */
14894 { }
14895 }
14896 },
357f915e 14897 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14898 .type = ALC_FIXUP_VERBS,
14899 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14900 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14901 {}
14902 }
14903 },
1a99d4a4 14904 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14905 .type = ALC_FIXUP_FUNC,
14906 .v.func = alc269_fixup_hweq,
14907 .chained = true,
14908 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
1a99d4a4 14909 }
ff818c24
TI
14910};
14911
14912static struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14913 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14914 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14915 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14916 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14917 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
022c92be 14918 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14919 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14920 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14921 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14922 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14923 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14924 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14925 {}
14926};
14927
14928
f6a92248
KY
14929/*
14930 * configuration and preset
14931 */
ea734963 14932static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14933 [ALC269_BASIC] = "basic",
2922c9af 14934 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14935 [ALC269_AMIC] = "laptop-amic",
14936 [ALC269_DMIC] = "laptop-dmic",
64154835 14937 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14938 [ALC269_LIFEBOOK] = "lifebook",
14939 [ALC269_AUTO] = "auto",
f6a92248
KY
14940};
14941
14942static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14943 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14944 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14945 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14946 ALC269_AMIC),
14947 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14948 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14949 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14950 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14951 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14952 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14953 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14954 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14955 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14956 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14957 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14958 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14959 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14960 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14961 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14962 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14963 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14964 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14965 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14966 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14967 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14968 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14969 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14970 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14971 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14972 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14973 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14974 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14975 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14976 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14977 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14978 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14979 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14980 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14981 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14982 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14983 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14984 ALC269_DMIC),
60db6b53 14985 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14986 ALC269_DMIC),
14987 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14988 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14989 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14990 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14991 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14992 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14993 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14994 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14995 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14996 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14997 {}
14998};
14999
15000static struct alc_config_preset alc269_presets[] = {
15001 [ALC269_BASIC] = {
f9e336f6 15002 .mixers = { alc269_base_mixer },
f6a92248
KY
15003 .init_verbs = { alc269_init_verbs },
15004 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15005 .dac_nids = alc269_dac_nids,
15006 .hp_nid = 0x03,
15007 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15008 .channel_mode = alc269_modes,
15009 .input_mux = &alc269_capture_source,
15010 },
60db6b53
KY
15011 [ALC269_QUANTA_FL1] = {
15012 .mixers = { alc269_quanta_fl1_mixer },
15013 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15014 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15015 .dac_nids = alc269_dac_nids,
15016 .hp_nid = 0x03,
15017 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15018 .channel_mode = alc269_modes,
15019 .input_mux = &alc269_capture_source,
15020 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15021 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15022 .init_hook = alc269_quanta_fl1_init_hook,
15023 },
84898e87
KY
15024 [ALC269_AMIC] = {
15025 .mixers = { alc269_laptop_mixer },
15026 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15027 .init_verbs = { alc269_init_verbs,
84898e87 15028 alc269_laptop_amic_init_verbs },
f53281e6
KY
15029 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15030 .dac_nids = alc269_dac_nids,
15031 .hp_nid = 0x03,
15032 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15033 .channel_mode = alc269_modes,
84898e87
KY
15034 .unsol_event = alc269_laptop_unsol_event,
15035 .setup = alc269_laptop_amic_setup,
15036 .init_hook = alc269_laptop_inithook,
f53281e6 15037 },
84898e87
KY
15038 [ALC269_DMIC] = {
15039 .mixers = { alc269_laptop_mixer },
15040 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15041 .init_verbs = { alc269_init_verbs,
84898e87
KY
15042 alc269_laptop_dmic_init_verbs },
15043 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15044 .dac_nids = alc269_dac_nids,
15045 .hp_nid = 0x03,
15046 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15047 .channel_mode = alc269_modes,
15048 .unsol_event = alc269_laptop_unsol_event,
15049 .setup = alc269_laptop_dmic_setup,
15050 .init_hook = alc269_laptop_inithook,
15051 },
15052 [ALC269VB_AMIC] = {
15053 .mixers = { alc269vb_laptop_mixer },
15054 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15055 .init_verbs = { alc269vb_init_verbs,
15056 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15057 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15058 .dac_nids = alc269_dac_nids,
15059 .hp_nid = 0x03,
15060 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15061 .channel_mode = alc269_modes,
84898e87 15062 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 15063 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
15064 .init_hook = alc269_laptop_inithook,
15065 },
15066 [ALC269VB_DMIC] = {
15067 .mixers = { alc269vb_laptop_mixer },
15068 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15069 .init_verbs = { alc269vb_init_verbs,
15070 alc269vb_laptop_dmic_init_verbs },
15071 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15072 .dac_nids = alc269_dac_nids,
15073 .hp_nid = 0x03,
15074 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15075 .channel_mode = alc269_modes,
15076 .unsol_event = alc269_laptop_unsol_event,
15077 .setup = alc269vb_laptop_dmic_setup,
15078 .init_hook = alc269_laptop_inithook,
f53281e6 15079 },
26f5df26 15080 [ALC269_FUJITSU] = {
45bdd1c1 15081 .mixers = { alc269_fujitsu_mixer },
84898e87 15082 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15083 .init_verbs = { alc269_init_verbs,
84898e87 15084 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15085 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15086 .dac_nids = alc269_dac_nids,
15087 .hp_nid = 0x03,
15088 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15089 .channel_mode = alc269_modes,
84898e87
KY
15090 .unsol_event = alc269_laptop_unsol_event,
15091 .setup = alc269_laptop_dmic_setup,
15092 .init_hook = alc269_laptop_inithook,
26f5df26 15093 },
64154835
TV
15094 [ALC269_LIFEBOOK] = {
15095 .mixers = { alc269_lifebook_mixer },
15096 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15097 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15098 .dac_nids = alc269_dac_nids,
15099 .hp_nid = 0x03,
15100 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15101 .channel_mode = alc269_modes,
15102 .input_mux = &alc269_capture_source,
15103 .unsol_event = alc269_lifebook_unsol_event,
15104 .init_hook = alc269_lifebook_init_hook,
15105 },
fe3eb0a7
KY
15106 [ALC271_ACER] = {
15107 .mixers = { alc269_asus_mixer },
15108 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15109 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15110 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15111 .dac_nids = alc269_dac_nids,
15112 .adc_nids = alc262_dmic_adc_nids,
15113 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15114 .capsrc_nids = alc262_dmic_capsrc_nids,
15115 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15116 .channel_mode = alc269_modes,
15117 .input_mux = &alc269_capture_source,
15118 .dig_out_nid = ALC880_DIGOUT_NID,
15119 .unsol_event = alc_sku_unsol_event,
15120 .setup = alc269vb_laptop_dmic_setup,
15121 .init_hook = alc_inithook,
15122 },
f6a92248
KY
15123};
15124
977ddd6b
KY
15125static int alc269_fill_coef(struct hda_codec *codec)
15126{
15127 int val;
15128
15129 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15130 alc_write_coef_idx(codec, 0xf, 0x960b);
15131 alc_write_coef_idx(codec, 0xe, 0x8817);
15132 }
15133
15134 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15135 alc_write_coef_idx(codec, 0xf, 0x960b);
15136 alc_write_coef_idx(codec, 0xe, 0x8814);
15137 }
15138
15139 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15140 val = alc_read_coef_idx(codec, 0x04);
15141 /* Power up output pin */
15142 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15143 }
15144
15145 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15146 val = alc_read_coef_idx(codec, 0xd);
15147 if ((val & 0x0c00) >> 10 != 0x1) {
15148 /* Capless ramp up clock control */
15149 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15150 }
15151 val = alc_read_coef_idx(codec, 0x17);
15152 if ((val & 0x01c0) >> 6 != 0x4) {
15153 /* Class D power on reset */
15154 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15155 }
15156 }
15157 return 0;
15158}
15159
f6a92248
KY
15160static int patch_alc269(struct hda_codec *codec)
15161{
15162 struct alc_spec *spec;
48c88e82 15163 int board_config, coef;
f6a92248
KY
15164 int err;
15165
15166 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15167 if (spec == NULL)
15168 return -ENOMEM;
15169
15170 codec->spec = spec;
15171
da00c244
KY
15172 alc_auto_parse_customize_define(codec);
15173
c793bec5
KY
15174 if (codec->vendor_id == 0x10ec0269) {
15175 coef = alc_read_coef_idx(codec, 0);
15176 if ((coef & 0x00f0) == 0x0010) {
15177 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15178 spec->cdefine.platform_type == 1) {
15179 alc_codec_rename(codec, "ALC271X");
15180 spec->codec_variant = ALC269_TYPE_ALC271X;
15181 } else if ((coef & 0xf000) == 0x1000) {
15182 spec->codec_variant = ALC269_TYPE_ALC270;
15183 } else if ((coef & 0xf000) == 0x2000) {
15184 alc_codec_rename(codec, "ALC259");
15185 spec->codec_variant = ALC269_TYPE_ALC259;
15186 } else if ((coef & 0xf000) == 0x3000) {
15187 alc_codec_rename(codec, "ALC258");
15188 spec->codec_variant = ALC269_TYPE_ALC258;
15189 } else {
15190 alc_codec_rename(codec, "ALC269VB");
15191 spec->codec_variant = ALC269_TYPE_ALC269VB;
15192 }
15193 } else
15194 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15195 alc269_fill_coef(codec);
15196 }
977ddd6b 15197
f6a92248
KY
15198 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15199 alc269_models,
15200 alc269_cfg_tbl);
15201
15202 if (board_config < 0) {
9a11f1aa
TI
15203 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15204 codec->chip_name);
f6a92248
KY
15205 board_config = ALC269_AUTO;
15206 }
15207
b5bfbc67
TI
15208 if (board_config == ALC269_AUTO) {
15209 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15210 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15211 }
ff818c24 15212
f6a92248
KY
15213 if (board_config == ALC269_AUTO) {
15214 /* automatic parse from the BIOS config */
15215 err = alc269_parse_auto_config(codec);
15216 if (err < 0) {
15217 alc_free(codec);
15218 return err;
15219 } else if (!err) {
15220 printk(KERN_INFO
15221 "hda_codec: Cannot set up configuration "
15222 "from BIOS. Using base mode...\n");
15223 board_config = ALC269_BASIC;
15224 }
15225 }
15226
dc1eae25 15227 if (has_cdefine_beep(codec)) {
8af2591d
TI
15228 err = snd_hda_attach_beep_device(codec, 0x1);
15229 if (err < 0) {
15230 alc_free(codec);
15231 return err;
15232 }
680cd536
KK
15233 }
15234
f6a92248 15235 if (board_config != ALC269_AUTO)
e9c364c0 15236 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15237
84898e87 15238 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15239 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15240 * fix the sample rate of analog I/O to 44.1kHz
15241 */
15242 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15243 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15244 } else if (spec->dual_adc_switch) {
15245 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15246 /* switch ADC dynamically */
15247 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15248 } else {
15249 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15250 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15251 }
f6a92248
KY
15252 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15253 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15254
6694635d 15255 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15256 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15257 spec->adc_nids = alc269_adc_nids;
15258 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15259 spec->capsrc_nids = alc269_capsrc_nids;
15260 } else {
15261 spec->adc_nids = alc269vb_adc_nids;
15262 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15263 spec->capsrc_nids = alc269vb_capsrc_nids;
15264 }
84898e87
KY
15265 }
15266
f9e336f6 15267 if (!spec->cap_mixer)
b59bdf3b 15268 set_capture_mixer(codec);
dc1eae25 15269 if (has_cdefine_beep(codec))
da00c244 15270 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15271
b5bfbc67 15272 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15273
100d5eb3
TI
15274 spec->vmaster_nid = 0x02;
15275
f6a92248 15276 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15277#ifdef CONFIG_SND_HDA_POWER_SAVE
15278 codec->patch_ops.suspend = alc269_suspend;
15279#endif
15280#ifdef SND_HDA_NEEDS_RESUME
15281 codec->patch_ops.resume = alc269_resume;
15282#endif
f6a92248
KY
15283 if (board_config == ALC269_AUTO)
15284 spec->init_hook = alc269_auto_init;
bf1b0225
KY
15285
15286 alc_init_jacks(codec);
f6a92248
KY
15287#ifdef CONFIG_SND_HDA_POWER_SAVE
15288 if (!spec->loopback.amplist)
15289 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15290 if (alc269_mic2_for_mute_led(codec))
15291 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15292#endif
15293
15294 return 0;
15295}
15296
df694daa
KY
15297/*
15298 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15299 */
15300
15301/*
15302 * set the path ways for 2 channel output
15303 * need to set the codec line out and mic 1 pin widgets to inputs
15304 */
15305static struct hda_verb alc861_threestack_ch2_init[] = {
15306 /* set pin widget 1Ah (line in) for input */
15307 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15308 /* set pin widget 18h (mic1/2) for input, for mic also enable
15309 * the vref
15310 */
df694daa
KY
15311 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15312
9c7f852e
TI
15313 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15314#if 0
15315 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15316 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15317#endif
df694daa
KY
15318 { } /* end */
15319};
15320/*
15321 * 6ch mode
15322 * need to set the codec line out and mic 1 pin widgets to outputs
15323 */
15324static struct hda_verb alc861_threestack_ch6_init[] = {
15325 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15326 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15327 /* set pin widget 18h (mic1) for output (CLFE)*/
15328 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15329
15330 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15331 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15332
9c7f852e
TI
15333 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15334#if 0
15335 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15336 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15337#endif
df694daa
KY
15338 { } /* end */
15339};
15340
15341static struct hda_channel_mode alc861_threestack_modes[2] = {
15342 { 2, alc861_threestack_ch2_init },
15343 { 6, alc861_threestack_ch6_init },
15344};
22309c3e
TI
15345/* Set mic1 as input and unmute the mixer */
15346static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15347 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15348 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15349 { } /* end */
15350};
15351/* Set mic1 as output and mute mixer */
15352static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15353 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15354 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15355 { } /* end */
15356};
15357
15358static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15359 { 2, alc861_uniwill_m31_ch2_init },
15360 { 4, alc861_uniwill_m31_ch4_init },
15361};
df694daa 15362
7cdbff94
MD
15363/* Set mic1 and line-in as input and unmute the mixer */
15364static struct hda_verb alc861_asus_ch2_init[] = {
15365 /* set pin widget 1Ah (line in) for input */
15366 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15367 /* set pin widget 18h (mic1/2) for input, for mic also enable
15368 * the vref
15369 */
7cdbff94
MD
15370 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15371
15372 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15373#if 0
15374 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15375 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15376#endif
15377 { } /* end */
15378};
15379/* Set mic1 nad line-in as output and mute mixer */
15380static struct hda_verb alc861_asus_ch6_init[] = {
15381 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15382 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15383 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15384 /* set pin widget 18h (mic1) for output (CLFE)*/
15385 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15386 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15387 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15388 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15389
15390 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15391#if 0
15392 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15393 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15394#endif
15395 { } /* end */
15396};
15397
15398static struct hda_channel_mode alc861_asus_modes[2] = {
15399 { 2, alc861_asus_ch2_init },
15400 { 6, alc861_asus_ch6_init },
15401};
15402
df694daa
KY
15403/* patch-ALC861 */
15404
15405static struct snd_kcontrol_new alc861_base_mixer[] = {
15406 /* output mixer control */
15407 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15408 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15409 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15410 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15411 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15412
15413 /*Input mixer control */
15414 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15415 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15416 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15417 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15418 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15419 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15420 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15421 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15422 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15423 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15424
df694daa
KY
15425 { } /* end */
15426};
15427
15428static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15429 /* output mixer control */
15430 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15431 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15432 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15433 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15434 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15435
15436 /* Input mixer control */
15437 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15438 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15439 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15440 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15441 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15442 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15443 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15444 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15445 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15446 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15447
df694daa
KY
15448 {
15449 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15450 .name = "Channel Mode",
15451 .info = alc_ch_mode_info,
15452 .get = alc_ch_mode_get,
15453 .put = alc_ch_mode_put,
15454 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15455 },
15456 { } /* end */
a53d1aec
TD
15457};
15458
d1d985f0 15459static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15460 /* output mixer control */
15461 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15463 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15464
a53d1aec 15465 { } /* end */
f12ab1e0 15466};
a53d1aec 15467
22309c3e
TI
15468static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15469 /* output mixer control */
15470 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15471 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15472 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15473 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15474 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15475
15476 /* Input mixer control */
15477 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15478 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15479 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15480 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15481 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15482 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15484 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15485 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15486 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15487
22309c3e
TI
15488 {
15489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15490 .name = "Channel Mode",
15491 .info = alc_ch_mode_info,
15492 .get = alc_ch_mode_get,
15493 .put = alc_ch_mode_put,
15494 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15495 },
15496 { } /* end */
f12ab1e0 15497};
7cdbff94
MD
15498
15499static struct snd_kcontrol_new alc861_asus_mixer[] = {
15500 /* output mixer control */
15501 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15502 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15503 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15504 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15505 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15506
15507 /* Input mixer control */
15508 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15509 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15510 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15511 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15512 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15513 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15515 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15516 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15517 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15518
7cdbff94
MD
15519 {
15520 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15521 .name = "Channel Mode",
15522 .info = alc_ch_mode_info,
15523 .get = alc_ch_mode_get,
15524 .put = alc_ch_mode_put,
15525 .private_value = ARRAY_SIZE(alc861_asus_modes),
15526 },
15527 { }
56bb0cab
TI
15528};
15529
15530/* additional mixer */
d1d985f0 15531static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15532 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15533 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15534 { }
15535};
7cdbff94 15536
df694daa
KY
15537/*
15538 * generic initialization of ADC, input mixers and output mixers
15539 */
15540static struct hda_verb alc861_base_init_verbs[] = {
15541 /*
15542 * Unmute ADC0 and set the default input to mic-in
15543 */
15544 /* port-A for surround (rear panel) */
15545 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15546 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15547 /* port-B for mic-in (rear panel) with vref */
15548 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15549 /* port-C for line-in (rear panel) */
15550 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15551 /* port-D for Front */
15552 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15553 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15554 /* port-E for HP out (front panel) */
15555 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15556 /* route front PCM to HP */
9dece1d7 15557 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15558 /* port-F for mic-in (front panel) with vref */
15559 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15560 /* port-G for CLFE (rear panel) */
15561 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15562 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15563 /* port-H for side (rear panel) */
15564 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15565 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15566 /* CD-in */
15567 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15568 /* route front mic to ADC1*/
15569 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15570 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15571
df694daa
KY
15572 /* Unmute DAC0~3 & spdif out*/
15573 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15574 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15575 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15576 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15578
df694daa
KY
15579 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15580 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15581 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15582 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15583 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15584
df694daa
KY
15585 /* Unmute Stereo Mixer 15 */
15586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15587 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15588 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15590
15591 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15592 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15593 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15594 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15595 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15596 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15597 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15599 /* hp used DAC 3 (Front) */
15600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15601 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15602
15603 { }
15604};
15605
15606static struct hda_verb alc861_threestack_init_verbs[] = {
15607 /*
15608 * Unmute ADC0 and set the default input to mic-in
15609 */
15610 /* port-A for surround (rear panel) */
15611 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15612 /* port-B for mic-in (rear panel) with vref */
15613 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15614 /* port-C for line-in (rear panel) */
15615 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15616 /* port-D for Front */
15617 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15618 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15619 /* port-E for HP out (front panel) */
15620 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15621 /* route front PCM to HP */
9dece1d7 15622 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15623 /* port-F for mic-in (front panel) with vref */
15624 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15625 /* port-G for CLFE (rear panel) */
15626 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15627 /* port-H for side (rear panel) */
15628 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15629 /* CD-in */
15630 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15631 /* route front mic to ADC1*/
15632 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15633 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15634 /* Unmute DAC0~3 & spdif out*/
15635 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15636 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15637 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15638 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15639 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15640
df694daa
KY
15641 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15642 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15643 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15644 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15645 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15646
df694daa
KY
15647 /* Unmute Stereo Mixer 15 */
15648 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15650 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15651 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15652
15653 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15654 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15655 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15656 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15657 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15658 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15659 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15660 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15661 /* hp used DAC 3 (Front) */
15662 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15663 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15664 { }
15665};
22309c3e
TI
15666
15667static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15668 /*
15669 * Unmute ADC0 and set the default input to mic-in
15670 */
15671 /* port-A for surround (rear panel) */
15672 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15673 /* port-B for mic-in (rear panel) with vref */
15674 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15675 /* port-C for line-in (rear panel) */
15676 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15677 /* port-D for Front */
15678 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15679 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15680 /* port-E for HP out (front panel) */
f12ab1e0
TI
15681 /* this has to be set to VREF80 */
15682 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15683 /* route front PCM to HP */
9dece1d7 15684 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15685 /* port-F for mic-in (front panel) with vref */
15686 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15687 /* port-G for CLFE (rear panel) */
15688 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15689 /* port-H for side (rear panel) */
15690 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15691 /* CD-in */
15692 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15693 /* route front mic to ADC1*/
15694 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15695 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15696 /* Unmute DAC0~3 & spdif out*/
15697 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15698 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15699 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15700 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15701 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15702
22309c3e
TI
15703 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15704 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15705 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15706 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15707 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15708
22309c3e
TI
15709 /* Unmute Stereo Mixer 15 */
15710 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15711 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15713 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15714
15715 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15716 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15717 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15718 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15719 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15721 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15722 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15723 /* hp used DAC 3 (Front) */
15724 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15725 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15726 { }
15727};
15728
7cdbff94
MD
15729static struct hda_verb alc861_asus_init_verbs[] = {
15730 /*
15731 * Unmute ADC0 and set the default input to mic-in
15732 */
f12ab1e0
TI
15733 /* port-A for surround (rear panel)
15734 * according to codec#0 this is the HP jack
15735 */
7cdbff94
MD
15736 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15737 /* route front PCM to HP */
15738 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15739 /* port-B for mic-in (rear panel) with vref */
15740 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15741 /* port-C for line-in (rear panel) */
15742 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15743 /* port-D for Front */
15744 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15745 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15746 /* port-E for HP out (front panel) */
f12ab1e0
TI
15747 /* this has to be set to VREF80 */
15748 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15749 /* route front PCM to HP */
9dece1d7 15750 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15751 /* port-F for mic-in (front panel) with vref */
15752 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15753 /* port-G for CLFE (rear panel) */
15754 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15755 /* port-H for side (rear panel) */
15756 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15757 /* CD-in */
15758 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15759 /* route front mic to ADC1*/
15760 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15761 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15762 /* Unmute DAC0~3 & spdif out*/
15763 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15764 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15765 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15766 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15767 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15768 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15769 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15770 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15771 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15772 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15773
7cdbff94
MD
15774 /* Unmute Stereo Mixer 15 */
15775 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15776 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15777 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15778 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15779
15780 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15781 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15782 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15783 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15784 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15785 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15787 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15788 /* hp used DAC 3 (Front) */
15789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15790 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15791 { }
15792};
15793
56bb0cab
TI
15794/* additional init verbs for ASUS laptops */
15795static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15796 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15797 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15798 { }
15799};
7cdbff94 15800
df694daa
KY
15801/*
15802 * generic initialization of ADC, input mixers and output mixers
15803 */
15804static struct hda_verb alc861_auto_init_verbs[] = {
15805 /*
15806 * Unmute ADC0 and set the default input to mic-in
15807 */
f12ab1e0 15808 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15809 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15810
df694daa
KY
15811 /* Unmute DAC0~3 & spdif out*/
15812 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15813 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15814 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15815 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15816 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15817
df694daa
KY
15818 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15819 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15820 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15821 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15822 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15823
df694daa
KY
15824 /* Unmute Stereo Mixer 15 */
15825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15829
1c20930a
TI
15830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15831 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15834 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15836 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15838
15839 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15840 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15841 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15842 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15843 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15844 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15845 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15846 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15847
f12ab1e0 15848 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15849
15850 { }
15851};
15852
a53d1aec
TD
15853static struct hda_verb alc861_toshiba_init_verbs[] = {
15854 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15855
a53d1aec
TD
15856 { }
15857};
15858
15859/* toggle speaker-output according to the hp-jack state */
15860static void alc861_toshiba_automute(struct hda_codec *codec)
15861{
864f92be 15862 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15863
47fd830a
TI
15864 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15865 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15866 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15867 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15868}
15869
15870static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15871 unsigned int res)
15872{
a53d1aec
TD
15873 if ((res >> 26) == ALC880_HP_EVENT)
15874 alc861_toshiba_automute(codec);
15875}
15876
def319f9 15877/* pcm configuration: identical with ALC880 */
df694daa
KY
15878#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15879#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15880#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15881#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15882
15883
15884#define ALC861_DIGOUT_NID 0x07
15885
15886static struct hda_channel_mode alc861_8ch_modes[1] = {
15887 { 8, NULL }
15888};
15889
15890static hda_nid_t alc861_dac_nids[4] = {
15891 /* front, surround, clfe, side */
15892 0x03, 0x06, 0x05, 0x04
15893};
15894
9c7f852e
TI
15895static hda_nid_t alc660_dac_nids[3] = {
15896 /* front, clfe, surround */
15897 0x03, 0x05, 0x06
15898};
15899
df694daa
KY
15900static hda_nid_t alc861_adc_nids[1] = {
15901 /* ADC0-2 */
15902 0x08,
15903};
15904
15905static struct hda_input_mux alc861_capture_source = {
15906 .num_items = 5,
15907 .items = {
15908 { "Mic", 0x0 },
15909 { "Front Mic", 0x3 },
15910 { "Line", 0x1 },
15911 { "CD", 0x4 },
15912 { "Mixer", 0x5 },
15913 },
15914};
15915
1c20930a
TI
15916static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15917{
15918 struct alc_spec *spec = codec->spec;
15919 hda_nid_t mix, srcs[5];
15920 int i, j, num;
15921
15922 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15923 return 0;
15924 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15925 if (num < 0)
15926 return 0;
15927 for (i = 0; i < num; i++) {
15928 unsigned int type;
a22d543a 15929 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15930 if (type != AC_WID_AUD_OUT)
15931 continue;
15932 for (j = 0; j < spec->multiout.num_dacs; j++)
15933 if (spec->multiout.dac_nids[j] == srcs[i])
15934 break;
15935 if (j >= spec->multiout.num_dacs)
15936 return srcs[i];
15937 }
15938 return 0;
15939}
15940
df694daa 15941/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15942static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15943 const struct auto_pin_cfg *cfg)
df694daa 15944{
1c20930a 15945 struct alc_spec *spec = codec->spec;
df694daa 15946 int i;
1c20930a 15947 hda_nid_t nid, dac;
df694daa
KY
15948
15949 spec->multiout.dac_nids = spec->private_dac_nids;
15950 for (i = 0; i < cfg->line_outs; i++) {
15951 nid = cfg->line_out_pins[i];
1c20930a
TI
15952 dac = alc861_look_for_dac(codec, nid);
15953 if (!dac)
15954 continue;
15955 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15956 }
df694daa
KY
15957 return 0;
15958}
15959
bcb2f0f5
TI
15960static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15961 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15962{
bcb2f0f5 15963 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15964 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15965}
15966
bcb2f0f5
TI
15967#define alc861_create_out_sw(codec, pfx, nid, chs) \
15968 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15969
df694daa 15970/* add playback controls from the parsed DAC table */
1c20930a 15971static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15972 const struct auto_pin_cfg *cfg)
15973{
1c20930a 15974 struct alc_spec *spec = codec->spec;
ea734963 15975 static const char * const chname[4] = {
f12ab1e0
TI
15976 "Front", "Surround", NULL /*CLFE*/, "Side"
15977 };
bcb2f0f5 15978 const char *pfx = alc_get_line_out_pfx(cfg, true);
df694daa 15979 hda_nid_t nid;
1c20930a
TI
15980 int i, err;
15981
df694daa
KY
15982 for (i = 0; i < cfg->line_outs; i++) {
15983 nid = spec->multiout.dac_nids[i];
f12ab1e0 15984 if (!nid)
df694daa 15985 continue;
bcb2f0f5 15986 if (!pfx && i == 2) {
df694daa 15987 /* Center/LFE */
1c20930a 15988 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15989 if (err < 0)
df694daa 15990 return err;
1c20930a 15991 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15992 if (err < 0)
df694daa
KY
15993 return err;
15994 } else {
bcb2f0f5
TI
15995 const char *name = pfx;
15996 if (!name)
15997 name = chname[i];
15998 err = __alc861_create_out_sw(codec, name, nid, i, 3);
f12ab1e0 15999 if (err < 0)
df694daa
KY
16000 return err;
16001 }
16002 }
16003 return 0;
16004}
16005
1c20930a 16006static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16007{
1c20930a 16008 struct alc_spec *spec = codec->spec;
df694daa
KY
16009 int err;
16010 hda_nid_t nid;
16011
f12ab1e0 16012 if (!pin)
df694daa
KY
16013 return 0;
16014
16015 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16016 nid = alc861_look_for_dac(codec, pin);
16017 if (nid) {
16018 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16019 if (err < 0)
16020 return err;
16021 spec->multiout.hp_nid = nid;
16022 }
df694daa
KY
16023 }
16024 return 0;
16025}
16026
16027/* create playback/capture controls for input pins */
05f5f477 16028static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16029 const struct auto_pin_cfg *cfg)
df694daa 16030{
05f5f477 16031 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16032}
16033
f12ab1e0
TI
16034static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16035 hda_nid_t nid,
1c20930a 16036 int pin_type, hda_nid_t dac)
df694daa 16037{
1c20930a
TI
16038 hda_nid_t mix, srcs[5];
16039 int i, num;
16040
564c5bea
JL
16041 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16042 pin_type);
1c20930a 16043 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16044 AMP_OUT_UNMUTE);
1c20930a
TI
16045 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16046 return;
16047 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16048 if (num < 0)
16049 return;
16050 for (i = 0; i < num; i++) {
16051 unsigned int mute;
16052 if (srcs[i] == dac || srcs[i] == 0x15)
16053 mute = AMP_IN_UNMUTE(i);
16054 else
16055 mute = AMP_IN_MUTE(i);
16056 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16057 mute);
16058 }
df694daa
KY
16059}
16060
16061static void alc861_auto_init_multi_out(struct hda_codec *codec)
16062{
16063 struct alc_spec *spec = codec->spec;
16064 int i;
16065
16066 for (i = 0; i < spec->autocfg.line_outs; i++) {
16067 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16068 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16069 if (nid)
baba8ee9 16070 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16071 spec->multiout.dac_nids[i]);
df694daa
KY
16072 }
16073}
16074
16075static void alc861_auto_init_hp_out(struct hda_codec *codec)
16076{
16077 struct alc_spec *spec = codec->spec;
df694daa 16078
15870f05
TI
16079 if (spec->autocfg.hp_outs)
16080 alc861_auto_set_output_and_unmute(codec,
16081 spec->autocfg.hp_pins[0],
16082 PIN_HP,
1c20930a 16083 spec->multiout.hp_nid);
15870f05
TI
16084 if (spec->autocfg.speaker_outs)
16085 alc861_auto_set_output_and_unmute(codec,
16086 spec->autocfg.speaker_pins[0],
16087 PIN_OUT,
1c20930a 16088 spec->multiout.dac_nids[0]);
df694daa
KY
16089}
16090
16091static void alc861_auto_init_analog_input(struct hda_codec *codec)
16092{
16093 struct alc_spec *spec = codec->spec;
66ceeb6b 16094 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16095 int i;
16096
66ceeb6b
TI
16097 for (i = 0; i < cfg->num_inputs; i++) {
16098 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16099 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16100 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16101 }
16102}
16103
16104/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16105/* return 1 if successful, 0 if the proper config is not found,
16106 * or a negative error code
16107 */
df694daa
KY
16108static int alc861_parse_auto_config(struct hda_codec *codec)
16109{
16110 struct alc_spec *spec = codec->spec;
16111 int err;
16112 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16113
f12ab1e0
TI
16114 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16115 alc861_ignore);
16116 if (err < 0)
df694daa 16117 return err;
f12ab1e0 16118 if (!spec->autocfg.line_outs)
df694daa
KY
16119 return 0; /* can't find valid BIOS pin config */
16120
1c20930a 16121 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
16122 if (err < 0)
16123 return err;
1c20930a 16124 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16125 if (err < 0)
16126 return err;
1c20930a 16127 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16128 if (err < 0)
16129 return err;
05f5f477 16130 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16131 if (err < 0)
df694daa
KY
16132 return err;
16133
16134 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16135
757899ac 16136 alc_auto_parse_digital(codec);
df694daa 16137
603c4019 16138 if (spec->kctls.list)
d88897ea 16139 add_mixer(spec, spec->kctls.list);
df694daa 16140
d88897ea 16141 add_verb(spec, alc861_auto_init_verbs);
df694daa 16142
a1e8d2da 16143 spec->num_mux_defs = 1;
61b9b9b1 16144 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16145
16146 spec->adc_nids = alc861_adc_nids;
16147 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16148 set_capture_mixer(codec);
df694daa 16149
6227cdce 16150 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16151
df694daa
KY
16152 return 1;
16153}
16154
ae6b813a
TI
16155/* additional initialization for auto-configuration model */
16156static void alc861_auto_init(struct hda_codec *codec)
df694daa 16157{
f6c7e546 16158 struct alc_spec *spec = codec->spec;
df694daa
KY
16159 alc861_auto_init_multi_out(codec);
16160 alc861_auto_init_hp_out(codec);
16161 alc861_auto_init_analog_input(codec);
757899ac 16162 alc_auto_init_digital(codec);
f6c7e546 16163 if (spec->unsol_event)
7fb0d78f 16164 alc_inithook(codec);
df694daa
KY
16165}
16166
cb53c626
TI
16167#ifdef CONFIG_SND_HDA_POWER_SAVE
16168static struct hda_amp_list alc861_loopbacks[] = {
16169 { 0x15, HDA_INPUT, 0 },
16170 { 0x15, HDA_INPUT, 1 },
16171 { 0x15, HDA_INPUT, 2 },
16172 { 0x15, HDA_INPUT, 3 },
16173 { } /* end */
16174};
16175#endif
16176
df694daa
KY
16177
16178/*
16179 * configuration and preset
16180 */
ea734963 16181static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16182 [ALC861_3ST] = "3stack",
16183 [ALC660_3ST] = "3stack-660",
16184 [ALC861_3ST_DIG] = "3stack-dig",
16185 [ALC861_6ST_DIG] = "6stack-dig",
16186 [ALC861_UNIWILL_M31] = "uniwill-m31",
16187 [ALC861_TOSHIBA] = "toshiba",
16188 [ALC861_ASUS] = "asus",
16189 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16190 [ALC861_AUTO] = "auto",
16191};
16192
16193static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16194 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16195 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16196 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16197 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16198 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16199 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16200 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16201 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16202 * Any other models that need this preset?
16203 */
16204 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16205 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16206 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16207 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16208 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16209 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16210 /* FIXME: the below seems conflict */
16211 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16212 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16213 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16214 {}
16215};
16216
16217static struct alc_config_preset alc861_presets[] = {
16218 [ALC861_3ST] = {
16219 .mixers = { alc861_3ST_mixer },
16220 .init_verbs = { alc861_threestack_init_verbs },
16221 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16222 .dac_nids = alc861_dac_nids,
16223 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16224 .channel_mode = alc861_threestack_modes,
4e195a7b 16225 .need_dac_fix = 1,
df694daa
KY
16226 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16227 .adc_nids = alc861_adc_nids,
16228 .input_mux = &alc861_capture_source,
16229 },
16230 [ALC861_3ST_DIG] = {
16231 .mixers = { alc861_base_mixer },
16232 .init_verbs = { alc861_threestack_init_verbs },
16233 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16234 .dac_nids = alc861_dac_nids,
16235 .dig_out_nid = ALC861_DIGOUT_NID,
16236 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16237 .channel_mode = alc861_threestack_modes,
4e195a7b 16238 .need_dac_fix = 1,
df694daa
KY
16239 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16240 .adc_nids = alc861_adc_nids,
16241 .input_mux = &alc861_capture_source,
16242 },
16243 [ALC861_6ST_DIG] = {
16244 .mixers = { alc861_base_mixer },
16245 .init_verbs = { alc861_base_init_verbs },
16246 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16247 .dac_nids = alc861_dac_nids,
16248 .dig_out_nid = ALC861_DIGOUT_NID,
16249 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16250 .channel_mode = alc861_8ch_modes,
16251 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16252 .adc_nids = alc861_adc_nids,
16253 .input_mux = &alc861_capture_source,
16254 },
9c7f852e
TI
16255 [ALC660_3ST] = {
16256 .mixers = { alc861_3ST_mixer },
16257 .init_verbs = { alc861_threestack_init_verbs },
16258 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16259 .dac_nids = alc660_dac_nids,
16260 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16261 .channel_mode = alc861_threestack_modes,
4e195a7b 16262 .need_dac_fix = 1,
9c7f852e
TI
16263 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16264 .adc_nids = alc861_adc_nids,
16265 .input_mux = &alc861_capture_source,
16266 },
22309c3e
TI
16267 [ALC861_UNIWILL_M31] = {
16268 .mixers = { alc861_uniwill_m31_mixer },
16269 .init_verbs = { alc861_uniwill_m31_init_verbs },
16270 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16271 .dac_nids = alc861_dac_nids,
16272 .dig_out_nid = ALC861_DIGOUT_NID,
16273 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16274 .channel_mode = alc861_uniwill_m31_modes,
16275 .need_dac_fix = 1,
16276 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16277 .adc_nids = alc861_adc_nids,
16278 .input_mux = &alc861_capture_source,
16279 },
a53d1aec
TD
16280 [ALC861_TOSHIBA] = {
16281 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16282 .init_verbs = { alc861_base_init_verbs,
16283 alc861_toshiba_init_verbs },
a53d1aec
TD
16284 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16285 .dac_nids = alc861_dac_nids,
16286 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16287 .channel_mode = alc883_3ST_2ch_modes,
16288 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16289 .adc_nids = alc861_adc_nids,
16290 .input_mux = &alc861_capture_source,
16291 .unsol_event = alc861_toshiba_unsol_event,
16292 .init_hook = alc861_toshiba_automute,
16293 },
7cdbff94
MD
16294 [ALC861_ASUS] = {
16295 .mixers = { alc861_asus_mixer },
16296 .init_verbs = { alc861_asus_init_verbs },
16297 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16298 .dac_nids = alc861_dac_nids,
16299 .dig_out_nid = ALC861_DIGOUT_NID,
16300 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16301 .channel_mode = alc861_asus_modes,
16302 .need_dac_fix = 1,
16303 .hp_nid = 0x06,
16304 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16305 .adc_nids = alc861_adc_nids,
16306 .input_mux = &alc861_capture_source,
16307 },
56bb0cab
TI
16308 [ALC861_ASUS_LAPTOP] = {
16309 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16310 .init_verbs = { alc861_asus_init_verbs,
16311 alc861_asus_laptop_init_verbs },
16312 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16313 .dac_nids = alc861_dac_nids,
16314 .dig_out_nid = ALC861_DIGOUT_NID,
16315 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16316 .channel_mode = alc883_3ST_2ch_modes,
16317 .need_dac_fix = 1,
16318 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16319 .adc_nids = alc861_adc_nids,
16320 .input_mux = &alc861_capture_source,
16321 },
16322};
df694daa 16323
cfc9b06f
TI
16324/* Pin config fixes */
16325enum {
16326 PINFIX_FSC_AMILO_PI1505,
16327};
16328
cfc9b06f
TI
16329static const struct alc_fixup alc861_fixups[] = {
16330 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16331 .type = ALC_FIXUP_PINS,
16332 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16333 { 0x0b, 0x0221101f }, /* HP */
16334 { 0x0f, 0x90170310 }, /* speaker */
16335 { }
16336 }
cfc9b06f
TI
16337 },
16338};
16339
16340static struct snd_pci_quirk alc861_fixup_tbl[] = {
16341 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16342 {}
16343};
df694daa
KY
16344
16345static int patch_alc861(struct hda_codec *codec)
16346{
16347 struct alc_spec *spec;
16348 int board_config;
16349 int err;
16350
dc041e0b 16351 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16352 if (spec == NULL)
16353 return -ENOMEM;
16354
f12ab1e0 16355 codec->spec = spec;
df694daa 16356
f5fcc13c
TI
16357 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16358 alc861_models,
16359 alc861_cfg_tbl);
9c7f852e 16360
f5fcc13c 16361 if (board_config < 0) {
9a11f1aa
TI
16362 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16363 codec->chip_name);
df694daa
KY
16364 board_config = ALC861_AUTO;
16365 }
16366
b5bfbc67
TI
16367 if (board_config == ALC861_AUTO) {
16368 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16369 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16370 }
cfc9b06f 16371
df694daa
KY
16372 if (board_config == ALC861_AUTO) {
16373 /* automatic parse from the BIOS config */
16374 err = alc861_parse_auto_config(codec);
16375 if (err < 0) {
16376 alc_free(codec);
16377 return err;
f12ab1e0 16378 } else if (!err) {
9c7f852e
TI
16379 printk(KERN_INFO
16380 "hda_codec: Cannot set up configuration "
16381 "from BIOS. Using base mode...\n");
df694daa
KY
16382 board_config = ALC861_3ST_DIG;
16383 }
16384 }
16385
680cd536
KK
16386 err = snd_hda_attach_beep_device(codec, 0x23);
16387 if (err < 0) {
16388 alc_free(codec);
16389 return err;
16390 }
16391
df694daa 16392 if (board_config != ALC861_AUTO)
e9c364c0 16393 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16394
df694daa
KY
16395 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16396 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16397
df694daa
KY
16398 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16399 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16400
c7a8eb10
TI
16401 if (!spec->cap_mixer)
16402 set_capture_mixer(codec);
45bdd1c1
TI
16403 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16404
2134ea4f
TI
16405 spec->vmaster_nid = 0x03;
16406
b5bfbc67 16407 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16408
df694daa 16409 codec->patch_ops = alc_patch_ops;
c97259df 16410 if (board_config == ALC861_AUTO) {
ae6b813a 16411 spec->init_hook = alc861_auto_init;
c97259df
DC
16412#ifdef CONFIG_SND_HDA_POWER_SAVE
16413 spec->power_hook = alc_power_eapd;
16414#endif
16415 }
cb53c626
TI
16416#ifdef CONFIG_SND_HDA_POWER_SAVE
16417 if (!spec->loopback.amplist)
16418 spec->loopback.amplist = alc861_loopbacks;
16419#endif
ea1fb29a 16420
1da177e4
LT
16421 return 0;
16422}
16423
f32610ed
JS
16424/*
16425 * ALC861-VD support
16426 *
16427 * Based on ALC882
16428 *
16429 * In addition, an independent DAC
16430 */
16431#define ALC861VD_DIGOUT_NID 0x06
16432
16433static hda_nid_t alc861vd_dac_nids[4] = {
16434 /* front, surr, clfe, side surr */
16435 0x02, 0x03, 0x04, 0x05
16436};
16437
16438/* dac_nids for ALC660vd are in a different order - according to
16439 * Realtek's driver.
def319f9 16440 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16441 * of ALC660vd codecs, but for now there is only 3stack mixer
16442 * - and it is the same as in 861vd.
16443 * adc_nids in ALC660vd are (is) the same as in 861vd
16444 */
16445static hda_nid_t alc660vd_dac_nids[3] = {
16446 /* front, rear, clfe, rear_surr */
16447 0x02, 0x04, 0x03
16448};
16449
16450static hda_nid_t alc861vd_adc_nids[1] = {
16451 /* ADC0 */
16452 0x09,
16453};
16454
e1406348
TI
16455static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16456
f32610ed
JS
16457/* input MUX */
16458/* FIXME: should be a matrix-type input source selection */
16459static struct hda_input_mux alc861vd_capture_source = {
16460 .num_items = 4,
16461 .items = {
16462 { "Mic", 0x0 },
16463 { "Front Mic", 0x1 },
16464 { "Line", 0x2 },
16465 { "CD", 0x4 },
16466 },
16467};
16468
272a527c 16469static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16470 .num_items = 2,
272a527c 16471 .items = {
8607f7c4 16472 { "Mic", 0x0 },
28c4edb7 16473 { "Internal Mic", 0x1 },
272a527c
KY
16474 },
16475};
16476
d1a991a6
KY
16477static struct hda_input_mux alc861vd_hp_capture_source = {
16478 .num_items = 2,
16479 .items = {
16480 { "Front Mic", 0x0 },
16481 { "ATAPI Mic", 0x1 },
16482 },
16483};
16484
f32610ed
JS
16485/*
16486 * 2ch mode
16487 */
16488static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16489 { 2, NULL }
16490};
16491
16492/*
16493 * 6ch mode
16494 */
16495static struct hda_verb alc861vd_6stack_ch6_init[] = {
16496 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16497 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16498 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16499 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16500 { } /* end */
16501};
16502
16503/*
16504 * 8ch mode
16505 */
16506static struct hda_verb alc861vd_6stack_ch8_init[] = {
16507 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16508 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16509 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16510 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16511 { } /* end */
16512};
16513
16514static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16515 { 6, alc861vd_6stack_ch6_init },
16516 { 8, alc861vd_6stack_ch8_init },
16517};
16518
16519static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16520 {
16521 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16522 .name = "Channel Mode",
16523 .info = alc_ch_mode_info,
16524 .get = alc_ch_mode_get,
16525 .put = alc_ch_mode_put,
16526 },
16527 { } /* end */
16528};
16529
f32610ed
JS
16530/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16531 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16532 */
16533static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16534 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16535 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16536
16537 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16538 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16539
16540 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16541 HDA_OUTPUT),
16542 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16543 HDA_OUTPUT),
16544 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16545 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16546
16547 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16548 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16549
16550 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16551
5f99f86a 16552 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16553 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16554 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16555
5f99f86a 16556 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16557 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16558 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16559
16560 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16561 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16562
16563 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16564 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16565
f32610ed
JS
16566 { } /* end */
16567};
16568
16569static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16570 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16571 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16572
16573 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16574
5f99f86a 16575 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16576 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16578
5f99f86a 16579 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16580 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16582
16583 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16584 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16585
16586 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16587 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16588
f32610ed
JS
16589 { } /* end */
16590};
16591
bdd148a3
KY
16592static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16593 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16594 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16595 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16596
16597 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16598
5f99f86a 16599 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16602
5f99f86a 16603 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16604 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16605 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16606
16607 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16608 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16609
16610 { } /* end */
16611};
16612
b419f346 16613/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16614 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16615 */
16616static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16617 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16618 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16619 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16620 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16621 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16622 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16623 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16624 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16625 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16626 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16627 { } /* end */
16628};
16629
d1a991a6
KY
16630/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16631 * Front Mic=0x18, ATAPI Mic = 0x19,
16632 */
16633static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16634 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16635 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16636 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16637 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16638 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16639 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16640 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16641 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16642
d1a991a6
KY
16643 { } /* end */
16644};
16645
f32610ed
JS
16646/*
16647 * generic initialization of ADC, input mixers and output mixers
16648 */
16649static struct hda_verb alc861vd_volume_init_verbs[] = {
16650 /*
16651 * Unmute ADC0 and set the default input to mic-in
16652 */
16653 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16654 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16655
16656 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16657 * the analog-loopback mixer widget
16658 */
16659 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16660 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16661 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16662 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16663 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16664 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16665
16666 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16667 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16668 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16669 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16670 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16671
16672 /*
16673 * Set up output mixers (0x02 - 0x05)
16674 */
16675 /* set vol=0 to output mixers */
16676 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16677 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16678 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16679 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16680
16681 /* set up input amps for analog loopback */
16682 /* Amp Indices: DAC = 0, mixer = 1 */
16683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16685 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16687 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16689 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16690 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16691
16692 { }
16693};
16694
16695/*
16696 * 3-stack pin configuration:
16697 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16698 */
16699static struct hda_verb alc861vd_3stack_init_verbs[] = {
16700 /*
16701 * Set pin mode and muting
16702 */
16703 /* set front pin widgets 0x14 for output */
16704 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16705 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16706 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16707
16708 /* Mic (rear) pin: input vref at 80% */
16709 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16710 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16711 /* Front Mic pin: input vref at 80% */
16712 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16713 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16714 /* Line In pin: input */
16715 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16716 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16717 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16718 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16719 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16720 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16721 /* CD pin widget for input */
16722 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16723
16724 { }
16725};
16726
16727/*
16728 * 6-stack pin configuration:
16729 */
16730static struct hda_verb alc861vd_6stack_init_verbs[] = {
16731 /*
16732 * Set pin mode and muting
16733 */
16734 /* set front pin widgets 0x14 for output */
16735 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16736 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16737 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16738
16739 /* Rear Pin: output 1 (0x0d) */
16740 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16742 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16743 /* CLFE Pin: output 2 (0x0e) */
16744 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16745 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16746 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16747 /* Side Pin: output 3 (0x0f) */
16748 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16749 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16750 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16751
16752 /* Mic (rear) pin: input vref at 80% */
16753 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16754 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16755 /* Front Mic pin: input vref at 80% */
16756 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16757 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16758 /* Line In pin: input */
16759 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16761 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16762 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16763 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16764 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16765 /* CD pin widget for input */
16766 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16767
16768 { }
16769};
16770
bdd148a3
KY
16771static struct hda_verb alc861vd_eapd_verbs[] = {
16772 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16773 { }
16774};
16775
f9423e7a
KY
16776static struct hda_verb alc660vd_eapd_verbs[] = {
16777 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16778 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16779 { }
16780};
16781
bdd148a3
KY
16782static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16783 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16784 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16785 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16786 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16787 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16788 {}
16789};
16790
4f5d1706 16791static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16792{
a9fd4f3f 16793 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16794 spec->autocfg.hp_pins[0] = 0x1b;
16795 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16796}
16797
16798static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16799{
a9fd4f3f 16800 alc_automute_amp(codec);
eeb43387 16801 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16802}
16803
16804static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16805 unsigned int res)
16806{
16807 switch (res >> 26) {
bdd148a3 16808 case ALC880_MIC_EVENT:
eeb43387 16809 alc88x_simple_mic_automute(codec);
bdd148a3 16810 break;
a9fd4f3f
TI
16811 default:
16812 alc_automute_amp_unsol_event(codec, res);
16813 break;
bdd148a3
KY
16814 }
16815}
16816
272a527c
KY
16817static struct hda_verb alc861vd_dallas_verbs[] = {
16818 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16819 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16820 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16821 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16822
16823 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16824 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16825 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16826 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16827 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16828 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16829 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16830 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16831
272a527c
KY
16832 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16833 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16834 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16835 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16836 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16837 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16838 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16839 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16840
16841 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16842 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16843 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16844 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16845 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16846 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16847 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16848 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16849
16850 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16851 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16852 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16853 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16854
16855 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16856 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16857 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16858
16859 { } /* end */
16860};
16861
16862/* toggle speaker-output according to the hp-jack state */
4f5d1706 16863static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16864{
a9fd4f3f 16865 struct alc_spec *spec = codec->spec;
272a527c 16866
a9fd4f3f
TI
16867 spec->autocfg.hp_pins[0] = 0x15;
16868 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16869}
16870
cb53c626
TI
16871#ifdef CONFIG_SND_HDA_POWER_SAVE
16872#define alc861vd_loopbacks alc880_loopbacks
16873#endif
16874
def319f9 16875/* pcm configuration: identical with ALC880 */
f32610ed
JS
16876#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16877#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16878#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16879#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16880
16881/*
16882 * configuration and preset
16883 */
ea734963 16884static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16885 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16886 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16887 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16888 [ALC861VD_3ST] = "3stack",
16889 [ALC861VD_3ST_DIG] = "3stack-digout",
16890 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16891 [ALC861VD_LENOVO] = "lenovo",
272a527c 16892 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16893 [ALC861VD_HP] = "hp",
f32610ed
JS
16894 [ALC861VD_AUTO] = "auto",
16895};
16896
16897static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16898 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16899 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16900 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16901 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16902 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16903 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16904 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16905 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16906 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16907 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16908 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16909 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16910 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16911 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16912 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16913 {}
16914};
16915
16916static struct alc_config_preset alc861vd_presets[] = {
16917 [ALC660VD_3ST] = {
16918 .mixers = { alc861vd_3st_mixer },
16919 .init_verbs = { alc861vd_volume_init_verbs,
16920 alc861vd_3stack_init_verbs },
16921 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16922 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16923 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16924 .channel_mode = alc861vd_3stack_2ch_modes,
16925 .input_mux = &alc861vd_capture_source,
16926 },
6963f84c
MC
16927 [ALC660VD_3ST_DIG] = {
16928 .mixers = { alc861vd_3st_mixer },
16929 .init_verbs = { alc861vd_volume_init_verbs,
16930 alc861vd_3stack_init_verbs },
16931 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16932 .dac_nids = alc660vd_dac_nids,
16933 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16934 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16935 .channel_mode = alc861vd_3stack_2ch_modes,
16936 .input_mux = &alc861vd_capture_source,
16937 },
f32610ed
JS
16938 [ALC861VD_3ST] = {
16939 .mixers = { alc861vd_3st_mixer },
16940 .init_verbs = { alc861vd_volume_init_verbs,
16941 alc861vd_3stack_init_verbs },
16942 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16943 .dac_nids = alc861vd_dac_nids,
16944 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16945 .channel_mode = alc861vd_3stack_2ch_modes,
16946 .input_mux = &alc861vd_capture_source,
16947 },
16948 [ALC861VD_3ST_DIG] = {
16949 .mixers = { alc861vd_3st_mixer },
16950 .init_verbs = { alc861vd_volume_init_verbs,
16951 alc861vd_3stack_init_verbs },
16952 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16953 .dac_nids = alc861vd_dac_nids,
16954 .dig_out_nid = ALC861VD_DIGOUT_NID,
16955 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16956 .channel_mode = alc861vd_3stack_2ch_modes,
16957 .input_mux = &alc861vd_capture_source,
16958 },
16959 [ALC861VD_6ST_DIG] = {
16960 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16961 .init_verbs = { alc861vd_volume_init_verbs,
16962 alc861vd_6stack_init_verbs },
16963 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16964 .dac_nids = alc861vd_dac_nids,
16965 .dig_out_nid = ALC861VD_DIGOUT_NID,
16966 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16967 .channel_mode = alc861vd_6stack_modes,
16968 .input_mux = &alc861vd_capture_source,
16969 },
bdd148a3
KY
16970 [ALC861VD_LENOVO] = {
16971 .mixers = { alc861vd_lenovo_mixer },
16972 .init_verbs = { alc861vd_volume_init_verbs,
16973 alc861vd_3stack_init_verbs,
16974 alc861vd_eapd_verbs,
16975 alc861vd_lenovo_unsol_verbs },
16976 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16977 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16978 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16979 .channel_mode = alc861vd_3stack_2ch_modes,
16980 .input_mux = &alc861vd_capture_source,
16981 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16982 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16983 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16984 },
272a527c
KY
16985 [ALC861VD_DALLAS] = {
16986 .mixers = { alc861vd_dallas_mixer },
16987 .init_verbs = { alc861vd_dallas_verbs },
16988 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16989 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16990 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16991 .channel_mode = alc861vd_3stack_2ch_modes,
16992 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16993 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16994 .setup = alc861vd_dallas_setup,
16995 .init_hook = alc_automute_amp,
d1a991a6
KY
16996 },
16997 [ALC861VD_HP] = {
16998 .mixers = { alc861vd_hp_mixer },
16999 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17000 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17001 .dac_nids = alc861vd_dac_nids,
d1a991a6 17002 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17003 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17004 .channel_mode = alc861vd_3stack_2ch_modes,
17005 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 17006 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
17007 .setup = alc861vd_dallas_setup,
17008 .init_hook = alc_automute_amp,
ea1fb29a 17009 },
13c94744
TI
17010 [ALC660VD_ASUS_V1S] = {
17011 .mixers = { alc861vd_lenovo_mixer },
17012 .init_verbs = { alc861vd_volume_init_verbs,
17013 alc861vd_3stack_init_verbs,
17014 alc861vd_eapd_verbs,
17015 alc861vd_lenovo_unsol_verbs },
17016 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17017 .dac_nids = alc660vd_dac_nids,
17018 .dig_out_nid = ALC861VD_DIGOUT_NID,
17019 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17020 .channel_mode = alc861vd_3stack_2ch_modes,
17021 .input_mux = &alc861vd_capture_source,
17022 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17023 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17024 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17025 },
f32610ed
JS
17026};
17027
17028/*
17029 * BIOS auto configuration
17030 */
05f5f477
TI
17031static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17032 const struct auto_pin_cfg *cfg)
17033{
7167594a 17034 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17035}
17036
17037
f32610ed
JS
17038static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17039 hda_nid_t nid, int pin_type, int dac_idx)
17040{
f6c7e546 17041 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17042}
17043
17044static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17045{
17046 struct alc_spec *spec = codec->spec;
17047 int i;
17048
17049 for (i = 0; i <= HDA_SIDE; i++) {
17050 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17051 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17052 if (nid)
17053 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17054 pin_type, i);
f32610ed
JS
17055 }
17056}
17057
17058
17059static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17060{
17061 struct alc_spec *spec = codec->spec;
17062 hda_nid_t pin;
17063
17064 pin = spec->autocfg.hp_pins[0];
def319f9 17065 if (pin) /* connect to front and use dac 0 */
f32610ed 17066 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17067 pin = spec->autocfg.speaker_pins[0];
17068 if (pin)
17069 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17070}
17071
f32610ed
JS
17072#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17073
17074static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17075{
17076 struct alc_spec *spec = codec->spec;
66ceeb6b 17077 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17078 int i;
17079
66ceeb6b
TI
17080 for (i = 0; i < cfg->num_inputs; i++) {
17081 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17082 if (alc_is_input_pin(codec, nid)) {
30ea098f 17083 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17084 if (nid != ALC861VD_PIN_CD_NID &&
17085 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17086 snd_hda_codec_write(codec, nid, 0,
17087 AC_VERB_SET_AMP_GAIN_MUTE,
17088 AMP_OUT_MUTE);
17089 }
17090 }
17091}
17092
f511b01c
TI
17093#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17094
f32610ed
JS
17095#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17096#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17097
17098/* add playback controls from the parsed DAC table */
569ed348 17099/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17100 * different NIDs for mute/unmute switch and volume control */
17101static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17102 const struct auto_pin_cfg *cfg)
17103{
ea734963
TI
17104 static const char * const chname[4] = {
17105 "Front", "Surround", "CLFE", "Side"
17106 };
bcb2f0f5 17107 const char *pfx = alc_get_line_out_pfx(cfg, true);
f32610ed
JS
17108 hda_nid_t nid_v, nid_s;
17109 int i, err;
17110
17111 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 17112 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17113 continue;
17114 nid_v = alc861vd_idx_to_mixer_vol(
17115 alc880_dac_to_idx(
17116 spec->multiout.dac_nids[i]));
17117 nid_s = alc861vd_idx_to_mixer_switch(
17118 alc880_dac_to_idx(
17119 spec->multiout.dac_nids[i]));
17120
bcb2f0f5 17121 if (!pfx && i == 2) {
f32610ed 17122 /* Center/LFE */
0afe5f89
TI
17123 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17124 "Center",
f12ab1e0
TI
17125 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17126 HDA_OUTPUT));
17127 if (err < 0)
f32610ed 17128 return err;
0afe5f89
TI
17129 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17130 "LFE",
f12ab1e0
TI
17131 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17132 HDA_OUTPUT));
17133 if (err < 0)
f32610ed 17134 return err;
0afe5f89
TI
17135 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17136 "Center",
f12ab1e0
TI
17137 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17138 HDA_INPUT));
17139 if (err < 0)
f32610ed 17140 return err;
0afe5f89
TI
17141 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17142 "LFE",
f12ab1e0
TI
17143 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17144 HDA_INPUT));
17145 if (err < 0)
f32610ed
JS
17146 return err;
17147 } else {
bcb2f0f5
TI
17148 const char *name = pfx;
17149 if (!name)
17150 name = chname[i];
17151 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17152 name, i,
f12ab1e0
TI
17153 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17154 HDA_OUTPUT));
17155 if (err < 0)
f32610ed 17156 return err;
bcb2f0f5
TI
17157 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17158 name, i,
bdd148a3 17159 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17160 HDA_INPUT));
17161 if (err < 0)
f32610ed
JS
17162 return err;
17163 }
17164 }
17165 return 0;
17166}
17167
17168/* add playback controls for speaker and HP outputs */
17169/* Based on ALC880 version. But ALC861VD has separate,
17170 * different NIDs for mute/unmute switch and volume control */
17171static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17172 hda_nid_t pin, const char *pfx)
17173{
17174 hda_nid_t nid_v, nid_s;
17175 int err;
f32610ed 17176
f12ab1e0 17177 if (!pin)
f32610ed
JS
17178 return 0;
17179
17180 if (alc880_is_fixed_pin(pin)) {
17181 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17182 /* specify the DAC as the extra output */
f12ab1e0 17183 if (!spec->multiout.hp_nid)
f32610ed
JS
17184 spec->multiout.hp_nid = nid_v;
17185 else
17186 spec->multiout.extra_out_nid[0] = nid_v;
17187 /* control HP volume/switch on the output mixer amp */
17188 nid_v = alc861vd_idx_to_mixer_vol(
17189 alc880_fixed_pin_idx(pin));
17190 nid_s = alc861vd_idx_to_mixer_switch(
17191 alc880_fixed_pin_idx(pin));
17192
0afe5f89 17193 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17194 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17195 if (err < 0)
f32610ed 17196 return err;
0afe5f89 17197 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17198 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17199 if (err < 0)
f32610ed
JS
17200 return err;
17201 } else if (alc880_is_multi_pin(pin)) {
17202 /* set manual connection */
17203 /* we have only a switch on HP-out PIN */
0afe5f89 17204 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17205 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17206 if (err < 0)
f32610ed
JS
17207 return err;
17208 }
17209 return 0;
17210}
17211
17212/* parse the BIOS configuration and set up the alc_spec
17213 * return 1 if successful, 0 if the proper config is not found,
17214 * or a negative error code
17215 * Based on ALC880 version - had to change it to override
17216 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17217static int alc861vd_parse_auto_config(struct hda_codec *codec)
17218{
17219 struct alc_spec *spec = codec->spec;
17220 int err;
17221 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17222
f12ab1e0
TI
17223 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17224 alc861vd_ignore);
17225 if (err < 0)
f32610ed 17226 return err;
f12ab1e0 17227 if (!spec->autocfg.line_outs)
f32610ed
JS
17228 return 0; /* can't find valid BIOS pin config */
17229
f12ab1e0
TI
17230 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17231 if (err < 0)
17232 return err;
17233 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17234 if (err < 0)
17235 return err;
17236 err = alc861vd_auto_create_extra_out(spec,
17237 spec->autocfg.speaker_pins[0],
17238 "Speaker");
17239 if (err < 0)
17240 return err;
17241 err = alc861vd_auto_create_extra_out(spec,
17242 spec->autocfg.hp_pins[0],
17243 "Headphone");
17244 if (err < 0)
17245 return err;
05f5f477 17246 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17247 if (err < 0)
f32610ed
JS
17248 return err;
17249
17250 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17251
757899ac 17252 alc_auto_parse_digital(codec);
f32610ed 17253
603c4019 17254 if (spec->kctls.list)
d88897ea 17255 add_mixer(spec, spec->kctls.list);
f32610ed 17256
d88897ea 17257 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17258
17259 spec->num_mux_defs = 1;
61b9b9b1 17260 spec->input_mux = &spec->private_imux[0];
f32610ed 17261
776e184e
TI
17262 err = alc_auto_add_mic_boost(codec);
17263 if (err < 0)
17264 return err;
17265
6227cdce 17266 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17267
f32610ed
JS
17268 return 1;
17269}
17270
17271/* additional initialization for auto-configuration model */
17272static void alc861vd_auto_init(struct hda_codec *codec)
17273{
f6c7e546 17274 struct alc_spec *spec = codec->spec;
f32610ed
JS
17275 alc861vd_auto_init_multi_out(codec);
17276 alc861vd_auto_init_hp_out(codec);
17277 alc861vd_auto_init_analog_input(codec);
f511b01c 17278 alc861vd_auto_init_input_src(codec);
757899ac 17279 alc_auto_init_digital(codec);
f6c7e546 17280 if (spec->unsol_event)
7fb0d78f 17281 alc_inithook(codec);
f32610ed
JS
17282}
17283
f8f25ba3
TI
17284enum {
17285 ALC660VD_FIX_ASUS_GPIO1
17286};
17287
17288/* reset GPIO1 */
f8f25ba3
TI
17289static const struct alc_fixup alc861vd_fixups[] = {
17290 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17291 .type = ALC_FIXUP_VERBS,
17292 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17293 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17294 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17295 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17296 { }
17297 }
f8f25ba3
TI
17298 },
17299};
17300
17301static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17302 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17303 {}
17304};
17305
f32610ed
JS
17306static int patch_alc861vd(struct hda_codec *codec)
17307{
17308 struct alc_spec *spec;
17309 int err, board_config;
17310
17311 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17312 if (spec == NULL)
17313 return -ENOMEM;
17314
17315 codec->spec = spec;
17316
17317 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17318 alc861vd_models,
17319 alc861vd_cfg_tbl);
17320
17321 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17322 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17323 codec->chip_name);
f32610ed
JS
17324 board_config = ALC861VD_AUTO;
17325 }
17326
b5bfbc67
TI
17327 if (board_config == ALC861VD_AUTO) {
17328 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17329 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17330 }
f8f25ba3 17331
f32610ed
JS
17332 if (board_config == ALC861VD_AUTO) {
17333 /* automatic parse from the BIOS config */
17334 err = alc861vd_parse_auto_config(codec);
17335 if (err < 0) {
17336 alc_free(codec);
17337 return err;
f12ab1e0 17338 } else if (!err) {
f32610ed
JS
17339 printk(KERN_INFO
17340 "hda_codec: Cannot set up configuration "
17341 "from BIOS. Using base mode...\n");
17342 board_config = ALC861VD_3ST;
17343 }
17344 }
17345
680cd536
KK
17346 err = snd_hda_attach_beep_device(codec, 0x23);
17347 if (err < 0) {
17348 alc_free(codec);
17349 return err;
17350 }
17351
f32610ed 17352 if (board_config != ALC861VD_AUTO)
e9c364c0 17353 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17354
2f893286 17355 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17356 /* always turn on EAPD */
d88897ea 17357 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17358 }
17359
f32610ed
JS
17360 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17361 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17362
f32610ed
JS
17363 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17364 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17365
dd704698
TI
17366 if (!spec->adc_nids) {
17367 spec->adc_nids = alc861vd_adc_nids;
17368 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17369 }
17370 if (!spec->capsrc_nids)
17371 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17372
b59bdf3b 17373 set_capture_mixer(codec);
45bdd1c1 17374 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17375
2134ea4f
TI
17376 spec->vmaster_nid = 0x02;
17377
b5bfbc67 17378 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17379
f32610ed
JS
17380 codec->patch_ops = alc_patch_ops;
17381
17382 if (board_config == ALC861VD_AUTO)
17383 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17384#ifdef CONFIG_SND_HDA_POWER_SAVE
17385 if (!spec->loopback.amplist)
17386 spec->loopback.amplist = alc861vd_loopbacks;
17387#endif
f32610ed
JS
17388
17389 return 0;
17390}
17391
bc9f98a9
KY
17392/*
17393 * ALC662 support
17394 *
17395 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17396 * configuration. Each pin widget can choose any input DACs and a mixer.
17397 * Each ADC is connected from a mixer of all inputs. This makes possible
17398 * 6-channel independent captures.
17399 *
17400 * In addition, an independent DAC for the multi-playback (not used in this
17401 * driver yet).
17402 */
17403#define ALC662_DIGOUT_NID 0x06
17404#define ALC662_DIGIN_NID 0x0a
17405
17406static hda_nid_t alc662_dac_nids[4] = {
17407 /* front, rear, clfe, rear_surr */
17408 0x02, 0x03, 0x04
17409};
17410
622e84cd
KY
17411static hda_nid_t alc272_dac_nids[2] = {
17412 0x02, 0x03
17413};
17414
b59bdf3b 17415static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17416 /* ADC1-2 */
b59bdf3b 17417 0x09, 0x08
bc9f98a9 17418};
e1406348 17419
622e84cd
KY
17420static hda_nid_t alc272_adc_nids[1] = {
17421 /* ADC1-2 */
17422 0x08,
17423};
17424
b59bdf3b 17425static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17426static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17427
e1406348 17428
bc9f98a9
KY
17429/* input MUX */
17430/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17431static struct hda_input_mux alc662_capture_source = {
17432 .num_items = 4,
17433 .items = {
17434 { "Mic", 0x0 },
17435 { "Front Mic", 0x1 },
17436 { "Line", 0x2 },
17437 { "CD", 0x4 },
17438 },
17439};
17440
17441static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17442 .num_items = 2,
17443 .items = {
17444 { "Mic", 0x1 },
17445 { "Line", 0x2 },
17446 },
17447};
291702f0 17448
6dda9f4a
KY
17449static struct hda_input_mux alc663_capture_source = {
17450 .num_items = 3,
17451 .items = {
17452 { "Mic", 0x0 },
17453 { "Front Mic", 0x1 },
17454 { "Line", 0x2 },
17455 },
17456};
17457
4f5d1706 17458#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17459static struct hda_input_mux alc272_nc10_capture_source = {
17460 .num_items = 16,
17461 .items = {
17462 { "Autoselect Mic", 0x0 },
17463 { "Internal Mic", 0x1 },
17464 { "In-0x02", 0x2 },
17465 { "In-0x03", 0x3 },
17466 { "In-0x04", 0x4 },
17467 { "In-0x05", 0x5 },
17468 { "In-0x06", 0x6 },
17469 { "In-0x07", 0x7 },
17470 { "In-0x08", 0x8 },
17471 { "In-0x09", 0x9 },
17472 { "In-0x0a", 0x0a },
17473 { "In-0x0b", 0x0b },
17474 { "In-0x0c", 0x0c },
17475 { "In-0x0d", 0x0d },
17476 { "In-0x0e", 0x0e },
17477 { "In-0x0f", 0x0f },
17478 },
17479};
17480#endif
17481
bc9f98a9
KY
17482/*
17483 * 2ch mode
17484 */
17485static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17486 { 2, NULL }
17487};
17488
17489/*
17490 * 2ch mode
17491 */
17492static struct hda_verb alc662_3ST_ch2_init[] = {
17493 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17494 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17495 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17496 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17497 { } /* end */
17498};
17499
17500/*
17501 * 6ch mode
17502 */
17503static struct hda_verb alc662_3ST_ch6_init[] = {
17504 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17505 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17506 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17507 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17508 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17509 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17510 { } /* end */
17511};
17512
17513static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17514 { 2, alc662_3ST_ch2_init },
17515 { 6, alc662_3ST_ch6_init },
17516};
17517
17518/*
17519 * 2ch mode
17520 */
17521static struct hda_verb alc662_sixstack_ch6_init[] = {
17522 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17523 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17524 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17525 { } /* end */
17526};
17527
17528/*
17529 * 6ch mode
17530 */
17531static struct hda_verb alc662_sixstack_ch8_init[] = {
17532 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17533 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17534 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17535 { } /* end */
17536};
17537
17538static struct hda_channel_mode alc662_5stack_modes[2] = {
17539 { 2, alc662_sixstack_ch6_init },
17540 { 6, alc662_sixstack_ch8_init },
17541};
17542
17543/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17544 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17545 */
17546
17547static struct snd_kcontrol_new alc662_base_mixer[] = {
17548 /* output mixer control */
17549 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17550 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17551 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17552 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17553 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17554 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17555 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17556 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17557 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17558
17559 /*Input mixer control */
17560 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17561 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17562 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17563 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17564 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17565 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17566 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17567 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17568 { } /* end */
17569};
17570
17571static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17572 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17573 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17575 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17576 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17582 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17583 { } /* end */
17584};
17585
17586static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17587 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17588 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17589 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17590 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17591 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17592 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17593 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17594 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17595 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17596 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17597 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17598 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17599 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17602 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17603 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17604 { } /* end */
17605};
17606
17607static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17608 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17609 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17610 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17611 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17612 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17613 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17614 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17615 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17616 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17617 { } /* end */
17618};
17619
291702f0 17620static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17621 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17622 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17623
5f99f86a 17624 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17625 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17626 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17627
5f99f86a 17628 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17629 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17630 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17631 { } /* end */
17632};
17633
8c427226 17634static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17635 ALC262_HIPPO_MASTER_SWITCH,
17636 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17637 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17638 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17639 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17640 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17641 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17642 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17643 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17644 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17645 { } /* end */
17646};
17647
f1d4e28b
KY
17648static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17649 .ops = &snd_hda_bind_vol,
17650 .values = {
17651 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17652 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17653 0
17654 },
17655};
17656
17657static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17658 .ops = &snd_hda_bind_sw,
17659 .values = {
17660 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17661 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17662 0
17663 },
17664};
17665
6dda9f4a 17666static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17667 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17668 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17669 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17670 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17671 { } /* end */
17672};
17673
17674static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17675 .ops = &snd_hda_bind_sw,
17676 .values = {
17677 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17678 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17679 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17680 0
17681 },
17682};
17683
17684static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17685 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17686 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17687 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17688 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17689 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17690 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17691
17692 { } /* end */
17693};
17694
17695static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17696 .ops = &snd_hda_bind_sw,
17697 .values = {
17698 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17699 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17700 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17701 0
17702 },
17703};
17704
17705static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17706 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17707 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17710 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17711 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17712 { } /* end */
17713};
17714
17715static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17716 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17717 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17718 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17721 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17722 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17723 { } /* end */
17724};
17725
17726static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17727 .ops = &snd_hda_bind_vol,
17728 .values = {
17729 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17730 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17731 0
17732 },
17733};
17734
17735static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17736 .ops = &snd_hda_bind_sw,
17737 .values = {
17738 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17739 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17740 0
17741 },
17742};
17743
17744static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17745 HDA_BIND_VOL("Master Playback Volume",
17746 &alc663_asus_two_bind_master_vol),
17747 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17748 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17749 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17750 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17751 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17752 { } /* end */
17753};
17754
17755static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17756 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17757 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17758 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17759 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17761 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17762 { } /* end */
17763};
17764
17765static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17766 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17767 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17768 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17769 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17770 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17771
17772 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17773 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17774 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17775 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17776 { } /* end */
17777};
17778
17779static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17780 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17781 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17783
17784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17785 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17786 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17787 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17788 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17789 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17790 { } /* end */
17791};
17792
ebb83eeb
KY
17793static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17794 .ops = &snd_hda_bind_sw,
17795 .values = {
17796 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17797 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17798 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17799 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17800 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17801 0
17802 },
17803};
17804
17805static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17806 .ops = &snd_hda_bind_sw,
17807 .values = {
17808 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17809 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17810 0
17811 },
17812};
17813
17814static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17815 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17816 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17817 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17818 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17819 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17820 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17821 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17822 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17823 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17824 { } /* end */
17825};
17826
17827static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17828 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17829 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17830 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17831 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17832 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17835 { } /* end */
17836};
17837
17838
bc9f98a9
KY
17839static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17840 {
17841 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17842 .name = "Channel Mode",
17843 .info = alc_ch_mode_info,
17844 .get = alc_ch_mode_get,
17845 .put = alc_ch_mode_put,
17846 },
17847 { } /* end */
17848};
17849
17850static struct hda_verb alc662_init_verbs[] = {
17851 /* ADC: mute amp left and right */
17852 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17853 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17854
b60dd394
KY
17855 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17856 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17857 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17858 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17859 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17860 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17861
17862 /* Front Pin: output 0 (0x0c) */
17863 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17864 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17865
17866 /* Rear Pin: output 1 (0x0d) */
17867 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17868 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17869
17870 /* CLFE Pin: output 2 (0x0e) */
17871 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17872 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17873
17874 /* Mic (rear) pin: input vref at 80% */
17875 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17876 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17877 /* Front Mic pin: input vref at 80% */
17878 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17879 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17880 /* Line In pin: input */
17881 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17882 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17883 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17884 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17885 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17886 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17887 /* CD pin widget for input */
17888 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17889
17890 /* FIXME: use matrix-type input source selection */
17891 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17892 /* Input mixer */
17893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17894 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17895
17896 /* always trun on EAPD */
17897 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17898 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17899
bc9f98a9
KY
17900 { }
17901};
17902
cec27c89
KY
17903static struct hda_verb alc663_init_verbs[] = {
17904 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17905 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17906 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17907 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17908 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17909 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17910 { }
17911};
17912
17913static struct hda_verb alc272_init_verbs[] = {
17914 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17915 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17916 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17917 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17918 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17919 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17920 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17921 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17922 { }
17923};
17924
bc9f98a9
KY
17925static struct hda_verb alc662_sue_init_verbs[] = {
17926 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17927 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17928 {}
17929};
17930
17931static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17932 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17933 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17934 {}
bc9f98a9
KY
17935};
17936
8c427226
KY
17937/* Set Unsolicited Event*/
17938static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17939 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17940 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17941 {}
17942};
17943
6dda9f4a 17944static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17945 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17946 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17947 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17948 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17949 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17950 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17951 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17952 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17953 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17954 {}
17955};
17956
17957static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17958 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17959 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17960 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17963 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17964 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17965 {}
17966};
17967
17968static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17969 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17970 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17971 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17972 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17973 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17974 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17975 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17976 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17977 {}
17978};
6dda9f4a 17979
f1d4e28b
KY
17980static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17981 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17982 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17983 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17986 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17987 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17988 {}
17989};
6dda9f4a 17990
f1d4e28b
KY
17991static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17993 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17994 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17995 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17996 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17997 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17998 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17999 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18000 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18001 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18002 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18003 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18004 {}
18005};
18006
18007static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18008 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18009 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18010 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18011 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18012 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18014 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18015 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18016 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18017 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18018 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18019 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18020 {}
18021};
18022
18023static struct hda_verb alc663_g71v_init_verbs[] = {
18024 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18025 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18026 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18027
18028 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18029 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18030 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18031
18032 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18033 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18034 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18035 {}
18036};
18037
18038static struct hda_verb alc663_g50v_init_verbs[] = {
18039 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18040 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18041 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18042
18043 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18044 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18045 {}
18046};
18047
f1d4e28b
KY
18048static struct hda_verb alc662_ecs_init_verbs[] = {
18049 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18050 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18051 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18052 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18053 {}
18054};
18055
622e84cd
KY
18056static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18057 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18058 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18059 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18060 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18061 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18062 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18063 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18064 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18066 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18067 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18068 {}
18069};
18070
18071static struct hda_verb alc272_dell_init_verbs[] = {
18072 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18073 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18074 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18075 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18076 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18077 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18078 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18079 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18080 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18081 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18082 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18083 {}
18084};
18085
ebb83eeb
KY
18086static struct hda_verb alc663_mode7_init_verbs[] = {
18087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18088 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18089 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18090 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18091 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18092 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18093 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18094 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18095 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18096 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18098 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18099 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18100 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18101 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18102 {}
18103};
18104
18105static struct hda_verb alc663_mode8_init_verbs[] = {
18106 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18107 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18108 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18109 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18110 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18111 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18112 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18113 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18114 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18115 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18116 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18119 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18120 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18121 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18122 {}
18123};
18124
f1d4e28b
KY
18125static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18126 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18127 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18128 { } /* end */
18129};
18130
622e84cd
KY
18131static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18132 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18133 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18134 { } /* end */
18135};
18136
bc9f98a9
KY
18137static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18138{
18139 unsigned int present;
f12ab1e0 18140 unsigned char bits;
bc9f98a9 18141
864f92be 18142 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 18143 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18144
47fd830a
TI
18145 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18146 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18147}
18148
18149static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18150{
18151 unsigned int present;
f12ab1e0 18152 unsigned char bits;
bc9f98a9 18153
864f92be 18154 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 18155 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18156
47fd830a
TI
18157 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18158 HDA_AMP_MUTE, bits);
18159 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18160 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18161}
18162
18163static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18164 unsigned int res)
18165{
18166 if ((res >> 26) == ALC880_HP_EVENT)
18167 alc662_lenovo_101e_all_automute(codec);
18168 if ((res >> 26) == ALC880_FRONT_EVENT)
18169 alc662_lenovo_101e_ispeaker_automute(codec);
18170}
18171
291702f0
KY
18172/* unsolicited event for HP jack sensing */
18173static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18174 unsigned int res)
18175{
291702f0 18176 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18177 alc_mic_automute(codec);
42171c17
TI
18178 else
18179 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18180}
18181
4f5d1706
TI
18182static void alc662_eeepc_setup(struct hda_codec *codec)
18183{
18184 struct alc_spec *spec = codec->spec;
18185
18186 alc262_hippo1_setup(codec);
18187 spec->ext_mic.pin = 0x18;
18188 spec->ext_mic.mux_idx = 0;
18189 spec->int_mic.pin = 0x19;
18190 spec->int_mic.mux_idx = 1;
18191 spec->auto_mic = 1;
18192}
18193
291702f0
KY
18194static void alc662_eeepc_inithook(struct hda_codec *codec)
18195{
4f5d1706
TI
18196 alc262_hippo_automute(codec);
18197 alc_mic_automute(codec);
291702f0
KY
18198}
18199
4f5d1706 18200static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18201{
42171c17
TI
18202 struct alc_spec *spec = codec->spec;
18203
18204 spec->autocfg.hp_pins[0] = 0x14;
18205 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18206}
18207
4f5d1706
TI
18208#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18209
6dda9f4a
KY
18210static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18211{
18212 unsigned int present;
18213 unsigned char bits;
18214
864f92be 18215 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18216 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18217 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18218 HDA_AMP_MUTE, bits);
f1d4e28b 18219 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18220 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18221}
18222
18223static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18224{
18225 unsigned int present;
18226 unsigned char bits;
18227
864f92be 18228 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18229 bits = present ? HDA_AMP_MUTE : 0;
18230 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18231 HDA_AMP_MUTE, bits);
f1d4e28b 18232 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18233 HDA_AMP_MUTE, bits);
f1d4e28b 18234 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18235 HDA_AMP_MUTE, bits);
f1d4e28b 18236 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18237 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18238}
18239
18240static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18241{
18242 unsigned int present;
18243 unsigned char bits;
18244
864f92be 18245 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18246 bits = present ? HDA_AMP_MUTE : 0;
18247 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18248 HDA_AMP_MUTE, bits);
f1d4e28b 18249 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18250 HDA_AMP_MUTE, bits);
f1d4e28b 18251 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18252 HDA_AMP_MUTE, bits);
f1d4e28b 18253 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18254 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18255}
18256
18257static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18258{
18259 unsigned int present;
18260 unsigned char bits;
18261
864f92be 18262 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18263 bits = present ? 0 : PIN_OUT;
18264 snd_hda_codec_write(codec, 0x14, 0,
18265 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18266}
18267
18268static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18269{
18270 unsigned int present1, present2;
18271
864f92be
WF
18272 present1 = snd_hda_jack_detect(codec, 0x21);
18273 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18274
18275 if (present1 || present2) {
18276 snd_hda_codec_write_cache(codec, 0x14, 0,
18277 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18278 } else {
18279 snd_hda_codec_write_cache(codec, 0x14, 0,
18280 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18281 }
18282}
18283
18284static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18285{
18286 unsigned int present1, present2;
18287
864f92be
WF
18288 present1 = snd_hda_jack_detect(codec, 0x1b);
18289 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18290
18291 if (present1 || present2) {
18292 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18293 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18294 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18295 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18296 } else {
18297 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18298 HDA_AMP_MUTE, 0);
f1d4e28b 18299 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18300 HDA_AMP_MUTE, 0);
f1d4e28b 18301 }
6dda9f4a
KY
18302}
18303
ebb83eeb
KY
18304static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18305{
18306 unsigned int present1, present2;
18307
18308 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18309 AC_VERB_GET_PIN_SENSE, 0)
18310 & AC_PINSENSE_PRESENCE;
18311 present2 = snd_hda_codec_read(codec, 0x21, 0,
18312 AC_VERB_GET_PIN_SENSE, 0)
18313 & AC_PINSENSE_PRESENCE;
18314
18315 if (present1 || present2) {
18316 snd_hda_codec_write_cache(codec, 0x14, 0,
18317 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18318 snd_hda_codec_write_cache(codec, 0x17, 0,
18319 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18320 } else {
18321 snd_hda_codec_write_cache(codec, 0x14, 0,
18322 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18323 snd_hda_codec_write_cache(codec, 0x17, 0,
18324 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18325 }
18326}
18327
18328static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18329{
18330 unsigned int present1, present2;
18331
18332 present1 = snd_hda_codec_read(codec, 0x21, 0,
18333 AC_VERB_GET_PIN_SENSE, 0)
18334 & AC_PINSENSE_PRESENCE;
18335 present2 = snd_hda_codec_read(codec, 0x15, 0,
18336 AC_VERB_GET_PIN_SENSE, 0)
18337 & AC_PINSENSE_PRESENCE;
18338
18339 if (present1 || present2) {
18340 snd_hda_codec_write_cache(codec, 0x14, 0,
18341 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18342 snd_hda_codec_write_cache(codec, 0x17, 0,
18343 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18344 } else {
18345 snd_hda_codec_write_cache(codec, 0x14, 0,
18346 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18347 snd_hda_codec_write_cache(codec, 0x17, 0,
18348 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18349 }
18350}
18351
6dda9f4a
KY
18352static void alc663_m51va_unsol_event(struct hda_codec *codec,
18353 unsigned int res)
18354{
18355 switch (res >> 26) {
18356 case ALC880_HP_EVENT:
18357 alc663_m51va_speaker_automute(codec);
18358 break;
18359 case ALC880_MIC_EVENT:
4f5d1706 18360 alc_mic_automute(codec);
6dda9f4a
KY
18361 break;
18362 }
18363}
18364
4f5d1706
TI
18365static void alc663_m51va_setup(struct hda_codec *codec)
18366{
18367 struct alc_spec *spec = codec->spec;
18368 spec->ext_mic.pin = 0x18;
18369 spec->ext_mic.mux_idx = 0;
18370 spec->int_mic.pin = 0x12;
ebb83eeb 18371 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18372 spec->auto_mic = 1;
18373}
18374
6dda9f4a
KY
18375static void alc663_m51va_inithook(struct hda_codec *codec)
18376{
18377 alc663_m51va_speaker_automute(codec);
4f5d1706 18378 alc_mic_automute(codec);
6dda9f4a
KY
18379}
18380
f1d4e28b 18381/* ***************** Mode1 ******************************/
4f5d1706 18382#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18383
18384static void alc663_mode1_setup(struct hda_codec *codec)
18385{
18386 struct alc_spec *spec = codec->spec;
18387 spec->ext_mic.pin = 0x18;
18388 spec->ext_mic.mux_idx = 0;
18389 spec->int_mic.pin = 0x19;
18390 spec->int_mic.mux_idx = 1;
18391 spec->auto_mic = 1;
18392}
18393
4f5d1706 18394#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18395
f1d4e28b
KY
18396/* ***************** Mode2 ******************************/
18397static void alc662_mode2_unsol_event(struct hda_codec *codec,
18398 unsigned int res)
18399{
18400 switch (res >> 26) {
18401 case ALC880_HP_EVENT:
18402 alc662_f5z_speaker_automute(codec);
18403 break;
18404 case ALC880_MIC_EVENT:
4f5d1706 18405 alc_mic_automute(codec);
f1d4e28b
KY
18406 break;
18407 }
18408}
18409
ebb83eeb 18410#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18411
f1d4e28b
KY
18412static void alc662_mode2_inithook(struct hda_codec *codec)
18413{
18414 alc662_f5z_speaker_automute(codec);
4f5d1706 18415 alc_mic_automute(codec);
f1d4e28b
KY
18416}
18417/* ***************** Mode3 ******************************/
18418static void alc663_mode3_unsol_event(struct hda_codec *codec,
18419 unsigned int res)
18420{
18421 switch (res >> 26) {
18422 case ALC880_HP_EVENT:
18423 alc663_two_hp_m1_speaker_automute(codec);
18424 break;
18425 case ALC880_MIC_EVENT:
4f5d1706 18426 alc_mic_automute(codec);
f1d4e28b
KY
18427 break;
18428 }
18429}
18430
ebb83eeb 18431#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18432
f1d4e28b
KY
18433static void alc663_mode3_inithook(struct hda_codec *codec)
18434{
18435 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18436 alc_mic_automute(codec);
f1d4e28b
KY
18437}
18438/* ***************** Mode4 ******************************/
18439static void alc663_mode4_unsol_event(struct hda_codec *codec,
18440 unsigned int res)
18441{
18442 switch (res >> 26) {
18443 case ALC880_HP_EVENT:
18444 alc663_21jd_two_speaker_automute(codec);
18445 break;
18446 case ALC880_MIC_EVENT:
4f5d1706 18447 alc_mic_automute(codec);
f1d4e28b
KY
18448 break;
18449 }
18450}
18451
ebb83eeb 18452#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18453
f1d4e28b
KY
18454static void alc663_mode4_inithook(struct hda_codec *codec)
18455{
18456 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18457 alc_mic_automute(codec);
f1d4e28b
KY
18458}
18459/* ***************** Mode5 ******************************/
18460static void alc663_mode5_unsol_event(struct hda_codec *codec,
18461 unsigned int res)
18462{
18463 switch (res >> 26) {
18464 case ALC880_HP_EVENT:
18465 alc663_15jd_two_speaker_automute(codec);
18466 break;
18467 case ALC880_MIC_EVENT:
4f5d1706 18468 alc_mic_automute(codec);
f1d4e28b
KY
18469 break;
18470 }
18471}
18472
ebb83eeb 18473#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18474
f1d4e28b
KY
18475static void alc663_mode5_inithook(struct hda_codec *codec)
18476{
18477 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18478 alc_mic_automute(codec);
f1d4e28b
KY
18479}
18480/* ***************** Mode6 ******************************/
18481static void alc663_mode6_unsol_event(struct hda_codec *codec,
18482 unsigned int res)
18483{
18484 switch (res >> 26) {
18485 case ALC880_HP_EVENT:
18486 alc663_two_hp_m2_speaker_automute(codec);
18487 break;
18488 case ALC880_MIC_EVENT:
4f5d1706 18489 alc_mic_automute(codec);
f1d4e28b
KY
18490 break;
18491 }
18492}
18493
ebb83eeb 18494#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18495
f1d4e28b
KY
18496static void alc663_mode6_inithook(struct hda_codec *codec)
18497{
18498 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18499 alc_mic_automute(codec);
f1d4e28b
KY
18500}
18501
ebb83eeb
KY
18502/* ***************** Mode7 ******************************/
18503static void alc663_mode7_unsol_event(struct hda_codec *codec,
18504 unsigned int res)
18505{
18506 switch (res >> 26) {
18507 case ALC880_HP_EVENT:
18508 alc663_two_hp_m7_speaker_automute(codec);
18509 break;
18510 case ALC880_MIC_EVENT:
18511 alc_mic_automute(codec);
18512 break;
18513 }
18514}
18515
18516#define alc663_mode7_setup alc663_mode1_setup
18517
18518static void alc663_mode7_inithook(struct hda_codec *codec)
18519{
18520 alc663_two_hp_m7_speaker_automute(codec);
18521 alc_mic_automute(codec);
18522}
18523
18524/* ***************** Mode8 ******************************/
18525static void alc663_mode8_unsol_event(struct hda_codec *codec,
18526 unsigned int res)
18527{
18528 switch (res >> 26) {
18529 case ALC880_HP_EVENT:
18530 alc663_two_hp_m8_speaker_automute(codec);
18531 break;
18532 case ALC880_MIC_EVENT:
18533 alc_mic_automute(codec);
18534 break;
18535 }
18536}
18537
18538#define alc663_mode8_setup alc663_m51va_setup
18539
18540static void alc663_mode8_inithook(struct hda_codec *codec)
18541{
18542 alc663_two_hp_m8_speaker_automute(codec);
18543 alc_mic_automute(codec);
18544}
18545
6dda9f4a
KY
18546static void alc663_g71v_hp_automute(struct hda_codec *codec)
18547{
18548 unsigned int present;
18549 unsigned char bits;
18550
864f92be 18551 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18552 bits = present ? HDA_AMP_MUTE : 0;
18553 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18554 HDA_AMP_MUTE, bits);
18555 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18556 HDA_AMP_MUTE, bits);
18557}
18558
18559static void alc663_g71v_front_automute(struct hda_codec *codec)
18560{
18561 unsigned int present;
18562 unsigned char bits;
18563
864f92be 18564 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18565 bits = present ? HDA_AMP_MUTE : 0;
18566 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18567 HDA_AMP_MUTE, bits);
18568}
18569
18570static void alc663_g71v_unsol_event(struct hda_codec *codec,
18571 unsigned int res)
18572{
18573 switch (res >> 26) {
18574 case ALC880_HP_EVENT:
18575 alc663_g71v_hp_automute(codec);
18576 break;
18577 case ALC880_FRONT_EVENT:
18578 alc663_g71v_front_automute(codec);
18579 break;
18580 case ALC880_MIC_EVENT:
4f5d1706 18581 alc_mic_automute(codec);
6dda9f4a
KY
18582 break;
18583 }
18584}
18585
4f5d1706
TI
18586#define alc663_g71v_setup alc663_m51va_setup
18587
6dda9f4a
KY
18588static void alc663_g71v_inithook(struct hda_codec *codec)
18589{
18590 alc663_g71v_front_automute(codec);
18591 alc663_g71v_hp_automute(codec);
4f5d1706 18592 alc_mic_automute(codec);
6dda9f4a
KY
18593}
18594
18595static void alc663_g50v_unsol_event(struct hda_codec *codec,
18596 unsigned int res)
18597{
18598 switch (res >> 26) {
18599 case ALC880_HP_EVENT:
18600 alc663_m51va_speaker_automute(codec);
18601 break;
18602 case ALC880_MIC_EVENT:
4f5d1706 18603 alc_mic_automute(codec);
6dda9f4a
KY
18604 break;
18605 }
18606}
18607
4f5d1706
TI
18608#define alc663_g50v_setup alc663_m51va_setup
18609
6dda9f4a
KY
18610static void alc663_g50v_inithook(struct hda_codec *codec)
18611{
18612 alc663_m51va_speaker_automute(codec);
4f5d1706 18613 alc_mic_automute(codec);
6dda9f4a
KY
18614}
18615
f1d4e28b
KY
18616static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18617 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18618 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18619
5f99f86a 18620 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18621 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18622 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18623
5f99f86a 18624 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18625 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18626 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18627 { } /* end */
18628};
18629
9541ba1d
CP
18630static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18631 /* Master Playback automatically created from Speaker and Headphone */
18632 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18633 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18634 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18636
8607f7c4
DH
18637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18639 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18640
28c4edb7
DH
18641 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18642 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18643 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18644 { } /* end */
18645};
18646
cb53c626
TI
18647#ifdef CONFIG_SND_HDA_POWER_SAVE
18648#define alc662_loopbacks alc880_loopbacks
18649#endif
18650
bc9f98a9 18651
def319f9 18652/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18653#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18654#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18655#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18656#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18657
18658/*
18659 * configuration and preset
18660 */
ea734963 18661static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18662 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18663 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18664 [ALC662_3ST_6ch] = "3stack-6ch",
18665 [ALC662_5ST_DIG] = "6stack-dig",
18666 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18667 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18668 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18669 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18670 [ALC663_ASUS_M51VA] = "m51va",
18671 [ALC663_ASUS_G71V] = "g71v",
18672 [ALC663_ASUS_H13] = "h13",
18673 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18674 [ALC663_ASUS_MODE1] = "asus-mode1",
18675 [ALC662_ASUS_MODE2] = "asus-mode2",
18676 [ALC663_ASUS_MODE3] = "asus-mode3",
18677 [ALC663_ASUS_MODE4] = "asus-mode4",
18678 [ALC663_ASUS_MODE5] = "asus-mode5",
18679 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18680 [ALC663_ASUS_MODE7] = "asus-mode7",
18681 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18682 [ALC272_DELL] = "dell",
18683 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18684 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18685 [ALC662_AUTO] = "auto",
18686};
18687
18688static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18689 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18690 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18691 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18692 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18693 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18694 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18695 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18696 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18697 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18698 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18699 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18700 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18701 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18702 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18703 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18704 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18705 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18706 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18707 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18708 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18709 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18710 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18711 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18712 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18713 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18714 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18715 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18716 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18717 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18718 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18719 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18720 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18721 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18722 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18723 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18724 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18725 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18726 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18727 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18728 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18729 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18730 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18731 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18732 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18733 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18734 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18735 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18736 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18737 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18738 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18739 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18740 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18741 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18742 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18743 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18744 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18745 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18746 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18747 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18748 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18749 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18750 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18751 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18752 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18753 ALC662_3ST_6ch_DIG),
4dee8baa 18754 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18755 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18756 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18757 ALC662_3ST_6ch_DIG),
6227cdce 18758 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18759 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18760 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18761 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18762 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18763 ALC662_3ST_6ch_DIG),
dea0a509
TI
18764 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18765 ALC663_ASUS_H13),
965b76d2 18766 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18767 {}
18768};
18769
18770static struct alc_config_preset alc662_presets[] = {
18771 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18772 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18773 .init_verbs = { alc662_init_verbs },
18774 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18775 .dac_nids = alc662_dac_nids,
18776 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18777 .dig_in_nid = ALC662_DIGIN_NID,
18778 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18779 .channel_mode = alc662_3ST_2ch_modes,
18780 .input_mux = &alc662_capture_source,
18781 },
18782 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18783 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18784 .init_verbs = { alc662_init_verbs },
18785 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18786 .dac_nids = alc662_dac_nids,
18787 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18788 .dig_in_nid = ALC662_DIGIN_NID,
18789 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18790 .channel_mode = alc662_3ST_6ch_modes,
18791 .need_dac_fix = 1,
18792 .input_mux = &alc662_capture_source,
f12ab1e0 18793 },
bc9f98a9 18794 [ALC662_3ST_6ch] = {
f9e336f6 18795 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18796 .init_verbs = { alc662_init_verbs },
18797 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18798 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18799 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18800 .channel_mode = alc662_3ST_6ch_modes,
18801 .need_dac_fix = 1,
18802 .input_mux = &alc662_capture_source,
f12ab1e0 18803 },
bc9f98a9 18804 [ALC662_5ST_DIG] = {
f9e336f6 18805 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18806 .init_verbs = { alc662_init_verbs },
18807 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18808 .dac_nids = alc662_dac_nids,
18809 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18810 .dig_in_nid = ALC662_DIGIN_NID,
18811 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18812 .channel_mode = alc662_5stack_modes,
18813 .input_mux = &alc662_capture_source,
18814 },
18815 [ALC662_LENOVO_101E] = {
f9e336f6 18816 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18817 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18818 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18819 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18821 .channel_mode = alc662_3ST_2ch_modes,
18822 .input_mux = &alc662_lenovo_101e_capture_source,
18823 .unsol_event = alc662_lenovo_101e_unsol_event,
18824 .init_hook = alc662_lenovo_101e_all_automute,
18825 },
291702f0 18826 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18827 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18828 .init_verbs = { alc662_init_verbs,
18829 alc662_eeepc_sue_init_verbs },
18830 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18831 .dac_nids = alc662_dac_nids,
291702f0
KY
18832 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18833 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18834 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18835 .setup = alc662_eeepc_setup,
291702f0
KY
18836 .init_hook = alc662_eeepc_inithook,
18837 },
8c427226 18838 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18839 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18840 alc662_chmode_mixer },
18841 .init_verbs = { alc662_init_verbs,
18842 alc662_eeepc_ep20_sue_init_verbs },
18843 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18844 .dac_nids = alc662_dac_nids,
8c427226
KY
18845 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18846 .channel_mode = alc662_3ST_6ch_modes,
18847 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18848 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18849 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18850 .init_hook = alc662_eeepc_ep20_inithook,
18851 },
f1d4e28b 18852 [ALC662_ECS] = {
f9e336f6 18853 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18854 .init_verbs = { alc662_init_verbs,
18855 alc662_ecs_init_verbs },
18856 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18857 .dac_nids = alc662_dac_nids,
18858 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18859 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18860 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18861 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18862 .init_hook = alc662_eeepc_inithook,
18863 },
6dda9f4a 18864 [ALC663_ASUS_M51VA] = {
f9e336f6 18865 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18866 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18867 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18868 .dac_nids = alc662_dac_nids,
18869 .dig_out_nid = ALC662_DIGOUT_NID,
18870 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18871 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18872 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18873 .setup = alc663_m51va_setup,
6dda9f4a
KY
18874 .init_hook = alc663_m51va_inithook,
18875 },
18876 [ALC663_ASUS_G71V] = {
f9e336f6 18877 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18878 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18879 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18880 .dac_nids = alc662_dac_nids,
18881 .dig_out_nid = ALC662_DIGOUT_NID,
18882 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18883 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18884 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18885 .setup = alc663_g71v_setup,
6dda9f4a
KY
18886 .init_hook = alc663_g71v_inithook,
18887 },
18888 [ALC663_ASUS_H13] = {
f9e336f6 18889 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18890 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18891 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18892 .dac_nids = alc662_dac_nids,
18893 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18894 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18895 .unsol_event = alc663_m51va_unsol_event,
18896 .init_hook = alc663_m51va_inithook,
18897 },
18898 [ALC663_ASUS_G50V] = {
f9e336f6 18899 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18900 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18901 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18902 .dac_nids = alc662_dac_nids,
18903 .dig_out_nid = ALC662_DIGOUT_NID,
18904 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18905 .channel_mode = alc662_3ST_6ch_modes,
18906 .input_mux = &alc663_capture_source,
18907 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18908 .setup = alc663_g50v_setup,
6dda9f4a
KY
18909 .init_hook = alc663_g50v_inithook,
18910 },
f1d4e28b 18911 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18912 .mixers = { alc663_m51va_mixer },
18913 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18914 .init_verbs = { alc662_init_verbs,
18915 alc663_21jd_amic_init_verbs },
18916 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18917 .hp_nid = 0x03,
18918 .dac_nids = alc662_dac_nids,
18919 .dig_out_nid = ALC662_DIGOUT_NID,
18920 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18921 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18922 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18923 .setup = alc663_mode1_setup,
f1d4e28b
KY
18924 .init_hook = alc663_mode1_inithook,
18925 },
18926 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18927 .mixers = { alc662_1bjd_mixer },
18928 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18929 .init_verbs = { alc662_init_verbs,
18930 alc662_1bjd_amic_init_verbs },
18931 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18932 .dac_nids = alc662_dac_nids,
18933 .dig_out_nid = ALC662_DIGOUT_NID,
18934 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18935 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18936 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18937 .setup = alc662_mode2_setup,
f1d4e28b
KY
18938 .init_hook = alc662_mode2_inithook,
18939 },
18940 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18941 .mixers = { alc663_two_hp_m1_mixer },
18942 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18943 .init_verbs = { alc662_init_verbs,
18944 alc663_two_hp_amic_m1_init_verbs },
18945 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18946 .hp_nid = 0x03,
18947 .dac_nids = alc662_dac_nids,
18948 .dig_out_nid = ALC662_DIGOUT_NID,
18949 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18950 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18951 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18952 .setup = alc663_mode3_setup,
f1d4e28b
KY
18953 .init_hook = alc663_mode3_inithook,
18954 },
18955 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18956 .mixers = { alc663_asus_21jd_clfe_mixer },
18957 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18958 .init_verbs = { alc662_init_verbs,
18959 alc663_21jd_amic_init_verbs},
18960 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18961 .hp_nid = 0x03,
18962 .dac_nids = alc662_dac_nids,
18963 .dig_out_nid = ALC662_DIGOUT_NID,
18964 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18965 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18966 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18967 .setup = alc663_mode4_setup,
f1d4e28b
KY
18968 .init_hook = alc663_mode4_inithook,
18969 },
18970 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18971 .mixers = { alc663_asus_15jd_clfe_mixer },
18972 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18973 .init_verbs = { alc662_init_verbs,
18974 alc663_15jd_amic_init_verbs },
18975 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18976 .hp_nid = 0x03,
18977 .dac_nids = alc662_dac_nids,
18978 .dig_out_nid = ALC662_DIGOUT_NID,
18979 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18980 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18981 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18982 .setup = alc663_mode5_setup,
f1d4e28b
KY
18983 .init_hook = alc663_mode5_inithook,
18984 },
18985 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18986 .mixers = { alc663_two_hp_m2_mixer },
18987 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18988 .init_verbs = { alc662_init_verbs,
18989 alc663_two_hp_amic_m2_init_verbs },
18990 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18991 .hp_nid = 0x03,
18992 .dac_nids = alc662_dac_nids,
18993 .dig_out_nid = ALC662_DIGOUT_NID,
18994 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18995 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18996 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18997 .setup = alc663_mode6_setup,
f1d4e28b
KY
18998 .init_hook = alc663_mode6_inithook,
18999 },
ebb83eeb
KY
19000 [ALC663_ASUS_MODE7] = {
19001 .mixers = { alc663_mode7_mixer },
19002 .cap_mixer = alc662_auto_capture_mixer,
19003 .init_verbs = { alc662_init_verbs,
19004 alc663_mode7_init_verbs },
19005 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19006 .hp_nid = 0x03,
19007 .dac_nids = alc662_dac_nids,
19008 .dig_out_nid = ALC662_DIGOUT_NID,
19009 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19010 .channel_mode = alc662_3ST_2ch_modes,
19011 .unsol_event = alc663_mode7_unsol_event,
19012 .setup = alc663_mode7_setup,
19013 .init_hook = alc663_mode7_inithook,
19014 },
19015 [ALC663_ASUS_MODE8] = {
19016 .mixers = { alc663_mode8_mixer },
19017 .cap_mixer = alc662_auto_capture_mixer,
19018 .init_verbs = { alc662_init_verbs,
19019 alc663_mode8_init_verbs },
19020 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19021 .hp_nid = 0x03,
19022 .dac_nids = alc662_dac_nids,
19023 .dig_out_nid = ALC662_DIGOUT_NID,
19024 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19025 .channel_mode = alc662_3ST_2ch_modes,
19026 .unsol_event = alc663_mode8_unsol_event,
19027 .setup = alc663_mode8_setup,
19028 .init_hook = alc663_mode8_inithook,
19029 },
622e84cd
KY
19030 [ALC272_DELL] = {
19031 .mixers = { alc663_m51va_mixer },
19032 .cap_mixer = alc272_auto_capture_mixer,
19033 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
19034 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19035 .dac_nids = alc662_dac_nids,
19036 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19037 .adc_nids = alc272_adc_nids,
19038 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19039 .capsrc_nids = alc272_capsrc_nids,
19040 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19041 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19042 .setup = alc663_m51va_setup,
622e84cd
KY
19043 .init_hook = alc663_m51va_inithook,
19044 },
19045 [ALC272_DELL_ZM1] = {
19046 .mixers = { alc663_m51va_mixer },
19047 .cap_mixer = alc662_auto_capture_mixer,
19048 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19049 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19050 .dac_nids = alc662_dac_nids,
19051 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19052 .adc_nids = alc662_adc_nids,
b59bdf3b 19053 .num_adc_nids = 1,
622e84cd
KY
19054 .capsrc_nids = alc662_capsrc_nids,
19055 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19056 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19057 .setup = alc663_m51va_setup,
622e84cd
KY
19058 .init_hook = alc663_m51va_inithook,
19059 },
9541ba1d
CP
19060 [ALC272_SAMSUNG_NC10] = {
19061 .mixers = { alc272_nc10_mixer },
19062 .init_verbs = { alc662_init_verbs,
19063 alc663_21jd_amic_init_verbs },
19064 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19065 .dac_nids = alc272_dac_nids,
19066 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19067 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 19068 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 19069 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19070 .setup = alc663_mode4_setup,
9541ba1d
CP
19071 .init_hook = alc663_mode4_inithook,
19072 },
bc9f98a9
KY
19073};
19074
19075
19076/*
19077 * BIOS auto configuration
19078 */
19079
7085ec12
TI
19080/* convert from MIX nid to DAC */
19081static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19082{
19083 if (nid == 0x0f)
19084 return 0x02;
19085 else if (nid >= 0x0c && nid <= 0x0e)
19086 return nid - 0x0c + 0x02;
cc1c452e
DH
19087 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19088 return 0x25;
7085ec12
TI
19089 else
19090 return 0;
19091}
19092
19093/* get MIX nid connected to the given pin targeted to DAC */
19094static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19095 hda_nid_t dac)
19096{
cc1c452e 19097 hda_nid_t mix[5];
7085ec12
TI
19098 int i, num;
19099
19100 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19101 for (i = 0; i < num; i++) {
19102 if (alc662_mix_to_dac(mix[i]) == dac)
19103 return mix[i];
19104 }
19105 return 0;
19106}
19107
19108/* look for an empty DAC slot */
19109static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19110{
19111 struct alc_spec *spec = codec->spec;
19112 hda_nid_t srcs[5];
19113 int i, j, num;
19114
19115 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19116 if (num < 0)
19117 return 0;
19118 for (i = 0; i < num; i++) {
19119 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19120 if (!nid)
19121 continue;
19122 for (j = 0; j < spec->multiout.num_dacs; j++)
19123 if (spec->multiout.dac_nids[j] == nid)
19124 break;
19125 if (j >= spec->multiout.num_dacs)
19126 return nid;
19127 }
19128 return 0;
19129}
19130
19131/* fill in the dac_nids table from the parsed pin configuration */
19132static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19133 const struct auto_pin_cfg *cfg)
19134{
19135 struct alc_spec *spec = codec->spec;
19136 int i;
19137 hda_nid_t dac;
19138
19139 spec->multiout.dac_nids = spec->private_dac_nids;
19140 for (i = 0; i < cfg->line_outs; i++) {
19141 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19142 if (!dac)
19143 continue;
19144 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19145 }
19146 return 0;
19147}
19148
bcb2f0f5
TI
19149static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19150 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19151{
bcb2f0f5 19152 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
19153 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19154}
19155
bcb2f0f5
TI
19156static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19157 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19158{
bcb2f0f5 19159 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19160 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19161}
19162
bcb2f0f5
TI
19163#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19164 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19165#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19166 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19167#define alc662_add_stereo_vol(spec, pfx, nid) \
19168 alc662_add_vol_ctl(spec, pfx, nid, 3)
19169#define alc662_add_stereo_sw(spec, pfx, nid) \
19170 alc662_add_sw_ctl(spec, pfx, nid, 3)
19171
bc9f98a9 19172/* add playback controls from the parsed DAC table */
7085ec12 19173static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19174 const struct auto_pin_cfg *cfg)
19175{
7085ec12 19176 struct alc_spec *spec = codec->spec;
ea734963 19177 static const char * const chname[4] = {
bc9f98a9
KY
19178 "Front", "Surround", NULL /*CLFE*/, "Side"
19179 };
bcb2f0f5 19180 const char *pfx = alc_get_line_out_pfx(cfg, true);
7085ec12 19181 hda_nid_t nid, mix;
bc9f98a9
KY
19182 int i, err;
19183
19184 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19185 nid = spec->multiout.dac_nids[i];
19186 if (!nid)
19187 continue;
19188 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19189 if (!mix)
bc9f98a9 19190 continue;
bcb2f0f5 19191 if (!pfx && i == 2) {
bc9f98a9 19192 /* Center/LFE */
7085ec12 19193 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19194 if (err < 0)
19195 return err;
7085ec12 19196 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19197 if (err < 0)
19198 return err;
7085ec12 19199 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19200 if (err < 0)
19201 return err;
7085ec12 19202 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19203 if (err < 0)
19204 return err;
19205 } else {
bcb2f0f5
TI
19206 const char *name = pfx;
19207 if (!name)
19208 name = chname[i];
19209 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
bc9f98a9
KY
19210 if (err < 0)
19211 return err;
bcb2f0f5 19212 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
bc9f98a9
KY
19213 if (err < 0)
19214 return err;
19215 }
19216 }
19217 return 0;
19218}
19219
19220/* add playback controls for speaker and HP outputs */
7085ec12
TI
19221/* return DAC nid if any new DAC is assigned */
19222static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19223 const char *pfx)
19224{
7085ec12
TI
19225 struct alc_spec *spec = codec->spec;
19226 hda_nid_t nid, mix;
bc9f98a9 19227 int err;
bc9f98a9
KY
19228
19229 if (!pin)
19230 return 0;
7085ec12
TI
19231 nid = alc662_look_for_dac(codec, pin);
19232 if (!nid) {
7085ec12
TI
19233 /* the corresponding DAC is already occupied */
19234 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19235 return 0; /* no way */
19236 /* create a switch only */
0afe5f89 19237 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19238 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19239 }
19240
7085ec12
TI
19241 mix = alc662_dac_to_mix(codec, pin, nid);
19242 if (!mix)
19243 return 0;
19244 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19245 if (err < 0)
19246 return err;
19247 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19248 if (err < 0)
19249 return err;
19250 return nid;
bc9f98a9
KY
19251}
19252
19253/* create playback/capture controls for input pins */
05f5f477 19254#define alc662_auto_create_input_ctls \
4b7348a1 19255 alc882_auto_create_input_ctls
bc9f98a9
KY
19256
19257static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19258 hda_nid_t nid, int pin_type,
7085ec12 19259 hda_nid_t dac)
bc9f98a9 19260{
7085ec12 19261 int i, num;
ce503f38 19262 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19263
f6c7e546 19264 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19265 /* need the manual connection? */
7085ec12
TI
19266 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19267 if (num <= 1)
19268 return;
19269 for (i = 0; i < num; i++) {
19270 if (alc662_mix_to_dac(srcs[i]) != dac)
19271 continue;
19272 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19273 return;
bc9f98a9
KY
19274 }
19275}
19276
19277static void alc662_auto_init_multi_out(struct hda_codec *codec)
19278{
19279 struct alc_spec *spec = codec->spec;
7085ec12 19280 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19281 int i;
19282
19283 for (i = 0; i <= HDA_SIDE; i++) {
19284 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19285 if (nid)
baba8ee9 19286 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19287 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19288 }
19289}
19290
19291static void alc662_auto_init_hp_out(struct hda_codec *codec)
19292{
19293 struct alc_spec *spec = codec->spec;
19294 hda_nid_t pin;
19295
19296 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19297 if (pin)
19298 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19299 spec->multiout.hp_nid);
f6c7e546
TI
19300 pin = spec->autocfg.speaker_pins[0];
19301 if (pin)
7085ec12
TI
19302 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19303 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19304}
19305
bc9f98a9
KY
19306#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19307
19308static void alc662_auto_init_analog_input(struct hda_codec *codec)
19309{
19310 struct alc_spec *spec = codec->spec;
66ceeb6b 19311 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19312 int i;
19313
66ceeb6b
TI
19314 for (i = 0; i < cfg->num_inputs; i++) {
19315 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19316 if (alc_is_input_pin(codec, nid)) {
30ea098f 19317 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19318 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19319 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19320 snd_hda_codec_write(codec, nid, 0,
19321 AC_VERB_SET_AMP_GAIN_MUTE,
19322 AMP_OUT_MUTE);
19323 }
19324 }
19325}
19326
f511b01c
TI
19327#define alc662_auto_init_input_src alc882_auto_init_input_src
19328
bc9f98a9
KY
19329static int alc662_parse_auto_config(struct hda_codec *codec)
19330{
19331 struct alc_spec *spec = codec->spec;
19332 int err;
19333 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19334
19335 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19336 alc662_ignore);
19337 if (err < 0)
19338 return err;
19339 if (!spec->autocfg.line_outs)
19340 return 0; /* can't find valid BIOS pin config */
19341
7085ec12 19342 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19343 if (err < 0)
19344 return err;
7085ec12 19345 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19346 if (err < 0)
19347 return err;
7085ec12 19348 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19349 spec->autocfg.speaker_pins[0],
19350 "Speaker");
19351 if (err < 0)
19352 return err;
7085ec12
TI
19353 if (err)
19354 spec->multiout.extra_out_nid[0] = err;
19355 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19356 "Headphone");
19357 if (err < 0)
19358 return err;
7085ec12
TI
19359 if (err)
19360 spec->multiout.hp_nid = err;
05f5f477 19361 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19362 if (err < 0)
bc9f98a9
KY
19363 return err;
19364
19365 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19366
757899ac 19367 alc_auto_parse_digital(codec);
bc9f98a9 19368
603c4019 19369 if (spec->kctls.list)
d88897ea 19370 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19371
19372 spec->num_mux_defs = 1;
61b9b9b1 19373 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19374
cec27c89
KY
19375 add_verb(spec, alc662_init_verbs);
19376 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19377 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19378 add_verb(spec, alc663_init_verbs);
19379
19380 if (codec->vendor_id == 0x10ec0272)
19381 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19382
19383 err = alc_auto_add_mic_boost(codec);
19384 if (err < 0)
19385 return err;
19386
6227cdce
KY
19387 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19388 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19389 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19390 else
19391 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19392
8c87286f 19393 return 1;
bc9f98a9
KY
19394}
19395
19396/* additional initialization for auto-configuration model */
19397static void alc662_auto_init(struct hda_codec *codec)
19398{
f6c7e546 19399 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19400 alc662_auto_init_multi_out(codec);
19401 alc662_auto_init_hp_out(codec);
19402 alc662_auto_init_analog_input(codec);
f511b01c 19403 alc662_auto_init_input_src(codec);
757899ac 19404 alc_auto_init_digital(codec);
f6c7e546 19405 if (spec->unsol_event)
7fb0d78f 19406 alc_inithook(codec);
bc9f98a9
KY
19407}
19408
6be7948f 19409static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19410 const struct alc_fixup *fix, int action)
6fc398cb 19411{
b5bfbc67 19412 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19413 return;
6be7948f
TB
19414 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19415 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19416 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19417 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19418 (0 << AC_AMPCAP_MUTE_SHIFT)))
19419 printk(KERN_WARNING
19420 "hda_codec: failed to override amp caps for NID 0x2\n");
19421}
19422
6cb3b707 19423enum {
2df03514 19424 ALC662_FIXUP_ASPIRE,
6cb3b707 19425 ALC662_FIXUP_IDEAPAD,
6be7948f 19426 ALC272_FIXUP_MARIO,
d2ebd479 19427 ALC662_FIXUP_CZC_P10T,
6cb3b707
DH
19428};
19429
19430static const struct alc_fixup alc662_fixups[] = {
2df03514 19431 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19432 .type = ALC_FIXUP_PINS,
19433 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19434 { 0x15, 0x99130112 }, /* subwoofer */
19435 { }
19436 }
19437 },
6cb3b707 19438 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19439 .type = ALC_FIXUP_PINS,
19440 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19441 { 0x17, 0x99130112 }, /* subwoofer */
19442 { }
19443 }
19444 },
6be7948f 19445 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19446 .type = ALC_FIXUP_FUNC,
19447 .v.func = alc272_fixup_mario,
d2ebd479
AA
19448 },
19449 [ALC662_FIXUP_CZC_P10T] = {
19450 .type = ALC_FIXUP_VERBS,
19451 .v.verbs = (const struct hda_verb[]) {
19452 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19453 {}
19454 }
19455 },
6cb3b707
DH
19456};
19457
19458static struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19459 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
2df03514 19460 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19461 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19462 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19463 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19464 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19465 {}
19466};
19467
6be7948f
TB
19468static const struct alc_model_fixup alc662_fixup_models[] = {
19469 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19470 {}
19471};
6cb3b707
DH
19472
19473
bc9f98a9
KY
19474static int patch_alc662(struct hda_codec *codec)
19475{
19476 struct alc_spec *spec;
19477 int err, board_config;
693194f3 19478 int coef;
bc9f98a9
KY
19479
19480 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19481 if (!spec)
19482 return -ENOMEM;
19483
19484 codec->spec = spec;
19485
da00c244
KY
19486 alc_auto_parse_customize_define(codec);
19487
2c3bf9ab
TI
19488 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19489
693194f3
KY
19490 coef = alc_read_coef_idx(codec, 0);
19491 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19492 alc_codec_rename(codec, "ALC661");
693194f3
KY
19493 else if (coef & (1 << 14) &&
19494 codec->bus->pci->subsystem_vendor == 0x1025 &&
19495 spec->cdefine.platform_type == 1)
c027ddcd 19496 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19497 else if (coef == 0x4011)
19498 alc_codec_rename(codec, "ALC656");
274693f3 19499
bc9f98a9
KY
19500 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19501 alc662_models,
19502 alc662_cfg_tbl);
19503 if (board_config < 0) {
9a11f1aa
TI
19504 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19505 codec->chip_name);
bc9f98a9
KY
19506 board_config = ALC662_AUTO;
19507 }
19508
19509 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19510 alc_pick_fixup(codec, alc662_fixup_models,
19511 alc662_fixup_tbl, alc662_fixups);
19512 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19513 /* automatic parse from the BIOS config */
19514 err = alc662_parse_auto_config(codec);
19515 if (err < 0) {
19516 alc_free(codec);
19517 return err;
8c87286f 19518 } else if (!err) {
bc9f98a9
KY
19519 printk(KERN_INFO
19520 "hda_codec: Cannot set up configuration "
19521 "from BIOS. Using base mode...\n");
19522 board_config = ALC662_3ST_2ch_DIG;
19523 }
19524 }
19525
dc1eae25 19526 if (has_cdefine_beep(codec)) {
8af2591d
TI
19527 err = snd_hda_attach_beep_device(codec, 0x1);
19528 if (err < 0) {
19529 alc_free(codec);
19530 return err;
19531 }
680cd536
KK
19532 }
19533
bc9f98a9 19534 if (board_config != ALC662_AUTO)
e9c364c0 19535 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19536
bc9f98a9
KY
19537 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19538 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19539
bc9f98a9
KY
19540 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19541 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19542
dd704698
TI
19543 if (!spec->adc_nids) {
19544 spec->adc_nids = alc662_adc_nids;
19545 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19546 }
19547 if (!spec->capsrc_nids)
19548 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19549
f9e336f6 19550 if (!spec->cap_mixer)
b59bdf3b 19551 set_capture_mixer(codec);
cec27c89 19552
dc1eae25 19553 if (has_cdefine_beep(codec)) {
da00c244
KY
19554 switch (codec->vendor_id) {
19555 case 0x10ec0662:
19556 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19557 break;
19558 case 0x10ec0272:
19559 case 0x10ec0663:
19560 case 0x10ec0665:
19561 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19562 break;
19563 case 0x10ec0273:
19564 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19565 break;
19566 }
cec27c89 19567 }
2134ea4f
TI
19568 spec->vmaster_nid = 0x02;
19569
b5bfbc67
TI
19570 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19571
bc9f98a9 19572 codec->patch_ops = alc_patch_ops;
b5bfbc67 19573 if (board_config == ALC662_AUTO)
bc9f98a9 19574 spec->init_hook = alc662_auto_init;
6cb3b707 19575
bf1b0225
KY
19576 alc_init_jacks(codec);
19577
cb53c626
TI
19578#ifdef CONFIG_SND_HDA_POWER_SAVE
19579 if (!spec->loopback.amplist)
19580 spec->loopback.amplist = alc662_loopbacks;
19581#endif
bc9f98a9
KY
19582
19583 return 0;
19584}
19585
274693f3
KY
19586static int patch_alc888(struct hda_codec *codec)
19587{
19588 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19589 kfree(codec->chip_name);
01e0f137
KY
19590 if (codec->vendor_id == 0x10ec0887)
19591 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19592 else
19593 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19594 if (!codec->chip_name) {
19595 alc_free(codec);
274693f3 19596 return -ENOMEM;
ac2c92e0
TI
19597 }
19598 return patch_alc662(codec);
274693f3 19599 }
ac2c92e0 19600 return patch_alc882(codec);
274693f3
KY
19601}
19602
d1eb57f4
KY
19603/*
19604 * ALC680 support
19605 */
c69aefab 19606#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19607#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19608#define alc680_modes alc260_modes
19609
19610static hda_nid_t alc680_dac_nids[3] = {
19611 /* Lout1, Lout2, hp */
19612 0x02, 0x03, 0x04
19613};
19614
19615static hda_nid_t alc680_adc_nids[3] = {
19616 /* ADC0-2 */
19617 /* DMIC, MIC, Line-in*/
19618 0x07, 0x08, 0x09
19619};
19620
c69aefab
KY
19621/*
19622 * Analog capture ADC cgange
19623 */
66ceeb6b
TI
19624static void alc680_rec_autoswitch(struct hda_codec *codec)
19625{
19626 struct alc_spec *spec = codec->spec;
19627 struct auto_pin_cfg *cfg = &spec->autocfg;
19628 int pin_found = 0;
19629 int type_found = AUTO_PIN_LAST;
19630 hda_nid_t nid;
19631 int i;
19632
19633 for (i = 0; i < cfg->num_inputs; i++) {
19634 nid = cfg->inputs[i].pin;
19635 if (!(snd_hda_query_pin_caps(codec, nid) &
19636 AC_PINCAP_PRES_DETECT))
19637 continue;
19638 if (snd_hda_jack_detect(codec, nid)) {
19639 if (cfg->inputs[i].type < type_found) {
19640 type_found = cfg->inputs[i].type;
19641 pin_found = nid;
19642 }
19643 }
19644 }
19645
19646 nid = 0x07;
19647 if (pin_found)
19648 snd_hda_get_connections(codec, pin_found, &nid, 1);
19649
19650 if (nid != spec->cur_adc)
19651 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19652 spec->cur_adc = nid;
19653 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19654 spec->cur_adc_format);
19655}
19656
c69aefab
KY
19657static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19658 struct hda_codec *codec,
19659 unsigned int stream_tag,
19660 unsigned int format,
19661 struct snd_pcm_substream *substream)
19662{
19663 struct alc_spec *spec = codec->spec;
c69aefab 19664
66ceeb6b 19665 spec->cur_adc = 0x07;
c69aefab
KY
19666 spec->cur_adc_stream_tag = stream_tag;
19667 spec->cur_adc_format = format;
19668
66ceeb6b 19669 alc680_rec_autoswitch(codec);
c69aefab
KY
19670 return 0;
19671}
19672
19673static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19674 struct hda_codec *codec,
19675 struct snd_pcm_substream *substream)
19676{
19677 snd_hda_codec_cleanup_stream(codec, 0x07);
19678 snd_hda_codec_cleanup_stream(codec, 0x08);
19679 snd_hda_codec_cleanup_stream(codec, 0x09);
19680 return 0;
19681}
19682
19683static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19684 .substreams = 1, /* can be overridden */
19685 .channels_min = 2,
19686 .channels_max = 2,
19687 /* NID is set in alc_build_pcms */
19688 .ops = {
19689 .prepare = alc680_capture_pcm_prepare,
19690 .cleanup = alc680_capture_pcm_cleanup
19691 },
19692};
19693
d1eb57f4
KY
19694static struct snd_kcontrol_new alc680_base_mixer[] = {
19695 /* output mixer control */
19696 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19697 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19698 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19699 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19700 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19701 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19702 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19703 { }
19704};
19705
c69aefab
KY
19706static struct hda_bind_ctls alc680_bind_cap_vol = {
19707 .ops = &snd_hda_bind_vol,
19708 .values = {
19709 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19710 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19711 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19712 0
19713 },
19714};
19715
19716static struct hda_bind_ctls alc680_bind_cap_switch = {
19717 .ops = &snd_hda_bind_sw,
19718 .values = {
19719 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19720 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19721 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19722 0
19723 },
19724};
19725
19726static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19727 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19728 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19729 { } /* end */
19730};
19731
19732/*
19733 * generic initialization of ADC, input mixers and output mixers
19734 */
19735static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19736 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19737 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19738 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19739
c69aefab
KY
19740 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19741 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19743 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19744 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19745 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19746
19747 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19749 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19750 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19751 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19752
19753 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19754 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19755 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19756
d1eb57f4
KY
19757 { }
19758};
19759
c69aefab
KY
19760/* toggle speaker-output according to the hp-jack state */
19761static void alc680_base_setup(struct hda_codec *codec)
19762{
19763 struct alc_spec *spec = codec->spec;
19764
19765 spec->autocfg.hp_pins[0] = 0x16;
19766 spec->autocfg.speaker_pins[0] = 0x14;
19767 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19768 spec->autocfg.num_inputs = 2;
19769 spec->autocfg.inputs[0].pin = 0x18;
19770 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19771 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19772 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19773}
19774
19775static void alc680_unsol_event(struct hda_codec *codec,
19776 unsigned int res)
19777{
19778 if ((res >> 26) == ALC880_HP_EVENT)
19779 alc_automute_amp(codec);
19780 if ((res >> 26) == ALC880_MIC_EVENT)
19781 alc680_rec_autoswitch(codec);
19782}
19783
19784static void alc680_inithook(struct hda_codec *codec)
19785{
19786 alc_automute_amp(codec);
19787 alc680_rec_autoswitch(codec);
19788}
19789
d1eb57f4
KY
19790/* create input playback/capture controls for the given pin */
19791static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19792 const char *ctlname, int idx)
19793{
19794 hda_nid_t dac;
19795 int err;
19796
19797 switch (nid) {
19798 case 0x14:
19799 dac = 0x02;
19800 break;
19801 case 0x15:
19802 dac = 0x03;
19803 break;
19804 case 0x16:
19805 dac = 0x04;
19806 break;
19807 default:
19808 return 0;
19809 }
19810 if (spec->multiout.dac_nids[0] != dac &&
19811 spec->multiout.dac_nids[1] != dac) {
19812 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19813 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19814 HDA_OUTPUT));
19815 if (err < 0)
19816 return err;
19817
19818 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19819 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19820
19821 if (err < 0)
19822 return err;
19823 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19824 }
19825
19826 return 0;
19827}
19828
19829/* add playback controls from the parsed DAC table */
19830static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19831 const struct auto_pin_cfg *cfg)
19832{
19833 hda_nid_t nid;
19834 int err;
19835
19836 spec->multiout.dac_nids = spec->private_dac_nids;
19837
19838 nid = cfg->line_out_pins[0];
19839 if (nid) {
19840 const char *name;
19841 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19842 name = "Speaker";
19843 else
19844 name = "Front";
19845 err = alc680_new_analog_output(spec, nid, name, 0);
19846 if (err < 0)
19847 return err;
19848 }
19849
19850 nid = cfg->speaker_pins[0];
19851 if (nid) {
19852 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19853 if (err < 0)
19854 return err;
19855 }
19856 nid = cfg->hp_pins[0];
19857 if (nid) {
19858 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19859 if (err < 0)
19860 return err;
19861 }
19862
19863 return 0;
19864}
19865
19866static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19867 hda_nid_t nid, int pin_type)
19868{
19869 alc_set_pin_output(codec, nid, pin_type);
19870}
19871
19872static void alc680_auto_init_multi_out(struct hda_codec *codec)
19873{
19874 struct alc_spec *spec = codec->spec;
19875 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19876 if (nid) {
19877 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19878 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19879 }
19880}
19881
19882static void alc680_auto_init_hp_out(struct hda_codec *codec)
19883{
19884 struct alc_spec *spec = codec->spec;
19885 hda_nid_t pin;
19886
19887 pin = spec->autocfg.hp_pins[0];
19888 if (pin)
19889 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19890 pin = spec->autocfg.speaker_pins[0];
19891 if (pin)
19892 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19893}
19894
19895/* pcm configuration: identical with ALC880 */
19896#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19897#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19898#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19899#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19900#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19901
19902/*
19903 * BIOS auto configuration
19904 */
19905static int alc680_parse_auto_config(struct hda_codec *codec)
19906{
19907 struct alc_spec *spec = codec->spec;
19908 int err;
19909 static hda_nid_t alc680_ignore[] = { 0 };
19910
19911 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19912 alc680_ignore);
19913 if (err < 0)
19914 return err;
c69aefab 19915
d1eb57f4
KY
19916 if (!spec->autocfg.line_outs) {
19917 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19918 spec->multiout.max_channels = 2;
19919 spec->no_analog = 1;
19920 goto dig_only;
19921 }
19922 return 0; /* can't find valid BIOS pin config */
19923 }
19924 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19925 if (err < 0)
19926 return err;
19927
19928 spec->multiout.max_channels = 2;
19929
19930 dig_only:
19931 /* digital only support output */
757899ac 19932 alc_auto_parse_digital(codec);
d1eb57f4
KY
19933 if (spec->kctls.list)
19934 add_mixer(spec, spec->kctls.list);
19935
19936 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19937
19938 err = alc_auto_add_mic_boost(codec);
19939 if (err < 0)
19940 return err;
19941
19942 return 1;
19943}
19944
19945#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19946
19947/* init callback for auto-configuration model -- overriding the default init */
19948static void alc680_auto_init(struct hda_codec *codec)
19949{
19950 struct alc_spec *spec = codec->spec;
19951 alc680_auto_init_multi_out(codec);
19952 alc680_auto_init_hp_out(codec);
19953 alc680_auto_init_analog_input(codec);
757899ac 19954 alc_auto_init_digital(codec);
d1eb57f4
KY
19955 if (spec->unsol_event)
19956 alc_inithook(codec);
19957}
19958
19959/*
19960 * configuration and preset
19961 */
ea734963 19962static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19963 [ALC680_BASE] = "base",
19964 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19965};
19966
19967static struct snd_pci_quirk alc680_cfg_tbl[] = {
19968 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19969 {}
19970};
19971
19972static struct alc_config_preset alc680_presets[] = {
19973 [ALC680_BASE] = {
19974 .mixers = { alc680_base_mixer },
c69aefab 19975 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19976 .init_verbs = { alc680_init_verbs },
19977 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19978 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19979 .dig_out_nid = ALC680_DIGOUT_NID,
19980 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19981 .channel_mode = alc680_modes,
c69aefab
KY
19982 .unsol_event = alc680_unsol_event,
19983 .setup = alc680_base_setup,
19984 .init_hook = alc680_inithook,
19985
d1eb57f4
KY
19986 },
19987};
19988
19989static int patch_alc680(struct hda_codec *codec)
19990{
19991 struct alc_spec *spec;
19992 int board_config;
19993 int err;
19994
19995 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19996 if (spec == NULL)
19997 return -ENOMEM;
19998
19999 codec->spec = spec;
20000
20001 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20002 alc680_models,
20003 alc680_cfg_tbl);
20004
20005 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20006 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20007 codec->chip_name);
20008 board_config = ALC680_AUTO;
20009 }
20010
20011 if (board_config == ALC680_AUTO) {
20012 /* automatic parse from the BIOS config */
20013 err = alc680_parse_auto_config(codec);
20014 if (err < 0) {
20015 alc_free(codec);
20016 return err;
20017 } else if (!err) {
20018 printk(KERN_INFO
20019 "hda_codec: Cannot set up configuration "
20020 "from BIOS. Using base mode...\n");
20021 board_config = ALC680_BASE;
20022 }
20023 }
20024
20025 if (board_config != ALC680_AUTO)
20026 setup_preset(codec, &alc680_presets[board_config]);
20027
20028 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 20029 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 20030 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 20031 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
20032
20033 if (!spec->adc_nids) {
20034 spec->adc_nids = alc680_adc_nids;
20035 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20036 }
20037
20038 if (!spec->cap_mixer)
20039 set_capture_mixer(codec);
20040
20041 spec->vmaster_nid = 0x02;
20042
20043 codec->patch_ops = alc_patch_ops;
20044 if (board_config == ALC680_AUTO)
20045 spec->init_hook = alc680_auto_init;
20046
20047 return 0;
20048}
20049
1da177e4
LT
20050/*
20051 * patch entries
20052 */
1289e9e8 20053static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 20054 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20055 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20056 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20057 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20058 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20059 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20060 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20061 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20062 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20063 .patch = patch_alc861 },
f32610ed
JS
20064 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20065 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20066 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20067 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20068 .patch = patch_alc882 },
bc9f98a9
KY
20069 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20070 .patch = patch_alc662 },
6dda9f4a 20071 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20072 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20073 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20074 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20075 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20076 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20077 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20078 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20079 .patch = patch_alc882 },
cb308f97 20080 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20081 .patch = patch_alc882 },
df694daa 20082 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20083 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20084 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20085 .patch = patch_alc882 },
274693f3 20086 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20087 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20088 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20089 {} /* terminator */
20090};
1289e9e8
TI
20091
20092MODULE_ALIAS("snd-hda-codec-id:10ec*");
20093
20094MODULE_LICENSE("GPL");
20095MODULE_DESCRIPTION("Realtek HD-audio codec");
20096
20097static struct hda_codec_preset_list realtek_list = {
20098 .preset = snd_hda_preset_realtek,
20099 .owner = THIS_MODULE,
20100};
20101
20102static int __init patch_realtek_init(void)
20103{
20104 return snd_hda_add_codec_preset(&realtek_list);
20105}
20106
20107static void __exit patch_realtek_exit(void)
20108{
20109 snd_hda_delete_codec_preset(&realtek_list);
20110}
20111
20112module_init(patch_realtek_init)
20113module_exit(patch_realtek_exit)