]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda: Prevent writing ICH6_PCIREG_TCSEL on AMD systems
[thirdparty/kernel/stable.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 5138 const char *name = pfx;
7e59e097
DH
5139 int index = i;
5140 if (!name) {
bcb2f0f5 5141 name = chname[i];
7e59e097
DH
5142 index = 0;
5143 }
bcb2f0f5 5144 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5145 name, index,
f12ab1e0
TI
5146 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5147 HDA_OUTPUT));
5148 if (err < 0)
e9edcee0 5149 return err;
bcb2f0f5 5150 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5151 name, index,
f12ab1e0
TI
5152 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5153 HDA_INPUT));
5154 if (err < 0)
e9edcee0
TI
5155 return err;
5156 }
5157 }
e9edcee0
TI
5158 return 0;
5159}
5160
8d88bc3d
TI
5161/* add playback controls for speaker and HP outputs */
5162static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5163 const char *pfx)
e9edcee0
TI
5164{
5165 hda_nid_t nid;
5166 int err;
5167
f12ab1e0 5168 if (!pin)
e9edcee0
TI
5169 return 0;
5170
5171 if (alc880_is_fixed_pin(pin)) {
5172 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5173 /* specify the DAC as the extra output */
f12ab1e0 5174 if (!spec->multiout.hp_nid)
e9edcee0 5175 spec->multiout.hp_nid = nid;
82bc955f
TI
5176 else
5177 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5178 /* control HP volume/switch on the output mixer amp */
5179 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5180 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5181 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5182 if (err < 0)
e9edcee0 5183 return err;
0afe5f89 5184 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5185 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5186 if (err < 0)
e9edcee0
TI
5187 return err;
5188 } else if (alc880_is_multi_pin(pin)) {
5189 /* set manual connection */
e9edcee0 5190 /* we have only a switch on HP-out PIN */
0afe5f89 5191 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5192 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5193 if (err < 0)
e9edcee0
TI
5194 return err;
5195 }
5196 return 0;
5197}
5198
5199/* create input playback/capture controls for the given pin */
f12ab1e0 5200static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5201 const char *ctlname, int ctlidx,
df694daa 5202 int idx, hda_nid_t mix_nid)
e9edcee0 5203{
df694daa 5204 int err;
e9edcee0 5205
66ceeb6b 5206 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5207 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5208 if (err < 0)
e9edcee0 5209 return err;
66ceeb6b 5210 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5211 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5212 if (err < 0)
e9edcee0
TI
5213 return err;
5214 return 0;
5215}
5216
05f5f477
TI
5217static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5218{
5219 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5220 return (pincap & AC_PINCAP_IN) != 0;
5221}
5222
e9edcee0 5223/* create playback/capture controls for input pins */
05f5f477
TI
5224static int alc_auto_create_input_ctls(struct hda_codec *codec,
5225 const struct auto_pin_cfg *cfg,
5226 hda_nid_t mixer,
5227 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5228{
05f5f477 5229 struct alc_spec *spec = codec->spec;
61b9b9b1 5230 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5231 int i, err, idx, type_idx = 0;
5232 const char *prev_label = NULL;
e9edcee0 5233
66ceeb6b 5234 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5235 hda_nid_t pin;
10a20af7 5236 const char *label;
05f5f477 5237
66ceeb6b 5238 pin = cfg->inputs[i].pin;
05f5f477
TI
5239 if (!alc_is_input_pin(codec, pin))
5240 continue;
5241
5322bf27
DH
5242 label = hda_get_autocfg_input_label(codec, cfg, i);
5243 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5244 type_idx++;
5245 else
5246 type_idx = 0;
5322bf27
DH
5247 prev_label = label;
5248
05f5f477
TI
5249 if (mixer) {
5250 idx = get_connection_index(codec, mixer, pin);
5251 if (idx >= 0) {
5252 err = new_analog_input(spec, pin,
10a20af7
TI
5253 label, type_idx,
5254 idx, mixer);
05f5f477
TI
5255 if (err < 0)
5256 return err;
5257 }
5258 }
5259
5260 if (!cap1)
5261 continue;
5262 idx = get_connection_index(codec, cap1, pin);
5263 if (idx < 0 && cap2)
5264 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5265 if (idx >= 0)
5266 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5267 }
5268 return 0;
5269}
5270
05f5f477
TI
5271static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5272 const struct auto_pin_cfg *cfg)
5273{
5274 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5275}
5276
f6c7e546
TI
5277static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5278 unsigned int pin_type)
5279{
5280 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5281 pin_type);
5282 /* unmute pin */
d260cdf6
TI
5283 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5284 AMP_OUT_UNMUTE);
f6c7e546
TI
5285}
5286
df694daa
KY
5287static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5288 hda_nid_t nid, int pin_type,
e9edcee0
TI
5289 int dac_idx)
5290{
f6c7e546 5291 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5292 /* need the manual connection? */
5293 if (alc880_is_multi_pin(nid)) {
5294 struct alc_spec *spec = codec->spec;
5295 int idx = alc880_multi_pin_idx(nid);
5296 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5297 AC_VERB_SET_CONNECT_SEL,
5298 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5299 }
5300}
5301
baba8ee9
TI
5302static int get_pin_type(int line_out_type)
5303{
5304 if (line_out_type == AUTO_PIN_HP_OUT)
5305 return PIN_HP;
5306 else
5307 return PIN_OUT;
5308}
5309
e9edcee0
TI
5310static void alc880_auto_init_multi_out(struct hda_codec *codec)
5311{
5312 struct alc_spec *spec = codec->spec;
5313 int i;
ea1fb29a 5314
e9edcee0
TI
5315 for (i = 0; i < spec->autocfg.line_outs; i++) {
5316 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5317 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5318 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5319 }
5320}
5321
8d88bc3d 5322static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5323{
5324 struct alc_spec *spec = codec->spec;
5325 hda_nid_t pin;
5326
82bc955f 5327 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5328 if (pin) /* connect to front */
5329 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5330 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5331 if (pin) /* connect to front */
5332 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5333}
5334
5335static void alc880_auto_init_analog_input(struct hda_codec *codec)
5336{
5337 struct alc_spec *spec = codec->spec;
66ceeb6b 5338 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5339 int i;
5340
66ceeb6b
TI
5341 for (i = 0; i < cfg->num_inputs; i++) {
5342 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5343 if (alc_is_input_pin(codec, nid)) {
30ea098f 5344 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5345 if (nid != ALC880_PIN_CD_NID &&
5346 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5347 snd_hda_codec_write(codec, nid, 0,
5348 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5349 AMP_OUT_MUTE);
5350 }
5351 }
5352}
5353
7f311a46
TI
5354static void alc880_auto_init_input_src(struct hda_codec *codec)
5355{
5356 struct alc_spec *spec = codec->spec;
5357 int c;
5358
5359 for (c = 0; c < spec->num_adc_nids; c++) {
5360 unsigned int mux_idx;
5361 const struct hda_input_mux *imux;
5362 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5363 imux = &spec->input_mux[mux_idx];
5364 if (!imux->num_items && mux_idx > 0)
5365 imux = &spec->input_mux[0];
5366 if (imux)
5367 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5368 AC_VERB_SET_CONNECT_SEL,
5369 imux->items[0].index);
5370 }
5371}
5372
e9edcee0 5373/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5374/* return 1 if successful, 0 if the proper config is not found,
5375 * or a negative error code
5376 */
e9edcee0
TI
5377static int alc880_parse_auto_config(struct hda_codec *codec)
5378{
5379 struct alc_spec *spec = codec->spec;
757899ac 5380 int err;
df694daa 5381 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5382
f12ab1e0
TI
5383 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5384 alc880_ignore);
5385 if (err < 0)
e9edcee0 5386 return err;
f12ab1e0 5387 if (!spec->autocfg.line_outs)
e9edcee0 5388 return 0; /* can't find valid BIOS pin config */
df694daa 5389
f12ab1e0
TI
5390 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5391 if (err < 0)
5392 return err;
5393 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5394 if (err < 0)
5395 return err;
5396 err = alc880_auto_create_extra_out(spec,
5397 spec->autocfg.speaker_pins[0],
5398 "Speaker");
5399 if (err < 0)
5400 return err;
5401 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5402 "Headphone");
5403 if (err < 0)
5404 return err;
05f5f477 5405 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5406 if (err < 0)
e9edcee0
TI
5407 return err;
5408
5409 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5410
757899ac 5411 alc_auto_parse_digital(codec);
e9edcee0 5412
603c4019 5413 if (spec->kctls.list)
d88897ea 5414 add_mixer(spec, spec->kctls.list);
e9edcee0 5415
d88897ea 5416 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5417
a1e8d2da 5418 spec->num_mux_defs = 1;
61b9b9b1 5419 spec->input_mux = &spec->private_imux[0];
e9edcee0 5420
6227cdce 5421 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5422
e9edcee0
TI
5423 return 1;
5424}
5425
ae6b813a
TI
5426/* additional initialization for auto-configuration model */
5427static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5428{
f6c7e546 5429 struct alc_spec *spec = codec->spec;
e9edcee0 5430 alc880_auto_init_multi_out(codec);
8d88bc3d 5431 alc880_auto_init_extra_out(codec);
e9edcee0 5432 alc880_auto_init_analog_input(codec);
7f311a46 5433 alc880_auto_init_input_src(codec);
757899ac 5434 alc_auto_init_digital(codec);
f6c7e546 5435 if (spec->unsol_event)
7fb0d78f 5436 alc_inithook(codec);
e9edcee0
TI
5437}
5438
b59bdf3b
TI
5439/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5440 * one of two digital mic pins, e.g. on ALC272
5441 */
5442static void fixup_automic_adc(struct hda_codec *codec)
5443{
5444 struct alc_spec *spec = codec->spec;
5445 int i;
5446
5447 for (i = 0; i < spec->num_adc_nids; i++) {
5448 hda_nid_t cap = spec->capsrc_nids ?
5449 spec->capsrc_nids[i] : spec->adc_nids[i];
5450 int iidx, eidx;
5451
5452 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5453 if (iidx < 0)
5454 continue;
5455 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5456 if (eidx < 0)
5457 continue;
5458 spec->int_mic.mux_idx = iidx;
5459 spec->ext_mic.mux_idx = eidx;
5460 if (spec->capsrc_nids)
5461 spec->capsrc_nids += i;
5462 spec->adc_nids += i;
5463 spec->num_adc_nids = 1;
5464 return;
5465 }
5466 snd_printd(KERN_INFO "hda_codec: %s: "
5467 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5468 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5469 spec->auto_mic = 0; /* disable auto-mic to be sure */
5470}
5471
748cce43
TI
5472/* select or unmute the given capsrc route */
5473static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5474 int idx)
5475{
5476 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5477 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5478 HDA_AMP_MUTE, 0);
5479 } else {
5480 snd_hda_codec_write_cache(codec, cap, 0,
5481 AC_VERB_SET_CONNECT_SEL, idx);
5482 }
5483}
5484
840b64c0
TI
5485/* set the default connection to that pin */
5486static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5487{
5488 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5489 int i;
5490
eaa9b3a7
TI
5491 for (i = 0; i < spec->num_adc_nids; i++) {
5492 hda_nid_t cap = spec->capsrc_nids ?
5493 spec->capsrc_nids[i] : spec->adc_nids[i];
5494 int idx;
5495
5496 idx = get_connection_index(codec, cap, pin);
5497 if (idx < 0)
5498 continue;
748cce43 5499 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5500 return i; /* return the found index */
5501 }
5502 return -1; /* not found */
5503}
5504
5505/* choose the ADC/MUX containing the input pin and initialize the setup */
5506static void fixup_single_adc(struct hda_codec *codec)
5507{
5508 struct alc_spec *spec = codec->spec;
66ceeb6b 5509 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5510 int i;
5511
5512 /* search for the input pin; there must be only one */
66ceeb6b 5513 if (cfg->num_inputs != 1)
eaa9b3a7 5514 return;
66ceeb6b 5515 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5516 if (i >= 0) {
5517 /* use only this ADC */
5518 if (spec->capsrc_nids)
5519 spec->capsrc_nids += i;
5520 spec->adc_nids += i;
5521 spec->num_adc_nids = 1;
eaa9b3a7
TI
5522 }
5523}
5524
840b64c0
TI
5525/* initialize dual adcs */
5526static void fixup_dual_adc_switch(struct hda_codec *codec)
5527{
5528 struct alc_spec *spec = codec->spec;
5529 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5530 init_capsrc_for_pin(codec, spec->int_mic.pin);
5531}
5532
b59bdf3b 5533static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5534{
b59bdf3b 5535 struct alc_spec *spec = codec->spec;
a23b688f
TI
5536 static struct snd_kcontrol_new *caps[2][3] = {
5537 { alc_capture_mixer_nosrc1,
5538 alc_capture_mixer_nosrc2,
5539 alc_capture_mixer_nosrc3 },
5540 { alc_capture_mixer1,
5541 alc_capture_mixer2,
5542 alc_capture_mixer3 },
f9e336f6 5543 };
a23b688f 5544 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5545 int mux = 0;
840b64c0
TI
5546 int num_adcs = spec->num_adc_nids;
5547 if (spec->dual_adc_switch)
5548 fixup_dual_adc_switch(codec);
5549 else if (spec->auto_mic)
b59bdf3b 5550 fixup_automic_adc(codec);
eaa9b3a7
TI
5551 else if (spec->input_mux) {
5552 if (spec->input_mux->num_items > 1)
5553 mux = 1;
5554 else if (spec->input_mux->num_items == 1)
5555 fixup_single_adc(codec);
5556 }
840b64c0
TI
5557 if (spec->dual_adc_switch)
5558 num_adcs = 1;
5559 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5560 }
f9e336f6
TI
5561}
5562
6694635d
TI
5563/* fill adc_nids (and capsrc_nids) containing all active input pins */
5564static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5565 int num_nids)
5566{
5567 struct alc_spec *spec = codec->spec;
66ceeb6b 5568 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5569 int n;
5570 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5571
5572 for (n = 0; n < num_nids; n++) {
5573 hda_nid_t adc, cap;
5574 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5575 int nconns, i, j;
5576
5577 adc = nids[n];
5578 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5579 continue;
5580 cap = adc;
5581 nconns = snd_hda_get_connections(codec, cap, conn,
5582 ARRAY_SIZE(conn));
5583 if (nconns == 1) {
5584 cap = conn[0];
5585 nconns = snd_hda_get_connections(codec, cap, conn,
5586 ARRAY_SIZE(conn));
5587 }
5588 if (nconns <= 0)
5589 continue;
5590 if (!fallback_adc) {
5591 fallback_adc = adc;
5592 fallback_cap = cap;
5593 }
66ceeb6b
TI
5594 for (i = 0; i < cfg->num_inputs; i++) {
5595 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5596 for (j = 0; j < nconns; j++) {
5597 if (conn[j] == nid)
5598 break;
5599 }
5600 if (j >= nconns)
5601 break;
5602 }
66ceeb6b 5603 if (i >= cfg->num_inputs) {
6694635d
TI
5604 int num_adcs = spec->num_adc_nids;
5605 spec->private_adc_nids[num_adcs] = adc;
5606 spec->private_capsrc_nids[num_adcs] = cap;
5607 spec->num_adc_nids++;
5608 spec->adc_nids = spec->private_adc_nids;
5609 if (adc != cap)
5610 spec->capsrc_nids = spec->private_capsrc_nids;
5611 }
5612 }
5613 if (!spec->num_adc_nids) {
5614 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5615 " using fallback 0x%x\n",
5616 codec->chip_name, fallback_adc);
6694635d
TI
5617 spec->private_adc_nids[0] = fallback_adc;
5618 spec->adc_nids = spec->private_adc_nids;
5619 if (fallback_adc != fallback_cap) {
5620 spec->private_capsrc_nids[0] = fallback_cap;
5621 spec->capsrc_nids = spec->private_adc_nids;
5622 }
5623 }
5624}
5625
67d634c0 5626#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5627#define set_beep_amp(spec, nid, idx, dir) \
5628 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5629
5630static struct snd_pci_quirk beep_white_list[] = {
5631 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5632 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5633 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5634 {}
5635};
5636
5637static inline int has_cdefine_beep(struct hda_codec *codec)
5638{
5639 struct alc_spec *spec = codec->spec;
5640 const struct snd_pci_quirk *q;
5641 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5642 if (q)
5643 return q->value;
5644 return spec->cdefine.enable_pcbeep;
5645}
67d634c0
TI
5646#else
5647#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5648#define has_cdefine_beep(codec) 0
67d634c0 5649#endif
45bdd1c1
TI
5650
5651/*
5652 * OK, here we have finally the patch for ALC880
5653 */
5654
1da177e4
LT
5655static int patch_alc880(struct hda_codec *codec)
5656{
5657 struct alc_spec *spec;
5658 int board_config;
df694daa 5659 int err;
1da177e4 5660
e560d8d8 5661 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5662 if (spec == NULL)
5663 return -ENOMEM;
5664
5665 codec->spec = spec;
5666
f5fcc13c
TI
5667 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5668 alc880_models,
5669 alc880_cfg_tbl);
5670 if (board_config < 0) {
9a11f1aa
TI
5671 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5672 codec->chip_name);
e9edcee0 5673 board_config = ALC880_AUTO;
1da177e4 5674 }
1da177e4 5675
e9edcee0
TI
5676 if (board_config == ALC880_AUTO) {
5677 /* automatic parse from the BIOS config */
5678 err = alc880_parse_auto_config(codec);
5679 if (err < 0) {
5680 alc_free(codec);
5681 return err;
f12ab1e0 5682 } else if (!err) {
9c7f852e
TI
5683 printk(KERN_INFO
5684 "hda_codec: Cannot set up configuration "
5685 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5686 board_config = ALC880_3ST;
5687 }
1da177e4
LT
5688 }
5689
680cd536
KK
5690 err = snd_hda_attach_beep_device(codec, 0x1);
5691 if (err < 0) {
5692 alc_free(codec);
5693 return err;
5694 }
5695
df694daa 5696 if (board_config != ALC880_AUTO)
e9c364c0 5697 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5698
1da177e4
LT
5699 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5700 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5701 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5702
1da177e4
LT
5703 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5704 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5705
f12ab1e0 5706 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5707 /* check whether NID 0x07 is valid */
54d17403 5708 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5709 /* get type */
a22d543a 5710 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5711 if (wcap != AC_WID_AUD_IN) {
5712 spec->adc_nids = alc880_adc_nids_alt;
5713 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5714 } else {
5715 spec->adc_nids = alc880_adc_nids;
5716 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5717 }
5718 }
b59bdf3b 5719 set_capture_mixer(codec);
45bdd1c1 5720 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5721
2134ea4f
TI
5722 spec->vmaster_nid = 0x0c;
5723
1da177e4 5724 codec->patch_ops = alc_patch_ops;
e9edcee0 5725 if (board_config == ALC880_AUTO)
ae6b813a 5726 spec->init_hook = alc880_auto_init;
cb53c626
TI
5727#ifdef CONFIG_SND_HDA_POWER_SAVE
5728 if (!spec->loopback.amplist)
5729 spec->loopback.amplist = alc880_loopbacks;
5730#endif
1da177e4
LT
5731
5732 return 0;
5733}
5734
e9edcee0 5735
1da177e4
LT
5736/*
5737 * ALC260 support
5738 */
5739
e9edcee0
TI
5740static hda_nid_t alc260_dac_nids[1] = {
5741 /* front */
5742 0x02,
5743};
5744
5745static hda_nid_t alc260_adc_nids[1] = {
5746 /* ADC0 */
5747 0x04,
5748};
5749
df694daa 5750static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5751 /* ADC1 */
5752 0x05,
5753};
5754
d57fdac0
JW
5755/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5756 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5757 */
5758static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5759 /* ADC0, ADC1 */
5760 0x04, 0x05
5761};
5762
e9edcee0
TI
5763#define ALC260_DIGOUT_NID 0x03
5764#define ALC260_DIGIN_NID 0x06
5765
5766static struct hda_input_mux alc260_capture_source = {
5767 .num_items = 4,
5768 .items = {
5769 { "Mic", 0x0 },
5770 { "Front Mic", 0x1 },
5771 { "Line", 0x2 },
5772 { "CD", 0x4 },
5773 },
5774};
5775
17e7aec6 5776/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5777 * headphone jack and the internal CD lines since these are the only pins at
5778 * which audio can appear. For flexibility, also allow the option of
5779 * recording the mixer output on the second ADC (ADC0 doesn't have a
5780 * connection to the mixer output).
a9430dd8 5781 */
a1e8d2da
JW
5782static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5783 {
5784 .num_items = 3,
5785 .items = {
5786 { "Mic/Line", 0x0 },
5787 { "CD", 0x4 },
5788 { "Headphone", 0x2 },
5789 },
a9430dd8 5790 },
a1e8d2da
JW
5791 {
5792 .num_items = 4,
5793 .items = {
5794 { "Mic/Line", 0x0 },
5795 { "CD", 0x4 },
5796 { "Headphone", 0x2 },
5797 { "Mixer", 0x5 },
5798 },
5799 },
5800
a9430dd8
JW
5801};
5802
a1e8d2da
JW
5803/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5804 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5805 */
a1e8d2da
JW
5806static struct hda_input_mux alc260_acer_capture_sources[2] = {
5807 {
5808 .num_items = 4,
5809 .items = {
5810 { "Mic", 0x0 },
5811 { "Line", 0x2 },
5812 { "CD", 0x4 },
5813 { "Headphone", 0x5 },
5814 },
5815 },
5816 {
5817 .num_items = 5,
5818 .items = {
5819 { "Mic", 0x0 },
5820 { "Line", 0x2 },
5821 { "CD", 0x4 },
5822 { "Headphone", 0x6 },
5823 { "Mixer", 0x5 },
5824 },
0bfc90e9
JW
5825 },
5826};
cc959489
MS
5827
5828/* Maxdata Favorit 100XS */
5829static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5830 {
5831 .num_items = 2,
5832 .items = {
5833 { "Line/Mic", 0x0 },
5834 { "CD", 0x4 },
5835 },
5836 },
5837 {
5838 .num_items = 3,
5839 .items = {
5840 { "Line/Mic", 0x0 },
5841 { "CD", 0x4 },
5842 { "Mixer", 0x5 },
5843 },
5844 },
5845};
5846
1da177e4
LT
5847/*
5848 * This is just place-holder, so there's something for alc_build_pcms to look
5849 * at when it calculates the maximum number of channels. ALC260 has no mixer
5850 * element which allows changing the channel mode, so the verb list is
5851 * never used.
5852 */
d2a6d7dc 5853static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5854 { 2, NULL },
5855};
5856
df694daa
KY
5857
5858/* Mixer combinations
5859 *
5860 * basic: base_output + input + pc_beep + capture
5861 * HP: base_output + input + capture_alt
5862 * HP_3013: hp_3013 + input + capture
5863 * fujitsu: fujitsu + capture
0bfc90e9 5864 * acer: acer + capture
df694daa
KY
5865 */
5866
5867static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5868 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5869 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5870 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5871 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5872 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5873 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5874 { } /* end */
f12ab1e0 5875};
1da177e4 5876
df694daa 5877static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5878 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5879 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5880 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5881 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5882 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5883 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5884 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5885 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5886 { } /* end */
5887};
5888
bec15c3a
TI
5889/* update HP, line and mono out pins according to the master switch */
5890static void alc260_hp_master_update(struct hda_codec *codec,
5891 hda_nid_t hp, hda_nid_t line,
5892 hda_nid_t mono)
5893{
5894 struct alc_spec *spec = codec->spec;
5895 unsigned int val = spec->master_sw ? PIN_HP : 0;
5896 /* change HP and line-out pins */
30cde0aa 5897 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5898 val);
30cde0aa 5899 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5900 val);
5901 /* mono (speaker) depending on the HP jack sense */
5902 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5903 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5904 val);
5905}
5906
5907static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5908 struct snd_ctl_elem_value *ucontrol)
5909{
5910 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5911 struct alc_spec *spec = codec->spec;
5912 *ucontrol->value.integer.value = spec->master_sw;
5913 return 0;
5914}
5915
5916static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5917 struct snd_ctl_elem_value *ucontrol)
5918{
5919 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5920 struct alc_spec *spec = codec->spec;
5921 int val = !!*ucontrol->value.integer.value;
5922 hda_nid_t hp, line, mono;
5923
5924 if (val == spec->master_sw)
5925 return 0;
5926 spec->master_sw = val;
5927 hp = (kcontrol->private_value >> 16) & 0xff;
5928 line = (kcontrol->private_value >> 8) & 0xff;
5929 mono = kcontrol->private_value & 0xff;
5930 alc260_hp_master_update(codec, hp, line, mono);
5931 return 1;
5932}
5933
5934static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5935 {
5936 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5937 .name = "Master Playback Switch",
5b0cb1d8 5938 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5939 .info = snd_ctl_boolean_mono_info,
5940 .get = alc260_hp_master_sw_get,
5941 .put = alc260_hp_master_sw_put,
5942 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5943 },
5944 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5945 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5946 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5947 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5948 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5949 HDA_OUTPUT),
5950 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5951 { } /* end */
5952};
5953
5954static struct hda_verb alc260_hp_unsol_verbs[] = {
5955 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5956 {},
5957};
5958
5959static void alc260_hp_automute(struct hda_codec *codec)
5960{
5961 struct alc_spec *spec = codec->spec;
bec15c3a 5962
864f92be 5963 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5964 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5965}
5966
5967static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5968{
5969 if ((res >> 26) == ALC880_HP_EVENT)
5970 alc260_hp_automute(codec);
5971}
5972
df694daa 5973static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5974 {
5975 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5976 .name = "Master Playback Switch",
5b0cb1d8 5977 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5978 .info = snd_ctl_boolean_mono_info,
5979 .get = alc260_hp_master_sw_get,
5980 .put = alc260_hp_master_sw_put,
30cde0aa 5981 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5982 },
df694daa
KY
5983 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5984 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5985 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5986 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5987 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5989 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5990 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5991 { } /* end */
5992};
5993
3f878308
KY
5994static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5995 .ops = &snd_hda_bind_vol,
5996 .values = {
5997 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5998 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5999 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6000 0
6001 },
6002};
6003
6004static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6005 .ops = &snd_hda_bind_sw,
6006 .values = {
6007 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6008 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6009 0
6010 },
6011};
6012
6013static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6014 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6015 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6016 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6017 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6018 { } /* end */
6019};
6020
bec15c3a
TI
6021static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6022 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6023 {},
6024};
6025
6026static void alc260_hp_3013_automute(struct hda_codec *codec)
6027{
6028 struct alc_spec *spec = codec->spec;
bec15c3a 6029
864f92be 6030 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 6031 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
6032}
6033
6034static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6035 unsigned int res)
6036{
6037 if ((res >> 26) == ALC880_HP_EVENT)
6038 alc260_hp_3013_automute(codec);
6039}
6040
3f878308
KY
6041static void alc260_hp_3012_automute(struct hda_codec *codec)
6042{
864f92be 6043 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 6044
3f878308
KY
6045 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6046 bits);
6047 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6048 bits);
6049 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6050 bits);
6051}
6052
6053static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6054 unsigned int res)
6055{
6056 if ((res >> 26) == ALC880_HP_EVENT)
6057 alc260_hp_3012_automute(codec);
6058}
6059
6060/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6061 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6062 */
c8b6bf9b 6063static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6064 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6065 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6066 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6067 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6068 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6069 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6070 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6071 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6072 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6073 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6074 { } /* end */
6075};
6076
a1e8d2da
JW
6077/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6078 * versions of the ALC260 don't act on requests to enable mic bias from NID
6079 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6080 * datasheet doesn't mention this restriction. At this stage it's not clear
6081 * whether this behaviour is intentional or is a hardware bug in chip
6082 * revisions available in early 2006. Therefore for now allow the
6083 * "Headphone Jack Mode" control to span all choices, but if it turns out
6084 * that the lack of mic bias for this NID is intentional we could change the
6085 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6086 *
6087 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6088 * don't appear to make the mic bias available from the "line" jack, even
6089 * though the NID used for this jack (0x14) can supply it. The theory is
6090 * that perhaps Acer have included blocking capacitors between the ALC260
6091 * and the output jack. If this turns out to be the case for all such
6092 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6093 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6094 *
6095 * The C20x Tablet series have a mono internal speaker which is controlled
6096 * via the chip's Mono sum widget and pin complex, so include the necessary
6097 * controls for such models. On models without a "mono speaker" the control
6098 * won't do anything.
a1e8d2da 6099 */
0bfc90e9
JW
6100static struct snd_kcontrol_new alc260_acer_mixer[] = {
6101 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6102 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6103 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6104 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6105 HDA_OUTPUT),
31bffaa9 6106 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6107 HDA_INPUT),
0bfc90e9
JW
6108 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6109 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6110 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6111 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6112 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6113 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6114 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6115 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6116 { } /* end */
6117};
6118
cc959489
MS
6119/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6120 */
6121static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6122 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6123 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6124 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6125 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6126 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6127 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6128 { } /* end */
6129};
6130
bc9f98a9
KY
6131/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6132 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6133 */
6134static struct snd_kcontrol_new alc260_will_mixer[] = {
6135 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6136 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6138 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6139 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6140 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6141 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6142 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6143 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6144 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6145 { } /* end */
6146};
6147
6148/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6149 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6150 */
6151static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6152 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6153 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6155 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6156 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6157 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6158 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6159 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6160 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6161 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6162 { } /* end */
6163};
6164
df694daa
KY
6165/*
6166 * initialization verbs
6167 */
1da177e4
LT
6168static struct hda_verb alc260_init_verbs[] = {
6169 /* Line In pin widget for input */
05acb863 6170 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6171 /* CD pin widget for input */
05acb863 6172 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6173 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6174 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6175 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6176 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6177 /* LINE-2 is used for line-out in rear */
05acb863 6178 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6179 /* select line-out */
fd56f2db 6180 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6181 /* LINE-OUT pin */
05acb863 6182 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6183 /* enable HP */
05acb863 6184 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6185 /* enable Mono */
05acb863
TI
6186 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6187 /* mute capture amp left and right */
16ded525 6188 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6189 /* set connection select to line in (default select for this ADC) */
6190 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6191 /* mute capture amp left and right */
6192 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6193 /* set connection select to line in (default select for this ADC) */
6194 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6195 /* set vol=0 Line-Out mixer amp left and right */
6196 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6197 /* unmute pin widget amp left and right (no gain on this amp) */
6198 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6199 /* set vol=0 HP mixer amp left and right */
6200 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6201 /* unmute pin widget amp left and right (no gain on this amp) */
6202 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6203 /* set vol=0 Mono mixer amp left and right */
6204 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6205 /* unmute pin widget amp left and right (no gain on this amp) */
6206 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6207 /* unmute LINE-2 out pin */
6208 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6209 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6210 * Line In 2 = 0x03
6211 */
cb53c626
TI
6212 /* mute analog inputs */
6213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6214 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6215 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6216 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6217 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6218 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6219 /* mute Front out path */
6220 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6221 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6222 /* mute Headphone out path */
6223 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6224 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6225 /* mute Mono out path */
6226 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6227 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6228 { }
6229};
6230
474167d6 6231#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6232static struct hda_verb alc260_hp_init_verbs[] = {
6233 /* Headphone and output */
6234 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6235 /* mono output */
6236 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6237 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6238 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6239 /* Mic2 (front panel) pin widget for input and vref at 80% */
6240 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6241 /* Line In pin widget for input */
6242 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6243 /* Line-2 pin widget for output */
6244 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6245 /* CD pin widget for input */
6246 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6247 /* unmute amp left and right */
6248 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6249 /* set connection select to line in (default select for this ADC) */
6250 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6251 /* unmute Line-Out mixer amp left and right (volume = 0) */
6252 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6253 /* mute pin widget amp left and right (no gain on this amp) */
6254 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6255 /* unmute HP mixer amp left and right (volume = 0) */
6256 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6257 /* mute pin widget amp left and right (no gain on this amp) */
6258 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6259 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6260 * Line In 2 = 0x03
6261 */
cb53c626
TI
6262 /* mute analog inputs */
6263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6264 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6265 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6266 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6267 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6268 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6269 /* Unmute Front out path */
6270 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6271 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6272 /* Unmute Headphone out path */
6273 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6274 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6275 /* Unmute Mono out path */
6276 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6277 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6278 { }
6279};
474167d6 6280#endif
df694daa
KY
6281
6282static struct hda_verb alc260_hp_3013_init_verbs[] = {
6283 /* Line out and output */
6284 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6285 /* mono output */
6286 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6287 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6288 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6289 /* Mic2 (front panel) pin widget for input and vref at 80% */
6290 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6291 /* Line In pin widget for input */
6292 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6293 /* Headphone pin widget for output */
6294 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6295 /* CD pin widget for input */
6296 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6297 /* unmute amp left and right */
6298 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6299 /* set connection select to line in (default select for this ADC) */
6300 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6301 /* unmute Line-Out mixer amp left and right (volume = 0) */
6302 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6303 /* mute pin widget amp left and right (no gain on this amp) */
6304 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6305 /* unmute HP mixer amp left and right (volume = 0) */
6306 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6307 /* mute pin widget amp left and right (no gain on this amp) */
6308 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6309 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6310 * Line In 2 = 0x03
6311 */
cb53c626
TI
6312 /* mute analog inputs */
6313 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6314 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6315 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6316 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6317 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6318 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6319 /* Unmute Front out path */
6320 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6321 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6322 /* Unmute Headphone out path */
6323 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6324 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6325 /* Unmute Mono out path */
6326 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6327 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6328 { }
6329};
6330
a9430dd8 6331/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6332 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6333 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6334 */
6335static struct hda_verb alc260_fujitsu_init_verbs[] = {
6336 /* Disable all GPIOs */
6337 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6338 /* Internal speaker is connected to headphone pin */
6339 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6340 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6341 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6342 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6343 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6344 /* Ensure all other unused pins are disabled and muted. */
6345 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6346 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6347 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6348 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6349 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6350 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6352 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6353
6354 /* Disable digital (SPDIF) pins */
6355 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6356 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6357
ea1fb29a 6358 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6359 * when acting as an output.
6360 */
6361 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6362
f7ace40d 6363 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6364 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6365 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6366 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6367 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6368 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6369 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6370 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6371 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6372 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6373
f7ace40d
JW
6374 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6375 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6376 /* Unmute Line1 pin widget output buffer since it starts as an output.
6377 * If the pin mode is changed by the user the pin mode control will
6378 * take care of enabling the pin's input/output buffers as needed.
6379 * Therefore there's no need to enable the input buffer at this
6380 * stage.
cdcd9268 6381 */
f7ace40d 6382 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6383 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6384 * mixer ctrl)
6385 */
f7ace40d
JW
6386 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6387
6388 /* Mute capture amp left and right */
6389 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6390 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6391 * in (on mic1 pin)
6392 */
6393 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6394
6395 /* Do the same for the second ADC: mute capture input amp and
6396 * set ADC connection to line in (on mic1 pin)
6397 */
6398 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6399 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6400
6401 /* Mute all inputs to mixer widget (even unconnected ones) */
6402 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6403 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6404 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6405 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6406 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6407 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6408 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6409 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6410
6411 { }
a9430dd8
JW
6412};
6413
0bfc90e9
JW
6414/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6415 * similar laptops (adapted from Fujitsu init verbs).
6416 */
6417static struct hda_verb alc260_acer_init_verbs[] = {
6418 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6419 * the headphone jack. Turn this on and rely on the standard mute
6420 * methods whenever the user wants to turn these outputs off.
6421 */
6422 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6423 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6424 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6425 /* Internal speaker/Headphone jack is connected to Line-out pin */
6426 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6427 /* Internal microphone/Mic jack is connected to Mic1 pin */
6428 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6429 /* Line In jack is connected to Line1 pin */
6430 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6431 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6432 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6433 /* Ensure all other unused pins are disabled and muted. */
6434 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6435 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6436 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6437 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6439 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6440 /* Disable digital (SPDIF) pins */
6441 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6442 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6443
ea1fb29a 6444 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6445 * bus when acting as outputs.
6446 */
6447 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6448 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6449
6450 /* Start with output sum widgets muted and their output gains at min */
6451 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6452 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6453 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6454 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6455 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6456 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6457 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6458 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6459 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6460
f12ab1e0
TI
6461 /* Unmute Line-out pin widget amp left and right
6462 * (no equiv mixer ctrl)
6463 */
0bfc90e9 6464 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6465 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6466 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6467 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6468 * inputs. If the pin mode is changed by the user the pin mode control
6469 * will take care of enabling the pin's input/output buffers as needed.
6470 * Therefore there's no need to enable the input buffer at this
6471 * stage.
6472 */
6473 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6474 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6475
6476 /* Mute capture amp left and right */
6477 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6478 /* Set ADC connection select to match default mixer setting - mic
6479 * (on mic1 pin)
6480 */
6481 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6482
6483 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6484 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6485 */
6486 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6487 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6488
6489 /* Mute all inputs to mixer widget (even unconnected ones) */
6490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6491 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6492 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6493 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6494 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6495 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6496 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6497 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6498
6499 { }
6500};
6501
cc959489
MS
6502/* Initialisation sequence for Maxdata Favorit 100XS
6503 * (adapted from Acer init verbs).
6504 */
6505static struct hda_verb alc260_favorit100_init_verbs[] = {
6506 /* GPIO 0 enables the output jack.
6507 * Turn this on and rely on the standard mute
6508 * methods whenever the user wants to turn these outputs off.
6509 */
6510 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6511 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6512 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6513 /* Line/Mic input jack is connected to Mic1 pin */
6514 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6515 /* Ensure all other unused pins are disabled and muted. */
6516 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6517 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6518 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6519 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6520 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6521 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6522 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6523 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6525 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6526 /* Disable digital (SPDIF) pins */
6527 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6528 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6529
6530 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6531 * bus when acting as outputs.
6532 */
6533 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6534 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6535
6536 /* Start with output sum widgets muted and their output gains at min */
6537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6538 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6539 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6542 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6543 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6544 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6545 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6546
6547 /* Unmute Line-out pin widget amp left and right
6548 * (no equiv mixer ctrl)
6549 */
6550 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6551 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6552 * inputs. If the pin mode is changed by the user the pin mode control
6553 * will take care of enabling the pin's input/output buffers as needed.
6554 * Therefore there's no need to enable the input buffer at this
6555 * stage.
6556 */
6557 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6558
6559 /* Mute capture amp left and right */
6560 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6561 /* Set ADC connection select to match default mixer setting - mic
6562 * (on mic1 pin)
6563 */
6564 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6565
6566 /* Do similar with the second ADC: mute capture input amp and
6567 * set ADC connection to mic to match ALSA's default state.
6568 */
6569 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6570 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6571
6572 /* Mute all inputs to mixer widget (even unconnected ones) */
6573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6578 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6579 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6580 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6581
6582 { }
6583};
6584
bc9f98a9
KY
6585static struct hda_verb alc260_will_verbs[] = {
6586 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6587 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6588 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6589 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6590 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6591 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6592 {}
6593};
6594
6595static struct hda_verb alc260_replacer_672v_verbs[] = {
6596 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6597 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6598 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6599
6600 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6601 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6602 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6603
6604 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6605 {}
6606};
6607
6608/* toggle speaker-output according to the hp-jack state */
6609static void alc260_replacer_672v_automute(struct hda_codec *codec)
6610{
6611 unsigned int present;
6612
6613 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6614 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6615 if (present) {
82beb8fd
TI
6616 snd_hda_codec_write_cache(codec, 0x01, 0,
6617 AC_VERB_SET_GPIO_DATA, 1);
6618 snd_hda_codec_write_cache(codec, 0x0f, 0,
6619 AC_VERB_SET_PIN_WIDGET_CONTROL,
6620 PIN_HP);
bc9f98a9 6621 } else {
82beb8fd
TI
6622 snd_hda_codec_write_cache(codec, 0x01, 0,
6623 AC_VERB_SET_GPIO_DATA, 0);
6624 snd_hda_codec_write_cache(codec, 0x0f, 0,
6625 AC_VERB_SET_PIN_WIDGET_CONTROL,
6626 PIN_OUT);
bc9f98a9
KY
6627 }
6628}
6629
6630static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6631 unsigned int res)
6632{
6633 if ((res >> 26) == ALC880_HP_EVENT)
6634 alc260_replacer_672v_automute(codec);
6635}
6636
3f878308
KY
6637static struct hda_verb alc260_hp_dc7600_verbs[] = {
6638 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6639 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6640 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6641 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6642 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6644 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6645 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6646 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6647 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6648 {}
6649};
6650
7cf51e48
JW
6651/* Test configuration for debugging, modelled after the ALC880 test
6652 * configuration.
6653 */
6654#ifdef CONFIG_SND_DEBUG
6655static hda_nid_t alc260_test_dac_nids[1] = {
6656 0x02,
6657};
6658static hda_nid_t alc260_test_adc_nids[2] = {
6659 0x04, 0x05,
6660};
a1e8d2da 6661/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6662 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6663 * is NID 0x04.
17e7aec6 6664 */
a1e8d2da
JW
6665static struct hda_input_mux alc260_test_capture_sources[2] = {
6666 {
6667 .num_items = 7,
6668 .items = {
6669 { "MIC1 pin", 0x0 },
6670 { "MIC2 pin", 0x1 },
6671 { "LINE1 pin", 0x2 },
6672 { "LINE2 pin", 0x3 },
6673 { "CD pin", 0x4 },
6674 { "LINE-OUT pin", 0x5 },
6675 { "HP-OUT pin", 0x6 },
6676 },
6677 },
6678 {
6679 .num_items = 8,
6680 .items = {
6681 { "MIC1 pin", 0x0 },
6682 { "MIC2 pin", 0x1 },
6683 { "LINE1 pin", 0x2 },
6684 { "LINE2 pin", 0x3 },
6685 { "CD pin", 0x4 },
6686 { "Mixer", 0x5 },
6687 { "LINE-OUT pin", 0x6 },
6688 { "HP-OUT pin", 0x7 },
6689 },
7cf51e48
JW
6690 },
6691};
6692static struct snd_kcontrol_new alc260_test_mixer[] = {
6693 /* Output driver widgets */
6694 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6695 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6696 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6697 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6698 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6699 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6700
a1e8d2da
JW
6701 /* Modes for retasking pin widgets
6702 * Note: the ALC260 doesn't seem to act on requests to enable mic
6703 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6704 * mention this restriction. At this stage it's not clear whether
6705 * this behaviour is intentional or is a hardware bug in chip
6706 * revisions available at least up until early 2006. Therefore for
6707 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6708 * choices, but if it turns out that the lack of mic bias for these
6709 * NIDs is intentional we could change their modes from
6710 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6711 */
7cf51e48
JW
6712 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6713 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6714 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6715 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6716 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6717 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6718
6719 /* Loopback mixer controls */
6720 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6721 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6722 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6723 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6724 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6725 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6726 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6727 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6728 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6729 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6730 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6731 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6732 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6733 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6734
6735 /* Controls for GPIO pins, assuming they are configured as outputs */
6736 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6737 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6738 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6739 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6740
92621f13
JW
6741 /* Switches to allow the digital IO pins to be enabled. The datasheet
6742 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6743 * make this output available should provide clarification.
92621f13
JW
6744 */
6745 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6746 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6747
f8225f6d
JW
6748 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6749 * this output to turn on an external amplifier.
6750 */
6751 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6752 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6753
7cf51e48
JW
6754 { } /* end */
6755};
6756static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6757 /* Enable all GPIOs as outputs with an initial value of 0 */
6758 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6759 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6760 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6761
7cf51e48
JW
6762 /* Enable retasking pins as output, initially without power amp */
6763 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6764 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6766 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6767 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6768 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6769
92621f13
JW
6770 /* Disable digital (SPDIF) pins initially, but users can enable
6771 * them via a mixer switch. In the case of SPDIF-out, this initverb
6772 * payload also sets the generation to 0, output to be in "consumer"
6773 * PCM format, copyright asserted, no pre-emphasis and no validity
6774 * control.
6775 */
7cf51e48
JW
6776 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6777 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6778
ea1fb29a 6779 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6780 * OUT1 sum bus when acting as an output.
6781 */
6782 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6783 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6784 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6785 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6786
6787 /* Start with output sum widgets muted and their output gains at min */
6788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6789 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6792 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6794 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6795 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6796 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6797
cdcd9268
JW
6798 /* Unmute retasking pin widget output buffers since the default
6799 * state appears to be output. As the pin mode is changed by the
6800 * user the pin mode control will take care of enabling the pin's
6801 * input/output buffers as needed.
6802 */
7cf51e48
JW
6803 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6804 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6805 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6806 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6807 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6808 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6809 /* Also unmute the mono-out pin widget */
6810 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6811
7cf51e48
JW
6812 /* Mute capture amp left and right */
6813 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6814 /* Set ADC connection select to match default mixer setting (mic1
6815 * pin)
7cf51e48
JW
6816 */
6817 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6818
6819 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6820 * set ADC connection to mic1 pin
7cf51e48
JW
6821 */
6822 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6823 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6824
6825 /* Mute all inputs to mixer widget (even unconnected ones) */
6826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6833 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6834
6835 { }
6836};
6837#endif
6838
6330079f
TI
6839#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6840#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6841
a3bcba38
TI
6842#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6843#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6844
df694daa
KY
6845/*
6846 * for BIOS auto-configuration
6847 */
16ded525 6848
df694daa 6849static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6850 const char *pfx, int *vol_bits)
df694daa
KY
6851{
6852 hda_nid_t nid_vol;
6853 unsigned long vol_val, sw_val;
df694daa
KY
6854 int err;
6855
6856 if (nid >= 0x0f && nid < 0x11) {
6857 nid_vol = nid - 0x7;
6858 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6859 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6860 } else if (nid == 0x11) {
6861 nid_vol = nid - 0x7;
6862 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6863 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6864 } else if (nid >= 0x12 && nid <= 0x15) {
6865 nid_vol = 0x08;
6866 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6867 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6868 } else
6869 return 0; /* N/A */
ea1fb29a 6870
863b4518
TI
6871 if (!(*vol_bits & (1 << nid_vol))) {
6872 /* first control for the volume widget */
0afe5f89 6873 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6874 if (err < 0)
6875 return err;
6876 *vol_bits |= (1 << nid_vol);
6877 }
0afe5f89 6878 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6879 if (err < 0)
df694daa
KY
6880 return err;
6881 return 1;
6882}
6883
6884/* add playback controls from the parsed DAC table */
6885static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6886 const struct auto_pin_cfg *cfg)
6887{
6888 hda_nid_t nid;
6889 int err;
863b4518 6890 int vols = 0;
df694daa
KY
6891
6892 spec->multiout.num_dacs = 1;
6893 spec->multiout.dac_nids = spec->private_dac_nids;
6894 spec->multiout.dac_nids[0] = 0x02;
6895
6896 nid = cfg->line_out_pins[0];
6897 if (nid) {
23112d6d
TI
6898 const char *pfx;
6899 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6900 pfx = "Master";
6901 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6902 pfx = "Speaker";
6903 else
6904 pfx = "Front";
6905 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6906 if (err < 0)
6907 return err;
6908 }
6909
82bc955f 6910 nid = cfg->speaker_pins[0];
df694daa 6911 if (nid) {
863b4518 6912 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6913 if (err < 0)
6914 return err;
6915 }
6916
eb06ed8f 6917 nid = cfg->hp_pins[0];
df694daa 6918 if (nid) {
863b4518
TI
6919 err = alc260_add_playback_controls(spec, nid, "Headphone",
6920 &vols);
df694daa
KY
6921 if (err < 0)
6922 return err;
6923 }
f12ab1e0 6924 return 0;
df694daa
KY
6925}
6926
6927/* create playback/capture controls for input pins */
05f5f477 6928static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6929 const struct auto_pin_cfg *cfg)
6930{
05f5f477 6931 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6932}
6933
6934static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6935 hda_nid_t nid, int pin_type,
6936 int sel_idx)
6937{
f6c7e546 6938 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6939 /* need the manual connection? */
6940 if (nid >= 0x12) {
6941 int idx = nid - 0x12;
6942 snd_hda_codec_write(codec, idx + 0x0b, 0,
6943 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6944 }
6945}
6946
6947static void alc260_auto_init_multi_out(struct hda_codec *codec)
6948{
6949 struct alc_spec *spec = codec->spec;
6950 hda_nid_t nid;
6951
f12ab1e0 6952 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6953 if (nid) {
6954 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6955 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6956 }
ea1fb29a 6957
82bc955f 6958 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6959 if (nid)
6960 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6961
eb06ed8f 6962 nid = spec->autocfg.hp_pins[0];
df694daa 6963 if (nid)
baba8ee9 6964 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6965}
df694daa
KY
6966
6967#define ALC260_PIN_CD_NID 0x16
6968static void alc260_auto_init_analog_input(struct hda_codec *codec)
6969{
6970 struct alc_spec *spec = codec->spec;
66ceeb6b 6971 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6972 int i;
6973
66ceeb6b
TI
6974 for (i = 0; i < cfg->num_inputs; i++) {
6975 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6976 if (nid >= 0x12) {
30ea098f 6977 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6978 if (nid != ALC260_PIN_CD_NID &&
6979 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6980 snd_hda_codec_write(codec, nid, 0,
6981 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6982 AMP_OUT_MUTE);
6983 }
6984 }
6985}
6986
7f311a46
TI
6987#define alc260_auto_init_input_src alc880_auto_init_input_src
6988
df694daa
KY
6989/*
6990 * generic initialization of ADC, input mixers and output mixers
6991 */
6992static struct hda_verb alc260_volume_init_verbs[] = {
6993 /*
6994 * Unmute ADC0-1 and set the default input to mic-in
6995 */
6996 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6997 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6998 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6999 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7000
df694daa
KY
7001 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7002 * mixer widget
f12ab1e0
TI
7003 * Note: PASD motherboards uses the Line In 2 as the input for
7004 * front panel mic (mic 2)
df694daa
KY
7005 */
7006 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7007 /* mute analog inputs */
7008 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7013
7014 /*
7015 * Set up output mixers (0x08 - 0x0a)
7016 */
7017 /* set vol=0 to output mixers */
7018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7020 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7021 /* set up input amps for analog loopback */
7022 /* Amp Indices: DAC = 0, mixer = 1 */
7023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7025 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7027 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7028 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7029
df694daa
KY
7030 { }
7031};
7032
7033static int alc260_parse_auto_config(struct hda_codec *codec)
7034{
7035 struct alc_spec *spec = codec->spec;
df694daa
KY
7036 int err;
7037 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7038
f12ab1e0
TI
7039 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7040 alc260_ignore);
7041 if (err < 0)
df694daa 7042 return err;
f12ab1e0
TI
7043 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7044 if (err < 0)
4a471b7d 7045 return err;
603c4019 7046 if (!spec->kctls.list)
df694daa 7047 return 0; /* can't find valid BIOS pin config */
05f5f477 7048 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7049 if (err < 0)
df694daa
KY
7050 return err;
7051
7052 spec->multiout.max_channels = 2;
7053
0852d7a6 7054 if (spec->autocfg.dig_outs)
df694daa 7055 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7056 if (spec->kctls.list)
d88897ea 7057 add_mixer(spec, spec->kctls.list);
df694daa 7058
d88897ea 7059 add_verb(spec, alc260_volume_init_verbs);
df694daa 7060
a1e8d2da 7061 spec->num_mux_defs = 1;
61b9b9b1 7062 spec->input_mux = &spec->private_imux[0];
df694daa 7063
6227cdce 7064 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7065
df694daa
KY
7066 return 1;
7067}
7068
ae6b813a
TI
7069/* additional initialization for auto-configuration model */
7070static void alc260_auto_init(struct hda_codec *codec)
df694daa 7071{
f6c7e546 7072 struct alc_spec *spec = codec->spec;
df694daa
KY
7073 alc260_auto_init_multi_out(codec);
7074 alc260_auto_init_analog_input(codec);
7f311a46 7075 alc260_auto_init_input_src(codec);
757899ac 7076 alc_auto_init_digital(codec);
f6c7e546 7077 if (spec->unsol_event)
7fb0d78f 7078 alc_inithook(codec);
df694daa
KY
7079}
7080
cb53c626
TI
7081#ifdef CONFIG_SND_HDA_POWER_SAVE
7082static struct hda_amp_list alc260_loopbacks[] = {
7083 { 0x07, HDA_INPUT, 0 },
7084 { 0x07, HDA_INPUT, 1 },
7085 { 0x07, HDA_INPUT, 2 },
7086 { 0x07, HDA_INPUT, 3 },
7087 { 0x07, HDA_INPUT, 4 },
7088 { } /* end */
7089};
7090#endif
7091
fc091769
TI
7092/*
7093 * Pin config fixes
7094 */
7095enum {
7096 PINFIX_HP_DC5750,
7097};
7098
fc091769
TI
7099static const struct alc_fixup alc260_fixups[] = {
7100 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7101 .type = ALC_FIXUP_PINS,
7102 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7103 { 0x11, 0x90130110 }, /* speaker */
7104 { }
7105 }
fc091769
TI
7106 },
7107};
7108
7109static struct snd_pci_quirk alc260_fixup_tbl[] = {
7110 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7111 {}
7112};
7113
df694daa
KY
7114/*
7115 * ALC260 configurations
7116 */
ea734963 7117static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7118 [ALC260_BASIC] = "basic",
7119 [ALC260_HP] = "hp",
7120 [ALC260_HP_3013] = "hp-3013",
2922c9af 7121 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7122 [ALC260_FUJITSU_S702X] = "fujitsu",
7123 [ALC260_ACER] = "acer",
bc9f98a9
KY
7124 [ALC260_WILL] = "will",
7125 [ALC260_REPLACER_672V] = "replacer",
cc959489 7126 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7127#ifdef CONFIG_SND_DEBUG
f5fcc13c 7128 [ALC260_TEST] = "test",
7cf51e48 7129#endif
f5fcc13c
TI
7130 [ALC260_AUTO] = "auto",
7131};
7132
7133static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7134 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7135 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7136 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7137 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7138 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7139 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7140 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7141 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7142 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7143 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7144 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7145 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7146 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7147 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7148 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7149 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7150 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7151 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7152 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7153 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7154 {}
7155};
7156
7157static struct alc_config_preset alc260_presets[] = {
7158 [ALC260_BASIC] = {
7159 .mixers = { alc260_base_output_mixer,
45bdd1c1 7160 alc260_input_mixer },
df694daa
KY
7161 .init_verbs = { alc260_init_verbs },
7162 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7163 .dac_nids = alc260_dac_nids,
f9e336f6 7164 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7165 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7166 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7167 .channel_mode = alc260_modes,
7168 .input_mux = &alc260_capture_source,
7169 },
7170 [ALC260_HP] = {
bec15c3a 7171 .mixers = { alc260_hp_output_mixer,
f9e336f6 7172 alc260_input_mixer },
bec15c3a
TI
7173 .init_verbs = { alc260_init_verbs,
7174 alc260_hp_unsol_verbs },
df694daa
KY
7175 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7176 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7177 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7178 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7179 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7180 .channel_mode = alc260_modes,
7181 .input_mux = &alc260_capture_source,
bec15c3a
TI
7182 .unsol_event = alc260_hp_unsol_event,
7183 .init_hook = alc260_hp_automute,
df694daa 7184 },
3f878308
KY
7185 [ALC260_HP_DC7600] = {
7186 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7187 alc260_input_mixer },
3f878308
KY
7188 .init_verbs = { alc260_init_verbs,
7189 alc260_hp_dc7600_verbs },
7190 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7191 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7192 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7193 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7194 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7195 .channel_mode = alc260_modes,
7196 .input_mux = &alc260_capture_source,
7197 .unsol_event = alc260_hp_3012_unsol_event,
7198 .init_hook = alc260_hp_3012_automute,
7199 },
df694daa
KY
7200 [ALC260_HP_3013] = {
7201 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7202 alc260_input_mixer },
bec15c3a
TI
7203 .init_verbs = { alc260_hp_3013_init_verbs,
7204 alc260_hp_3013_unsol_verbs },
df694daa
KY
7205 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7206 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7207 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7208 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7209 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7210 .channel_mode = alc260_modes,
7211 .input_mux = &alc260_capture_source,
bec15c3a
TI
7212 .unsol_event = alc260_hp_3013_unsol_event,
7213 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7214 },
7215 [ALC260_FUJITSU_S702X] = {
f9e336f6 7216 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7217 .init_verbs = { alc260_fujitsu_init_verbs },
7218 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7219 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7220 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7221 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7222 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7223 .channel_mode = alc260_modes,
a1e8d2da
JW
7224 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7225 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7226 },
0bfc90e9 7227 [ALC260_ACER] = {
f9e336f6 7228 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7229 .init_verbs = { alc260_acer_init_verbs },
7230 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7231 .dac_nids = alc260_dac_nids,
7232 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7233 .adc_nids = alc260_dual_adc_nids,
7234 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7235 .channel_mode = alc260_modes,
a1e8d2da
JW
7236 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7237 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7238 },
cc959489
MS
7239 [ALC260_FAVORIT100] = {
7240 .mixers = { alc260_favorit100_mixer },
7241 .init_verbs = { alc260_favorit100_init_verbs },
7242 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7243 .dac_nids = alc260_dac_nids,
7244 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7245 .adc_nids = alc260_dual_adc_nids,
7246 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7247 .channel_mode = alc260_modes,
7248 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7249 .input_mux = alc260_favorit100_capture_sources,
7250 },
bc9f98a9 7251 [ALC260_WILL] = {
f9e336f6 7252 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7253 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7254 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7255 .dac_nids = alc260_dac_nids,
7256 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7257 .adc_nids = alc260_adc_nids,
7258 .dig_out_nid = ALC260_DIGOUT_NID,
7259 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7260 .channel_mode = alc260_modes,
7261 .input_mux = &alc260_capture_source,
7262 },
7263 [ALC260_REPLACER_672V] = {
f9e336f6 7264 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7265 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7266 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7267 .dac_nids = alc260_dac_nids,
7268 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7269 .adc_nids = alc260_adc_nids,
7270 .dig_out_nid = ALC260_DIGOUT_NID,
7271 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7272 .channel_mode = alc260_modes,
7273 .input_mux = &alc260_capture_source,
7274 .unsol_event = alc260_replacer_672v_unsol_event,
7275 .init_hook = alc260_replacer_672v_automute,
7276 },
7cf51e48
JW
7277#ifdef CONFIG_SND_DEBUG
7278 [ALC260_TEST] = {
f9e336f6 7279 .mixers = { alc260_test_mixer },
7cf51e48
JW
7280 .init_verbs = { alc260_test_init_verbs },
7281 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7282 .dac_nids = alc260_test_dac_nids,
7283 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7284 .adc_nids = alc260_test_adc_nids,
7285 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7286 .channel_mode = alc260_modes,
a1e8d2da
JW
7287 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7288 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7289 },
7290#endif
df694daa
KY
7291};
7292
7293static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7294{
7295 struct alc_spec *spec;
df694daa 7296 int err, board_config;
1da177e4 7297
e560d8d8 7298 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7299 if (spec == NULL)
7300 return -ENOMEM;
7301
7302 codec->spec = spec;
7303
f5fcc13c
TI
7304 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7305 alc260_models,
7306 alc260_cfg_tbl);
7307 if (board_config < 0) {
9a11f1aa 7308 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7309 codec->chip_name);
df694daa 7310 board_config = ALC260_AUTO;
16ded525 7311 }
1da177e4 7312
b5bfbc67
TI
7313 if (board_config == ALC260_AUTO) {
7314 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7315 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7316 }
fc091769 7317
df694daa
KY
7318 if (board_config == ALC260_AUTO) {
7319 /* automatic parse from the BIOS config */
7320 err = alc260_parse_auto_config(codec);
7321 if (err < 0) {
7322 alc_free(codec);
7323 return err;
f12ab1e0 7324 } else if (!err) {
9c7f852e
TI
7325 printk(KERN_INFO
7326 "hda_codec: Cannot set up configuration "
7327 "from BIOS. Using base mode...\n");
df694daa
KY
7328 board_config = ALC260_BASIC;
7329 }
a9430dd8 7330 }
e9edcee0 7331
680cd536
KK
7332 err = snd_hda_attach_beep_device(codec, 0x1);
7333 if (err < 0) {
7334 alc_free(codec);
7335 return err;
7336 }
7337
df694daa 7338 if (board_config != ALC260_AUTO)
e9c364c0 7339 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7340
1da177e4
LT
7341 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7342 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7343 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7344
a3bcba38
TI
7345 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7346 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7347
4ef0ef19
TI
7348 if (!spec->adc_nids && spec->input_mux) {
7349 /* check whether NID 0x04 is valid */
7350 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7351 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7352 /* get type */
7353 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7354 spec->adc_nids = alc260_adc_nids_alt;
7355 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7356 } else {
7357 spec->adc_nids = alc260_adc_nids;
7358 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7359 }
7360 }
b59bdf3b 7361 set_capture_mixer(codec);
45bdd1c1 7362 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7363
b5bfbc67 7364 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7365
2134ea4f
TI
7366 spec->vmaster_nid = 0x08;
7367
1da177e4 7368 codec->patch_ops = alc_patch_ops;
df694daa 7369 if (board_config == ALC260_AUTO)
ae6b813a 7370 spec->init_hook = alc260_auto_init;
cb53c626
TI
7371#ifdef CONFIG_SND_HDA_POWER_SAVE
7372 if (!spec->loopback.amplist)
7373 spec->loopback.amplist = alc260_loopbacks;
7374#endif
1da177e4
LT
7375
7376 return 0;
7377}
7378
e9edcee0 7379
1da177e4 7380/*
4953550a 7381 * ALC882/883/885/888/889 support
1da177e4
LT
7382 *
7383 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7384 * configuration. Each pin widget can choose any input DACs and a mixer.
7385 * Each ADC is connected from a mixer of all inputs. This makes possible
7386 * 6-channel independent captures.
7387 *
7388 * In addition, an independent DAC for the multi-playback (not used in this
7389 * driver yet).
7390 */
df694daa
KY
7391#define ALC882_DIGOUT_NID 0x06
7392#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7393#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7394#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7395#define ALC1200_DIGOUT_NID 0x10
7396
1da177e4 7397
d2a6d7dc 7398static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7399 { 8, NULL }
7400};
7401
4953550a 7402/* DACs */
1da177e4
LT
7403static hda_nid_t alc882_dac_nids[4] = {
7404 /* front, rear, clfe, rear_surr */
7405 0x02, 0x03, 0x04, 0x05
7406};
4953550a 7407#define alc883_dac_nids alc882_dac_nids
1da177e4 7408
4953550a 7409/* ADCs */
df694daa
KY
7410#define alc882_adc_nids alc880_adc_nids
7411#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7412#define alc883_adc_nids alc882_adc_nids_alt
7413static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7414static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7415#define alc889_adc_nids alc880_adc_nids
1da177e4 7416
e1406348
TI
7417static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7418static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7419#define alc883_capsrc_nids alc882_capsrc_nids_alt
7420static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7421#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7422
1da177e4
LT
7423/* input MUX */
7424/* FIXME: should be a matrix-type input source selection */
7425
7426static struct hda_input_mux alc882_capture_source = {
7427 .num_items = 4,
7428 .items = {
7429 { "Mic", 0x0 },
7430 { "Front Mic", 0x1 },
7431 { "Line", 0x2 },
7432 { "CD", 0x4 },
7433 },
7434};
41d5545d 7435
4953550a
TI
7436#define alc883_capture_source alc882_capture_source
7437
87a8c370
JK
7438static struct hda_input_mux alc889_capture_source = {
7439 .num_items = 3,
7440 .items = {
7441 { "Front Mic", 0x0 },
7442 { "Mic", 0x3 },
7443 { "Line", 0x2 },
7444 },
7445};
7446
41d5545d
KS
7447static struct hda_input_mux mb5_capture_source = {
7448 .num_items = 3,
7449 .items = {
7450 { "Mic", 0x1 },
b8f171e7 7451 { "Line", 0x7 },
41d5545d
KS
7452 { "CD", 0x4 },
7453 },
7454};
7455
e458b1fa
LY
7456static struct hda_input_mux macmini3_capture_source = {
7457 .num_items = 2,
7458 .items = {
7459 { "Line", 0x2 },
7460 { "CD", 0x4 },
7461 },
7462};
7463
4953550a
TI
7464static struct hda_input_mux alc883_3stack_6ch_intel = {
7465 .num_items = 4,
7466 .items = {
7467 { "Mic", 0x1 },
7468 { "Front Mic", 0x0 },
7469 { "Line", 0x2 },
7470 { "CD", 0x4 },
7471 },
7472};
7473
7474static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7475 .num_items = 2,
7476 .items = {
7477 { "Mic", 0x1 },
7478 { "Line", 0x2 },
7479 },
7480};
7481
7482static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7483 .num_items = 4,
7484 .items = {
7485 { "Mic", 0x0 },
28c4edb7 7486 { "Internal Mic", 0x1 },
4953550a
TI
7487 { "Line", 0x2 },
7488 { "CD", 0x4 },
7489 },
7490};
7491
7492static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7493 .num_items = 2,
7494 .items = {
7495 { "Mic", 0x0 },
28c4edb7 7496 { "Internal Mic", 0x1 },
4953550a
TI
7497 },
7498};
7499
7500static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7501 .num_items = 3,
7502 .items = {
7503 { "Mic", 0x0 },
7504 { "Front Mic", 0x1 },
7505 { "Line", 0x4 },
7506 },
7507};
7508
7509static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7510 .num_items = 2,
7511 .items = {
7512 { "Mic", 0x0 },
7513 { "Line", 0x2 },
7514 },
7515};
7516
7517static struct hda_input_mux alc889A_mb31_capture_source = {
7518 .num_items = 2,
7519 .items = {
7520 { "Mic", 0x0 },
7521 /* Front Mic (0x01) unused */
7522 { "Line", 0x2 },
7523 /* Line 2 (0x03) unused */
af901ca1 7524 /* CD (0x04) unused? */
4953550a
TI
7525 },
7526};
7527
b7cccc52
JM
7528static struct hda_input_mux alc889A_imac91_capture_source = {
7529 .num_items = 2,
7530 .items = {
7531 { "Mic", 0x01 },
7532 { "Line", 0x2 }, /* Not sure! */
7533 },
7534};
7535
4953550a
TI
7536/*
7537 * 2ch mode
7538 */
7539static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7540 { 2, NULL }
7541};
7542
272a527c
KY
7543/*
7544 * 2ch mode
7545 */
7546static struct hda_verb alc882_3ST_ch2_init[] = {
7547 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7548 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7549 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7550 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7551 { } /* end */
7552};
7553
4953550a
TI
7554/*
7555 * 4ch mode
7556 */
7557static struct hda_verb alc882_3ST_ch4_init[] = {
7558 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7559 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7560 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7561 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7562 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7563 { } /* end */
7564};
7565
272a527c
KY
7566/*
7567 * 6ch mode
7568 */
7569static struct hda_verb alc882_3ST_ch6_init[] = {
7570 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7571 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7572 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7573 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7574 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7575 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7576 { } /* end */
7577};
7578
4953550a 7579static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7580 { 2, alc882_3ST_ch2_init },
4953550a 7581 { 4, alc882_3ST_ch4_init },
272a527c
KY
7582 { 6, alc882_3ST_ch6_init },
7583};
7584
4953550a
TI
7585#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7586
a65cc60f 7587/*
7588 * 2ch mode
7589 */
7590static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7591 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7592 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7593 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7594 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7595 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7596 { } /* end */
7597};
7598
7599/*
7600 * 4ch mode
7601 */
7602static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7603 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7604 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7605 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7606 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7607 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7608 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7609 { } /* end */
7610};
7611
7612/*
7613 * 6ch mode
7614 */
7615static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7616 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7617 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7618 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7619 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7620 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7621 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7622 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7623 { } /* end */
7624};
7625
7626static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7627 { 2, alc883_3ST_ch2_clevo_init },
7628 { 4, alc883_3ST_ch4_clevo_init },
7629 { 6, alc883_3ST_ch6_clevo_init },
7630};
7631
7632
df694daa
KY
7633/*
7634 * 6ch mode
7635 */
7636static struct hda_verb alc882_sixstack_ch6_init[] = {
7637 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7638 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7639 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7640 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7641 { } /* end */
7642};
7643
7644/*
7645 * 8ch mode
7646 */
7647static struct hda_verb alc882_sixstack_ch8_init[] = {
7648 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7649 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7650 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7651 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7652 { } /* end */
7653};
7654
7655static struct hda_channel_mode alc882_sixstack_modes[2] = {
7656 { 6, alc882_sixstack_ch6_init },
7657 { 8, alc882_sixstack_ch8_init },
7658};
7659
76e6f5a9
RH
7660
7661/* Macbook Air 2,1 */
7662
7663static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7664 { 2, NULL },
7665};
7666
87350ad0 7667/*
def319f9 7668 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7669 */
7670
7671/*
7672 * 2ch mode
7673 */
7674static struct hda_verb alc885_mbp_ch2_init[] = {
7675 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7676 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7677 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7678 { } /* end */
7679};
7680
7681/*
a3f730af 7682 * 4ch mode
87350ad0 7683 */
a3f730af 7684static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7685 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7686 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7687 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7688 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7689 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7690 { } /* end */
7691};
7692
a3f730af 7693static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7694 { 2, alc885_mbp_ch2_init },
a3f730af 7695 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7696};
7697
92b9de83
KS
7698/*
7699 * 2ch
7700 * Speakers/Woofer/HP = Front
7701 * LineIn = Input
7702 */
7703static struct hda_verb alc885_mb5_ch2_init[] = {
7704 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7705 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7706 { } /* end */
7707};
7708
7709/*
7710 * 6ch mode
7711 * Speakers/HP = Front
7712 * Woofer = LFE
7713 * LineIn = Surround
7714 */
7715static struct hda_verb alc885_mb5_ch6_init[] = {
7716 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7717 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7718 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7719 { } /* end */
7720};
7721
7722static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7723 { 2, alc885_mb5_ch2_init },
7724 { 6, alc885_mb5_ch6_init },
7725};
87350ad0 7726
d01aecdf 7727#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7728
7729/*
7730 * 2ch mode
7731 */
7732static struct hda_verb alc883_4ST_ch2_init[] = {
7733 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7734 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7735 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7736 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7737 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7738 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7739 { } /* end */
7740};
7741
7742/*
7743 * 4ch mode
7744 */
7745static struct hda_verb alc883_4ST_ch4_init[] = {
7746 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7747 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7748 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7749 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7750 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7751 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7752 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7753 { } /* end */
7754};
7755
7756/*
7757 * 6ch mode
7758 */
7759static struct hda_verb alc883_4ST_ch6_init[] = {
7760 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7761 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7762 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7763 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7764 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7765 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7766 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7767 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7768 { } /* end */
7769};
7770
7771/*
7772 * 8ch mode
7773 */
7774static struct hda_verb alc883_4ST_ch8_init[] = {
7775 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7776 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7777 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7778 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7779 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7780 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7781 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7782 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7783 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7784 { } /* end */
7785};
7786
7787static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7788 { 2, alc883_4ST_ch2_init },
7789 { 4, alc883_4ST_ch4_init },
7790 { 6, alc883_4ST_ch6_init },
7791 { 8, alc883_4ST_ch8_init },
7792};
7793
7794
7795/*
7796 * 2ch mode
7797 */
7798static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7799 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7800 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7801 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7802 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7803 { } /* end */
7804};
7805
7806/*
7807 * 4ch mode
7808 */
7809static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7810 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7811 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7812 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7813 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7814 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7815 { } /* end */
7816};
7817
7818/*
7819 * 6ch mode
7820 */
7821static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7822 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7823 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7824 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7825 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7826 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7827 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7828 { } /* end */
7829};
7830
7831static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7832 { 2, alc883_3ST_ch2_intel_init },
7833 { 4, alc883_3ST_ch4_intel_init },
7834 { 6, alc883_3ST_ch6_intel_init },
7835};
7836
dd7714c9
WF
7837/*
7838 * 2ch mode
7839 */
7840static struct hda_verb alc889_ch2_intel_init[] = {
7841 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7842 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7843 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7844 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7845 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7846 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7847 { } /* end */
7848};
7849
87a8c370
JK
7850/*
7851 * 6ch mode
7852 */
7853static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7854 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7855 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7856 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7857 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7858 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7859 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7860 { } /* end */
7861};
7862
7863/*
7864 * 8ch mode
7865 */
7866static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7867 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7868 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7869 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7870 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7871 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7872 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7873 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7874 { } /* end */
7875};
7876
dd7714c9
WF
7877static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7878 { 2, alc889_ch2_intel_init },
87a8c370
JK
7879 { 6, alc889_ch6_intel_init },
7880 { 8, alc889_ch8_intel_init },
7881};
7882
4953550a
TI
7883/*
7884 * 6ch mode
7885 */
7886static struct hda_verb alc883_sixstack_ch6_init[] = {
7887 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7888 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7889 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7890 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7891 { } /* end */
7892};
7893
7894/*
7895 * 8ch mode
7896 */
7897static struct hda_verb alc883_sixstack_ch8_init[] = {
7898 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7899 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7900 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7901 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7902 { } /* end */
7903};
7904
7905static struct hda_channel_mode alc883_sixstack_modes[2] = {
7906 { 6, alc883_sixstack_ch6_init },
7907 { 8, alc883_sixstack_ch8_init },
7908};
7909
7910
1da177e4
LT
7911/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7912 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7913 */
c8b6bf9b 7914static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7917 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7918 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7919 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7920 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7921 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7922 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7923 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7924 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7925 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7926 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7927 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7928 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7929 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 7931 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
7932 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7933 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 7934 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 7935 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7936 { } /* end */
7937};
7938
76e6f5a9
RH
7939/* Macbook Air 2,1 same control for HP and internal Speaker */
7940
7941static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7942 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7943 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7944 { }
7945};
7946
7947
87350ad0 7948static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7949 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7950 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7951 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7952 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7953 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7954 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7955 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7956 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7957 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
7958 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7959 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
7960 { } /* end */
7961};
41d5545d
KS
7962
7963static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7964 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7965 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7966 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7967 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7968 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7969 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7970 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7971 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7972 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7973 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7975 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
7976 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
7978 { } /* end */
7979};
92b9de83 7980
e458b1fa
LY
7981static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7983 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7985 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7986 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7987 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7988 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7989 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7990 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7991 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 7992 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
7993 { } /* end */
7994};
7995
4b7e1803 7996static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7997 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7998 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7999 { } /* end */
8000};
8001
8002
bdd148a3
KY
8003static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8004 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8005 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8006 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8007 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8009 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8011 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8013 { } /* end */
8014};
8015
272a527c
KY
8016static struct snd_kcontrol_new alc882_targa_mixer[] = {
8017 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8018 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8019 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8020 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8021 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8022 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8023 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8024 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8026 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8027 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8028 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8029 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8030 { } /* end */
8031};
8032
8033/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8034 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8035 */
8036static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8037 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8038 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8039 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8040 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8041 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8042 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8043 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8044 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8045 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8046 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8048 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8049 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8050 { } /* end */
8051};
8052
914759b7
TI
8053static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8054 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8055 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8056 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8057 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8058 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8059 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8060 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8062 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8063 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8064 { } /* end */
8065};
8066
df694daa
KY
8067static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8068 {
8069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8070 .name = "Channel Mode",
8071 .info = alc_ch_mode_info,
8072 .get = alc_ch_mode_get,
8073 .put = alc_ch_mode_put,
8074 },
8075 { } /* end */
8076};
8077
4953550a 8078static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8079 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8080 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8081 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8082 /* Rear mixer */
05acb863
TI
8083 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8084 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8085 /* CLFE mixer */
05acb863
TI
8086 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8087 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8088 /* Side mixer */
05acb863
TI
8089 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8090 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8091
e9edcee0 8092 /* Front Pin: output 0 (0x0c) */
05acb863 8093 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8094 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8095 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8096 /* Rear Pin: output 1 (0x0d) */
05acb863 8097 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8099 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8100 /* CLFE Pin: output 2 (0x0e) */
05acb863 8101 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8102 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8103 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8104 /* Side Pin: output 3 (0x0f) */
05acb863 8105 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8106 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8107 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8108 /* Mic (rear) pin: input vref at 80% */
16ded525 8109 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8110 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8111 /* Front Mic pin: input vref at 80% */
16ded525 8112 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8113 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8114 /* Line In pin: input */
05acb863 8115 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8116 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8117 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8118 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8119 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8120 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8121 /* CD pin widget for input */
05acb863 8122 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8123
8124 /* FIXME: use matrix-type input source selection */
8125 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8126 /* Input mixer2 */
05acb863 8127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8128 /* Input mixer3 */
05acb863 8129 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8130 /* ADC2: mute amp left and right */
8131 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8132 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8133 /* ADC3: mute amp left and right */
8134 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8135 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8136
8137 { }
8138};
8139
4953550a
TI
8140static struct hda_verb alc882_adc1_init_verbs[] = {
8141 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8142 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8143 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8144 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8145 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8146 /* ADC1: mute amp left and right */
8147 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8148 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8149 { }
8150};
8151
4b146cb0
TI
8152static struct hda_verb alc882_eapd_verbs[] = {
8153 /* change to EAPD mode */
8154 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8155 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8156 { }
4b146cb0
TI
8157};
8158
87a8c370
JK
8159static struct hda_verb alc889_eapd_verbs[] = {
8160 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8161 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8162 { }
8163};
8164
6732bd0d
WF
8165static struct hda_verb alc_hp15_unsol_verbs[] = {
8166 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8167 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8168 {}
8169};
87a8c370
JK
8170
8171static struct hda_verb alc885_init_verbs[] = {
8172 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8173 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8174 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8175 /* Rear mixer */
88102f3f
KY
8176 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8178 /* CLFE mixer */
88102f3f
KY
8179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8180 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8181 /* Side mixer */
88102f3f
KY
8182 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8183 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8184
8185 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8186 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8188 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8189 /* Front Pin: output 0 (0x0c) */
8190 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8191 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8192 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8193 /* Rear Pin: output 1 (0x0d) */
8194 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8195 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8196 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8197 /* CLFE Pin: output 2 (0x0e) */
8198 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8199 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8200 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8201 /* Side Pin: output 3 (0x0f) */
8202 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8203 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8204 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8205 /* Mic (rear) pin: input vref at 80% */
8206 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8207 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8208 /* Front Mic pin: input vref at 80% */
8209 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8210 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8211 /* Line In pin: input */
8212 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8213 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8214
8215 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8216 /* Input mixer1 */
88102f3f 8217 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8218 /* Input mixer2 */
8219 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8220 /* Input mixer3 */
88102f3f 8221 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8222 /* ADC2: mute amp left and right */
8223 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8224 /* ADC3: mute amp left and right */
8225 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8226
8227 { }
8228};
8229
8230static struct hda_verb alc885_init_input_verbs[] = {
8231 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8232 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8233 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8234 { }
8235};
8236
8237
8238/* Unmute Selector 24h and set the default input to front mic */
8239static struct hda_verb alc889_init_input_verbs[] = {
8240 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8241 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8242 { }
8243};
8244
8245
4953550a
TI
8246#define alc883_init_verbs alc882_base_init_verbs
8247
9102cd1c
TD
8248/* Mac Pro test */
8249static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8250 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8251 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8252 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8253 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8254 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8255 /* FIXME: this looks suspicious...
d355c82a
JK
8256 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8257 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8258 */
9102cd1c
TD
8259 { } /* end */
8260};
8261
8262static struct hda_verb alc882_macpro_init_verbs[] = {
8263 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8265 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8266 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8267 /* Front Pin: output 0 (0x0c) */
8268 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8269 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8270 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8271 /* Front Mic pin: input vref at 80% */
8272 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8273 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8274 /* Speaker: output */
8275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8277 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8278 /* Headphone output (output 0 - 0x0c) */
8279 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8280 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8281 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8282
8283 /* FIXME: use matrix-type input source selection */
8284 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8285 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8286 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8288 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8289 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8290 /* Input mixer2 */
8291 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8292 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8293 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8294 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8295 /* Input mixer3 */
8296 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8298 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8299 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8300 /* ADC1: mute amp left and right */
8301 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8302 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8303 /* ADC2: mute amp left and right */
8304 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8305 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8306 /* ADC3: mute amp left and right */
8307 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8308 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8309
8310 { }
8311};
f12ab1e0 8312
41d5545d
KS
8313/* Macbook 5,1 */
8314static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8315 /* DACs */
8316 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8317 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8318 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8319 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8320 /* Front mixer */
41d5545d
KS
8321 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8322 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8324 /* Surround mixer */
8325 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8326 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8327 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8328 /* LFE mixer */
8329 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8330 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8331 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8332 /* HP mixer */
8333 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8334 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8335 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8336 /* Front Pin (0x0c) */
41d5545d
KS
8337 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8339 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8340 /* LFE Pin (0x0e) */
8341 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8343 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8344 /* HP Pin (0x0f) */
41d5545d
KS
8345 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8346 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8347 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8348 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8349 /* Front Mic pin: input vref at 80% */
8350 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8351 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8352 /* Line In pin */
8353 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8354 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8355
b8f171e7
AM
8356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8359 { }
8360};
8361
e458b1fa
LY
8362/* Macmini 3,1 */
8363static struct hda_verb alc885_macmini3_init_verbs[] = {
8364 /* DACs */
8365 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8366 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8367 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8368 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8369 /* Front mixer */
8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8373 /* Surround mixer */
8374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8375 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8376 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8377 /* LFE mixer */
8378 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8380 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8381 /* HP mixer */
8382 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8383 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8384 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8385 /* Front Pin (0x0c) */
8386 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8387 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8388 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8389 /* LFE Pin (0x0e) */
8390 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8391 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8392 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8393 /* HP Pin (0x0f) */
8394 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8395 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8396 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8397 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8398 /* Line In pin */
8399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8400 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8401
8402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8405 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8406 { }
8407};
8408
76e6f5a9
RH
8409
8410static struct hda_verb alc885_mba21_init_verbs[] = {
8411 /*Internal and HP Speaker Mixer*/
8412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8415 /*Internal Speaker Pin (0x0c)*/
8416 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8417 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8418 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8419 /* HP Pin: output 0 (0x0e) */
8420 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8422 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8423 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8424 /* Line in (is hp when jack connected)*/
8425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8426 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8427
8428 { }
8429 };
8430
8431
87350ad0
TI
8432/* Macbook Pro rev3 */
8433static struct hda_verb alc885_mbp3_init_verbs[] = {
8434 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8437 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8438 /* Rear mixer */
8439 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8442 /* HP mixer */
8443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8445 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8446 /* Front Pin: output 0 (0x0c) */
8447 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8448 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8449 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8450 /* HP Pin: output 0 (0x0e) */
87350ad0 8451 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8453 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8454 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8455 /* Mic (rear) pin: input vref at 80% */
8456 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8457 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8458 /* Front Mic pin: input vref at 80% */
8459 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8460 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8461 /* Line In pin: use output 1 when in LineOut mode */
8462 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8463 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8464 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8465
8466 /* FIXME: use matrix-type input source selection */
8467 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8468 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8469 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8472 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8473 /* Input mixer2 */
8474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8477 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8478 /* Input mixer3 */
8479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8483 /* ADC1: mute amp left and right */
8484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8485 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8486 /* ADC2: mute amp left and right */
8487 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8488 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8489 /* ADC3: mute amp left and right */
8490 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8491 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8492
8493 { }
8494};
8495
4b7e1803
JM
8496/* iMac 9,1 */
8497static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8498 /* Internal Speaker Pin (0x0c) */
8499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8501 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8504 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8505 /* HP Pin: Rear */
4b7e1803
JM
8506 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8507 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8508 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8509 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8510 /* Line in Rear */
8511 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8512 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8513 /* Front Mic pin: input vref at 80% */
8514 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8515 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8516 /* Rear mixer */
8517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8519 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8520 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8521 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8522 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8524 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8525 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8526 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8527 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8528 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8529 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8531 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8532 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8533 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8534 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8538 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8539 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8540 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8541 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8542 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8543 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8544 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8545 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8546 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8547 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8548 { }
8549};
8550
c54728d8
NF
8551/* iMac 24 mixer. */
8552static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8553 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8554 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8555 { } /* end */
8556};
8557
8558/* iMac 24 init verbs. */
8559static struct hda_verb alc885_imac24_init_verbs[] = {
8560 /* Internal speakers: output 0 (0x0c) */
8561 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8562 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8563 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8564 /* Internal speakers: output 0 (0x0c) */
8565 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8566 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8567 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8568 /* Headphone: output 0 (0x0c) */
8569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8570 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8571 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8572 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8573 /* Front Mic: input vref at 80% */
8574 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8575 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8576 { }
8577};
8578
8579/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8580static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8581{
a9fd4f3f 8582 struct alc_spec *spec = codec->spec;
c54728d8 8583
a9fd4f3f
TI
8584 spec->autocfg.hp_pins[0] = 0x14;
8585 spec->autocfg.speaker_pins[0] = 0x18;
8586 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8587}
8588
9d54f08b
TI
8589#define alc885_mb5_setup alc885_imac24_setup
8590#define alc885_macmini3_setup alc885_imac24_setup
8591
76e6f5a9
RH
8592/* Macbook Air 2,1 */
8593static void alc885_mba21_setup(struct hda_codec *codec)
8594{
8595 struct alc_spec *spec = codec->spec;
8596
8597 spec->autocfg.hp_pins[0] = 0x14;
8598 spec->autocfg.speaker_pins[0] = 0x18;
8599}
8600
8601
8602
4f5d1706 8603static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8604{
a9fd4f3f 8605 struct alc_spec *spec = codec->spec;
87350ad0 8606
a9fd4f3f
TI
8607 spec->autocfg.hp_pins[0] = 0x15;
8608 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8609}
8610
9d54f08b 8611static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8612{
9d54f08b 8613 struct alc_spec *spec = codec->spec;
4b7e1803 8614
9d54f08b 8615 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8616 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8617 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8618}
87350ad0 8619
272a527c
KY
8620static struct hda_verb alc882_targa_verbs[] = {
8621 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8622 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8623
8624 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8626
272a527c
KY
8627 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8628 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8629 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8630
8631 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8632 { } /* end */
8633};
8634
8635/* toggle speaker-output according to the hp-jack state */
8636static void alc882_targa_automute(struct hda_codec *codec)
8637{
a9fd4f3f
TI
8638 struct alc_spec *spec = codec->spec;
8639 alc_automute_amp(codec);
82beb8fd 8640 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8641 spec->jack_present ? 1 : 3);
8642}
8643
4f5d1706 8644static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8645{
8646 struct alc_spec *spec = codec->spec;
8647
8648 spec->autocfg.hp_pins[0] = 0x14;
8649 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8650}
8651
8652static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8653{
a9fd4f3f 8654 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8655 alc882_targa_automute(codec);
272a527c
KY
8656}
8657
8658static struct hda_verb alc882_asus_a7j_verbs[] = {
8659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8661
8662 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8663 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8664 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8665
272a527c
KY
8666 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8667 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8668 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8669
8670 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8671 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8672 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8673 { } /* end */
8674};
8675
914759b7
TI
8676static struct hda_verb alc882_asus_a7m_verbs[] = {
8677 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8678 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8679
8680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8681 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8683
914759b7
TI
8684 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8685 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8686 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8687
8688 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8689 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8690 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8691 { } /* end */
8692};
8693
9102cd1c
TD
8694static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8695{
8696 unsigned int gpiostate, gpiomask, gpiodir;
8697
8698 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8699 AC_VERB_GET_GPIO_DATA, 0);
8700
8701 if (!muted)
8702 gpiostate |= (1 << pin);
8703 else
8704 gpiostate &= ~(1 << pin);
8705
8706 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8707 AC_VERB_GET_GPIO_MASK, 0);
8708 gpiomask |= (1 << pin);
8709
8710 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8711 AC_VERB_GET_GPIO_DIRECTION, 0);
8712 gpiodir |= (1 << pin);
8713
8714
8715 snd_hda_codec_write(codec, codec->afg, 0,
8716 AC_VERB_SET_GPIO_MASK, gpiomask);
8717 snd_hda_codec_write(codec, codec->afg, 0,
8718 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8719
8720 msleep(1);
8721
8722 snd_hda_codec_write(codec, codec->afg, 0,
8723 AC_VERB_SET_GPIO_DATA, gpiostate);
8724}
8725
7debbe51
TI
8726/* set up GPIO at initialization */
8727static void alc885_macpro_init_hook(struct hda_codec *codec)
8728{
8729 alc882_gpio_mute(codec, 0, 0);
8730 alc882_gpio_mute(codec, 1, 0);
8731}
8732
8733/* set up GPIO and update auto-muting at initialization */
8734static void alc885_imac24_init_hook(struct hda_codec *codec)
8735{
8736 alc885_macpro_init_hook(codec);
4f5d1706 8737 alc_automute_amp(codec);
7debbe51
TI
8738}
8739
df694daa
KY
8740/*
8741 * generic initialization of ADC, input mixers and output mixers
8742 */
4953550a 8743static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8744 /*
8745 * Unmute ADC0-2 and set the default input to mic-in
8746 */
4953550a
TI
8747 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8748 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8749 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8750 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8751
4953550a
TI
8752 /*
8753 * Set up output mixers (0x0c - 0x0f)
8754 */
8755 /* set vol=0 to output mixers */
8756 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8757 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8758 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8759 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8760 /* set up input amps for analog loopback */
8761 /* Amp Indices: DAC = 0, mixer = 1 */
8762 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8763 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8764 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8765 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8766 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8767 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8768 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8769 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8770 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8771 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8772
4953550a
TI
8773 /* FIXME: use matrix-type input source selection */
8774 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8775 /* Input mixer2 */
88102f3f 8776 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8777 /* Input mixer3 */
88102f3f 8778 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8779 { }
9c7f852e
TI
8780};
8781
eb4c41d3
TS
8782/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8783static struct hda_verb alc889A_mb31_ch2_init[] = {
8784 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8785 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8786 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8787 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8788 { } /* end */
8789};
8790
8791/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8792static struct hda_verb alc889A_mb31_ch4_init[] = {
8793 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8794 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8795 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8796 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8797 { } /* end */
8798};
8799
8800/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8801static struct hda_verb alc889A_mb31_ch5_init[] = {
8802 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8804 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8805 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8806 { } /* end */
8807};
8808
8809/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8810static struct hda_verb alc889A_mb31_ch6_init[] = {
8811 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8812 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8813 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8814 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8815 { } /* end */
8816};
8817
8818static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8819 { 2, alc889A_mb31_ch2_init },
8820 { 4, alc889A_mb31_ch4_init },
8821 { 5, alc889A_mb31_ch5_init },
8822 { 6, alc889A_mb31_ch6_init },
8823};
8824
b373bdeb
AN
8825static struct hda_verb alc883_medion_eapd_verbs[] = {
8826 /* eanable EAPD on medion laptop */
8827 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8828 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8829 { }
8830};
8831
4953550a 8832#define alc883_base_mixer alc882_base_mixer
834be88d 8833
a8848bd6
AS
8834static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8835 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8836 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8837 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8838 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8839 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8840 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8842 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8843 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8844 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8845 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8846 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8847 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8848 { } /* end */
8849};
8850
0c4cc443 8851static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8852 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8853 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8854 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8855 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8857 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8859 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8860 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8861 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8862 { } /* end */
8863};
8864
fb97dc67
J
8865static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8866 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8867 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8868 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8869 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8870 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8871 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8873 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8874 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8875 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8876 { } /* end */
8877};
8878
9c7f852e
TI
8879static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8880 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8881 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8883 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8884 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8886 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8887 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8888 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8889 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8890 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8891 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8892 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8893 { } /* end */
8894};
df694daa 8895
9c7f852e
TI
8896static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8897 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8898 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8899 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8900 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8901 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8902 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8903 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8904 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8905 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8906 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8907 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8908 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8909 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8910 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8911 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8912 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8913 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8914 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8915 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8916 { } /* end */
8917};
8918
17bba1b7
J
8919static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8920 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8921 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8922 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8923 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8924 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8925 HDA_OUTPUT),
8926 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8927 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8928 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8929 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8930 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8931 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8932 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8933 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8935 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
8936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8937 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8938 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 8939 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8940 { } /* end */
8941};
8942
87a8c370
JK
8943static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8944 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8945 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8946 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8947 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8948 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8949 HDA_OUTPUT),
8950 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8951 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8952 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8953 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8954 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8956 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8957 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8958 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 8959 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
8960 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8961 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8962 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
8963 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8964 { } /* end */
8965};
8966
d1d985f0 8967static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8968 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8969 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8970 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8971 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8972 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8973 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8974 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8975 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8976 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8977 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8978 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8980 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8981 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8982 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
8983 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8984 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8985 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 8986 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8987 { } /* end */
8988};
8989
c259249f 8990static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8991 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8992 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8993 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8994 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8995 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8996 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8997 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8998 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8999 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9000 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9005 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9006 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9008 { } /* end */
f12ab1e0 9009};
ccc656ce 9010
c259249f 9011static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9012 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9013 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9014 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9015 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9016 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9017 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9018 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9019 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9021 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9022 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9023 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9024 { } /* end */
f12ab1e0 9025};
ccc656ce 9026
b99dba34
TI
9027static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9028 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9029 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9030 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9031 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9032 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9033 { } /* end */
9034};
9035
bc9f98a9
KY
9036static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9037 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9038 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9039 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9040 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9041 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9042 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9043 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9045 { } /* end */
f12ab1e0 9046};
bc9f98a9 9047
272a527c
KY
9048static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9049 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9050 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9051 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9052 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9053 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9054 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9055 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9056 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9057 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9058 { } /* end */
ea1fb29a 9059};
272a527c 9060
7ad7b218
MC
9061static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9062 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9063 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9064 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9065 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9066 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9067 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9068 { } /* end */
9069};
9070
9071static struct hda_verb alc883_medion_wim2160_verbs[] = {
9072 /* Unmute front mixer */
9073 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9074 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9075
9076 /* Set speaker pin to front mixer */
9077 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9078
9079 /* Init headphone pin */
9080 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9081 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9082 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9083 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9084
9085 { } /* end */
9086};
9087
9088/* toggle speaker-output according to the hp-jack state */
9089static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9090{
9091 struct alc_spec *spec = codec->spec;
9092
9093 spec->autocfg.hp_pins[0] = 0x1a;
9094 spec->autocfg.speaker_pins[0] = 0x15;
9095}
9096
2880a867 9097static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9098 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9099 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9100 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9104 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9105 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9106 { } /* end */
d1a991a6 9107};
2880a867 9108
d2fd4b09
TV
9109static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9110 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9111 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9112 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9113 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9114 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9115 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9117 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9119 { } /* end */
9120};
9121
e2757d5e
KY
9122static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9123 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9124 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9125 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9126 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9127 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9128 0x0d, 1, 0x0, HDA_OUTPUT),
9129 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9130 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9131 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9132 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9133 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9134 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9135 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9136 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9137 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9138 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9139 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9140 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9141 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9142 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9143 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9144 { } /* end */
9145};
9146
eb4c41d3
TS
9147static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9148 /* Output mixers */
9149 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9150 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9151 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9152 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9153 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9154 HDA_OUTPUT),
9155 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9156 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9157 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9158 /* Output switches */
9159 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9160 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9161 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9162 /* Boost mixers */
5f99f86a
DH
9163 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9164 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9165 /* Input mixers */
9166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9168 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9169 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9170 { } /* end */
9171};
9172
3e1647c5
GG
9173static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9174 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9175 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9176 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9177 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9178 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9179 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9180 { } /* end */
9181};
9182
e2757d5e
KY
9183static struct hda_bind_ctls alc883_bind_cap_vol = {
9184 .ops = &snd_hda_bind_vol,
9185 .values = {
9186 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9187 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9188 0
9189 },
9190};
9191
9192static struct hda_bind_ctls alc883_bind_cap_switch = {
9193 .ops = &snd_hda_bind_sw,
9194 .values = {
9195 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9196 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9197 0
9198 },
9199};
9200
9201static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9203 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9204 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9205 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9206 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9207 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9208 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9209 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9210 { } /* end */
9211};
df694daa 9212
4953550a
TI
9213static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9214 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9215 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9216 {
9217 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9218 /* .name = "Capture Source", */
9219 .name = "Input Source",
9220 .count = 1,
9221 .info = alc_mux_enum_info,
9222 .get = alc_mux_enum_get,
9223 .put = alc_mux_enum_put,
9224 },
9225 { } /* end */
9226};
9c7f852e 9227
4953550a
TI
9228static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9229 {
9230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9231 .name = "Channel Mode",
9232 .info = alc_ch_mode_info,
9233 .get = alc_ch_mode_get,
9234 .put = alc_ch_mode_put,
9235 },
9236 { } /* end */
9c7f852e
TI
9237};
9238
a8848bd6 9239/* toggle speaker-output according to the hp-jack state */
4f5d1706 9240static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9241{
a9fd4f3f 9242 struct alc_spec *spec = codec->spec;
a8848bd6 9243
a9fd4f3f
TI
9244 spec->autocfg.hp_pins[0] = 0x15;
9245 spec->autocfg.speaker_pins[0] = 0x14;
9246 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9247}
9248
a8848bd6
AS
9249static struct hda_verb alc883_mitac_verbs[] = {
9250 /* HP */
9251 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9252 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9253 /* Subwoofer */
9254 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9255 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9256
9257 /* enable unsolicited event */
9258 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9259 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9260
9261 { } /* end */
9262};
9263
a65cc60f 9264static struct hda_verb alc883_clevo_m540r_verbs[] = {
9265 /* HP */
9266 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9268 /* Int speaker */
9269 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9270
9271 /* enable unsolicited event */
9272 /*
9273 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9274 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9275 */
9276
9277 { } /* end */
9278};
9279
0c4cc443 9280static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9281 /* HP */
9282 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9283 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9284 /* Int speaker */
9285 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9286 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9287
9288 /* enable unsolicited event */
9289 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9290 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9291
9292 { } /* end */
9293};
9294
fb97dc67
J
9295static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9296 /* HP */
9297 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9298 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9299 /* Subwoofer */
9300 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9302
9303 /* enable unsolicited event */
9304 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9305
9306 { } /* end */
9307};
9308
c259249f 9309static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9310 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9312
9313 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9314 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9315
64a8be74
DH
9316/* Connect Line-Out side jack (SPDIF) to Side */
9317 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9318 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9319 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9320/* Connect Mic jack to CLFE */
9321 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9322 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9323 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9324/* Connect Line-in jack to Surround */
9325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9326 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9327 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9328/* Connect HP out jack to Front */
9329 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9330 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9331 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9332
9333 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9334
9335 { } /* end */
9336};
9337
bc9f98a9
KY
9338static struct hda_verb alc883_lenovo_101e_verbs[] = {
9339 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9340 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9341 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9342 { } /* end */
9343};
9344
272a527c
KY
9345static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9348 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9350 { } /* end */
9351};
9352
9353static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9356 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9357 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9358 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9359 { } /* end */
9360};
9361
189609ae
KY
9362static struct hda_verb alc883_haier_w66_verbs[] = {
9363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9364 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9365
9366 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9367
9368 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9369 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9370 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9371 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9372 { } /* end */
9373};
9374
e2757d5e
KY
9375static struct hda_verb alc888_lenovo_sky_verbs[] = {
9376 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9377 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9378 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9381 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9382 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9383 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9384 { } /* end */
9385};
9386
8718b700
HRK
9387static struct hda_verb alc888_6st_dell_verbs[] = {
9388 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9389 { }
9390};
9391
3e1647c5
GG
9392static struct hda_verb alc883_vaiott_verbs[] = {
9393 /* HP */
9394 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9396
9397 /* enable unsolicited event */
9398 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9399
9400 { } /* end */
9401};
9402
4f5d1706 9403static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9404{
a9fd4f3f 9405 struct alc_spec *spec = codec->spec;
8718b700 9406
a9fd4f3f
TI
9407 spec->autocfg.hp_pins[0] = 0x1b;
9408 spec->autocfg.speaker_pins[0] = 0x14;
9409 spec->autocfg.speaker_pins[1] = 0x16;
9410 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9411}
9412
4723c022 9413static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9414 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9415 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9416 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9417 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9418 { } /* end */
5795b9e6
CM
9419};
9420
3ea0d7cf
HRK
9421/*
9422 * 2ch mode
9423 */
4723c022 9424static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9425 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9426 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9427 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9428 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9429 { } /* end */
8341de60
CM
9430};
9431
3ea0d7cf
HRK
9432/*
9433 * 4ch mode
9434 */
9435static struct hda_verb alc888_3st_hp_4ch_init[] = {
9436 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9437 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9438 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9439 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9440 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9441 { } /* end */
9442};
9443
9444/*
9445 * 6ch mode
9446 */
4723c022 9447static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9448 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9449 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9450 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9451 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9452 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9453 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9454 { } /* end */
8341de60
CM
9455};
9456
3ea0d7cf 9457static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9458 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9459 { 4, alc888_3st_hp_4ch_init },
4723c022 9460 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9461};
9462
272a527c
KY
9463/* toggle front-jack and RCA according to the hp-jack state */
9464static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9465{
864f92be 9466 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9467
47fd830a
TI
9468 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9469 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9470 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9471 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9472}
9473
9474/* toggle RCA according to the front-jack state */
9475static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9476{
864f92be 9477 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9478
47fd830a
TI
9479 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9480 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9481}
47fd830a 9482
272a527c
KY
9483static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9484 unsigned int res)
9485{
9486 if ((res >> 26) == ALC880_HP_EVENT)
9487 alc888_lenovo_ms7195_front_automute(codec);
9488 if ((res >> 26) == ALC880_FRONT_EVENT)
9489 alc888_lenovo_ms7195_rca_automute(codec);
9490}
9491
272a527c 9492/* toggle speaker-output according to the hp-jack state */
dc427170 9493static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9494{
a9fd4f3f 9495 struct alc_spec *spec = codec->spec;
272a527c 9496
a9fd4f3f
TI
9497 spec->autocfg.hp_pins[0] = 0x14;
9498 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9499}
9500
ccc656ce 9501/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9502#define alc883_targa_init_hook alc882_targa_init_hook
9503#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9504
4f5d1706 9505static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9506{
a9fd4f3f
TI
9507 struct alc_spec *spec = codec->spec;
9508
9509 spec->autocfg.hp_pins[0] = 0x15;
9510 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9511}
9512
9513static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9514{
a9fd4f3f 9515 alc_automute_amp(codec);
eeb43387 9516 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9517}
9518
9519static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9520 unsigned int res)
9521{
0c4cc443 9522 switch (res >> 26) {
0c4cc443 9523 case ALC880_MIC_EVENT:
eeb43387 9524 alc88x_simple_mic_automute(codec);
0c4cc443 9525 break;
a9fd4f3f
TI
9526 default:
9527 alc_automute_amp_unsol_event(codec, res);
9528 break;
0c4cc443 9529 }
368c7a95
J
9530}
9531
fb97dc67 9532/* toggle speaker-output according to the hp-jack state */
4f5d1706 9533static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9534{
a9fd4f3f 9535 struct alc_spec *spec = codec->spec;
fb97dc67 9536
a9fd4f3f
TI
9537 spec->autocfg.hp_pins[0] = 0x14;
9538 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9539}
9540
4f5d1706 9541static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9542{
a9fd4f3f 9543 struct alc_spec *spec = codec->spec;
189609ae 9544
a9fd4f3f
TI
9545 spec->autocfg.hp_pins[0] = 0x1b;
9546 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9547}
9548
bc9f98a9
KY
9549static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9550{
864f92be 9551 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9552
47fd830a
TI
9553 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9554 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9555}
9556
9557static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9558{
864f92be 9559 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9560
47fd830a
TI
9561 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9562 HDA_AMP_MUTE, bits);
9563 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9564 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9565}
9566
9567static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9568 unsigned int res)
9569{
9570 if ((res >> 26) == ALC880_HP_EVENT)
9571 alc883_lenovo_101e_all_automute(codec);
9572 if ((res >> 26) == ALC880_FRONT_EVENT)
9573 alc883_lenovo_101e_ispeaker_automute(codec);
9574}
9575
676a9b53 9576/* toggle speaker-output according to the hp-jack state */
4f5d1706 9577static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9578{
a9fd4f3f 9579 struct alc_spec *spec = codec->spec;
676a9b53 9580
a9fd4f3f
TI
9581 spec->autocfg.hp_pins[0] = 0x14;
9582 spec->autocfg.speaker_pins[0] = 0x15;
9583 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9584}
9585
d1a991a6
KY
9586static struct hda_verb alc883_acer_eapd_verbs[] = {
9587 /* HP Pin: output 0 (0x0c) */
9588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9589 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9590 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9591 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9592 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9593 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9594 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9595 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9596 /* eanable EAPD on medion laptop */
9597 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9598 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9599 /* enable unsolicited event */
9600 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9601 { }
9602};
9603
4f5d1706 9604static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9605{
a9fd4f3f 9606 struct alc_spec *spec = codec->spec;
5795b9e6 9607
a9fd4f3f
TI
9608 spec->autocfg.hp_pins[0] = 0x1b;
9609 spec->autocfg.speaker_pins[0] = 0x14;
9610 spec->autocfg.speaker_pins[1] = 0x15;
9611 spec->autocfg.speaker_pins[2] = 0x16;
9612 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9613}
9614
4f5d1706 9615static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9616{
a9fd4f3f 9617 struct alc_spec *spec = codec->spec;
e2757d5e 9618
a9fd4f3f
TI
9619 spec->autocfg.hp_pins[0] = 0x1b;
9620 spec->autocfg.speaker_pins[0] = 0x14;
9621 spec->autocfg.speaker_pins[1] = 0x15;
9622 spec->autocfg.speaker_pins[2] = 0x16;
9623 spec->autocfg.speaker_pins[3] = 0x17;
9624 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9625}
9626
4f5d1706 9627static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9628{
9629 struct alc_spec *spec = codec->spec;
9630
9631 spec->autocfg.hp_pins[0] = 0x15;
9632 spec->autocfg.speaker_pins[0] = 0x14;
9633 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9634}
9635
e2757d5e
KY
9636static struct hda_verb alc888_asus_m90v_verbs[] = {
9637 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9638 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9639 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9640 /* enable unsolicited event */
9641 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9642 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9643 { } /* end */
9644};
9645
4f5d1706 9646static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9647{
a9fd4f3f 9648 struct alc_spec *spec = codec->spec;
e2757d5e 9649
a9fd4f3f
TI
9650 spec->autocfg.hp_pins[0] = 0x1b;
9651 spec->autocfg.speaker_pins[0] = 0x14;
9652 spec->autocfg.speaker_pins[1] = 0x15;
9653 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9654 spec->ext_mic.pin = 0x18;
9655 spec->int_mic.pin = 0x19;
9656 spec->ext_mic.mux_idx = 0;
9657 spec->int_mic.mux_idx = 1;
9658 spec->auto_mic = 1;
e2757d5e
KY
9659}
9660
9661static struct hda_verb alc888_asus_eee1601_verbs[] = {
9662 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9663 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9665 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9666 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9667 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9668 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9669 /* enable unsolicited event */
9670 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9671 { } /* end */
9672};
9673
e2757d5e
KY
9674static void alc883_eee1601_inithook(struct hda_codec *codec)
9675{
a9fd4f3f
TI
9676 struct alc_spec *spec = codec->spec;
9677
9678 spec->autocfg.hp_pins[0] = 0x14;
9679 spec->autocfg.speaker_pins[0] = 0x1b;
9680 alc_automute_pin(codec);
e2757d5e
KY
9681}
9682
eb4c41d3
TS
9683static struct hda_verb alc889A_mb31_verbs[] = {
9684 /* Init rear pin (used as headphone output) */
9685 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9686 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9687 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9688 /* Init line pin (used as output in 4ch and 6ch mode) */
9689 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9690 /* Init line 2 pin (used as headphone out by default) */
9691 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9692 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9693 { } /* end */
9694};
9695
9696/* Mute speakers according to the headphone jack state */
9697static void alc889A_mb31_automute(struct hda_codec *codec)
9698{
9699 unsigned int present;
9700
9701 /* Mute only in 2ch or 4ch mode */
9702 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9703 == 0x00) {
864f92be 9704 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9705 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9706 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9707 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9708 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9709 }
9710}
9711
9712static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9713{
9714 if ((res >> 26) == ALC880_HP_EVENT)
9715 alc889A_mb31_automute(codec);
9716}
9717
4953550a 9718
cb53c626 9719#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9720#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9721#endif
9722
def319f9 9723/* pcm configuration: identical with ALC880 */
4953550a
TI
9724#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9725#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9726#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9727#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9728
9729static hda_nid_t alc883_slave_dig_outs[] = {
9730 ALC1200_DIGOUT_NID, 0,
9731};
9732
9733static hda_nid_t alc1200_slave_dig_outs[] = {
9734 ALC883_DIGOUT_NID, 0,
9735};
9c7f852e
TI
9736
9737/*
9738 * configuration and preset
9739 */
ea734963 9740static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9741 [ALC882_3ST_DIG] = "3stack-dig",
9742 [ALC882_6ST_DIG] = "6stack-dig",
9743 [ALC882_ARIMA] = "arima",
9744 [ALC882_W2JC] = "w2jc",
9745 [ALC882_TARGA] = "targa",
9746 [ALC882_ASUS_A7J] = "asus-a7j",
9747 [ALC882_ASUS_A7M] = "asus-a7m",
9748 [ALC885_MACPRO] = "macpro",
9749 [ALC885_MB5] = "mb5",
e458b1fa 9750 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9751 [ALC885_MBA21] = "mba21",
4953550a
TI
9752 [ALC885_MBP3] = "mbp3",
9753 [ALC885_IMAC24] = "imac24",
4b7e1803 9754 [ALC885_IMAC91] = "imac91",
4953550a 9755 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9756 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9757 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9758 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9759 [ALC883_TARGA_DIG] = "targa-dig",
9760 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9761 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9762 [ALC883_ACER] = "acer",
2880a867 9763 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9764 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9765 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9766 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9767 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9768 [ALC883_MEDION] = "medion",
7ad7b218 9769 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9770 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9771 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9772 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9773 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9774 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9775 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9776 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9777 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9778 [ALC883_MITAC] = "mitac",
a65cc60f 9779 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9780 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9781 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9782 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9783 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9784 [ALC889A_INTEL] = "intel-alc889a",
9785 [ALC889_INTEL] = "intel-x58",
3ab90935 9786 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9787 [ALC889A_MB31] = "mb31",
3e1647c5 9788 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9789 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9790};
9791
4953550a
TI
9792static struct snd_pci_quirk alc882_cfg_tbl[] = {
9793 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9794
ac3e3741 9795 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9796 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9797 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9798 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9799 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9800 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9801 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9802 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9803 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9804 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9805 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9806 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9807 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9808 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9809 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9810 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9811 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9812 ALC888_ACER_ASPIRE_6530G),
cc374c47 9813 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9814 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9815 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9816 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9817 /* default Acer -- disabled as it causes more problems.
9818 * model=auto should work fine now
9819 */
9820 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9821
5795b9e6 9822 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9823
febe3375 9824 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9825 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9826 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9827 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9828 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9829 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9830
9831 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9832 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9833 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9834 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9835 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9836 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9837 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9838 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9839 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9840 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9841 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9842
9843 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9844 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9845 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9846 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9847 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9848 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9849 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9850 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9851 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9852
6f3bf657 9853 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9854 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9855 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9856 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9857 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9858 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9859 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9860 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9861 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9862 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9863 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9864 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9865 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9866 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9867 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9868 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9869 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9870 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9871 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9872 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9873 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9874 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9875 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9876 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9877 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9878 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9879 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9880 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9881 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9882 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9883 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9884
ac3e3741 9885 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9886 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9887 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9888 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9889 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9890 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9891 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9892 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9893 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9894 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9895 ALC883_FUJITSU_PI2515),
bfb53037 9896 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9897 ALC888_FUJITSU_XA3530),
272a527c 9898 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9899 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9900 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9901 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9902 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9903 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9904 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9905 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9906
17bba1b7
J
9907 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9908 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9909 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9910 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9911 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9912 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9913 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9914
4953550a 9915 {}
f3cd3f5d
WF
9916};
9917
4953550a
TI
9918/* codec SSID table for Intel Mac */
9919static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9920 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9921 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9922 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9923 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9924 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9925 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9926 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9927 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9928 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9929 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9930 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9931 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9932 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9933 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9934 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9935 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9936 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9937 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9938 * so apparently no perfect solution yet
4953550a
TI
9939 */
9940 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9941 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9942 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9943 {} /* terminator */
b25c9da1
WF
9944};
9945
4953550a
TI
9946static struct alc_config_preset alc882_presets[] = {
9947 [ALC882_3ST_DIG] = {
9948 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9949 .init_verbs = { alc882_base_init_verbs,
9950 alc882_adc1_init_verbs },
4953550a
TI
9951 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9952 .dac_nids = alc882_dac_nids,
9953 .dig_out_nid = ALC882_DIGOUT_NID,
9954 .dig_in_nid = ALC882_DIGIN_NID,
9955 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9956 .channel_mode = alc882_ch_modes,
9957 .need_dac_fix = 1,
9958 .input_mux = &alc882_capture_source,
9959 },
9960 [ALC882_6ST_DIG] = {
9961 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9962 .init_verbs = { alc882_base_init_verbs,
9963 alc882_adc1_init_verbs },
4953550a
TI
9964 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9965 .dac_nids = alc882_dac_nids,
9966 .dig_out_nid = ALC882_DIGOUT_NID,
9967 .dig_in_nid = ALC882_DIGIN_NID,
9968 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9969 .channel_mode = alc882_sixstack_modes,
9970 .input_mux = &alc882_capture_source,
9971 },
9972 [ALC882_ARIMA] = {
9973 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9974 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9975 alc882_eapd_verbs },
4953550a
TI
9976 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9977 .dac_nids = alc882_dac_nids,
9978 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9979 .channel_mode = alc882_sixstack_modes,
9980 .input_mux = &alc882_capture_source,
9981 },
9982 [ALC882_W2JC] = {
9983 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9984 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9985 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9986 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9987 .dac_nids = alc882_dac_nids,
9988 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9989 .channel_mode = alc880_threestack_modes,
9990 .need_dac_fix = 1,
9991 .input_mux = &alc882_capture_source,
9992 .dig_out_nid = ALC882_DIGOUT_NID,
9993 },
76e6f5a9
RH
9994 [ALC885_MBA21] = {
9995 .mixers = { alc885_mba21_mixer },
9996 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9997 .num_dacs = 2,
9998 .dac_nids = alc882_dac_nids,
9999 .channel_mode = alc885_mba21_ch_modes,
10000 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10001 .input_mux = &alc882_capture_source,
10002 .unsol_event = alc_automute_amp_unsol_event,
10003 .setup = alc885_mba21_setup,
10004 .init_hook = alc_automute_amp,
10005 },
4953550a
TI
10006 [ALC885_MBP3] = {
10007 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10008 .init_verbs = { alc885_mbp3_init_verbs,
10009 alc880_gpio1_init_verbs },
be0ae923 10010 .num_dacs = 2,
4953550a 10011 .dac_nids = alc882_dac_nids,
be0ae923
TI
10012 .hp_nid = 0x04,
10013 .channel_mode = alc885_mbp_4ch_modes,
10014 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10015 .input_mux = &alc882_capture_source,
10016 .dig_out_nid = ALC882_DIGOUT_NID,
10017 .dig_in_nid = ALC882_DIGIN_NID,
10018 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10019 .setup = alc885_mbp3_setup,
10020 .init_hook = alc_automute_amp,
4953550a
TI
10021 },
10022 [ALC885_MB5] = {
10023 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10024 .init_verbs = { alc885_mb5_init_verbs,
10025 alc880_gpio1_init_verbs },
10026 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10027 .dac_nids = alc882_dac_nids,
10028 .channel_mode = alc885_mb5_6ch_modes,
10029 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10030 .input_mux = &mb5_capture_source,
10031 .dig_out_nid = ALC882_DIGOUT_NID,
10032 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10033 .unsol_event = alc_automute_amp_unsol_event,
10034 .setup = alc885_mb5_setup,
10035 .init_hook = alc_automute_amp,
4953550a 10036 },
e458b1fa
LY
10037 [ALC885_MACMINI3] = {
10038 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10039 .init_verbs = { alc885_macmini3_init_verbs,
10040 alc880_gpio1_init_verbs },
10041 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10042 .dac_nids = alc882_dac_nids,
10043 .channel_mode = alc885_macmini3_6ch_modes,
10044 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10045 .input_mux = &macmini3_capture_source,
10046 .dig_out_nid = ALC882_DIGOUT_NID,
10047 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10048 .unsol_event = alc_automute_amp_unsol_event,
10049 .setup = alc885_macmini3_setup,
10050 .init_hook = alc_automute_amp,
e458b1fa 10051 },
4953550a
TI
10052 [ALC885_MACPRO] = {
10053 .mixers = { alc882_macpro_mixer },
10054 .init_verbs = { alc882_macpro_init_verbs },
10055 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10056 .dac_nids = alc882_dac_nids,
10057 .dig_out_nid = ALC882_DIGOUT_NID,
10058 .dig_in_nid = ALC882_DIGIN_NID,
10059 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10060 .channel_mode = alc882_ch_modes,
10061 .input_mux = &alc882_capture_source,
10062 .init_hook = alc885_macpro_init_hook,
10063 },
10064 [ALC885_IMAC24] = {
10065 .mixers = { alc885_imac24_mixer },
10066 .init_verbs = { alc885_imac24_init_verbs },
10067 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10068 .dac_nids = alc882_dac_nids,
10069 .dig_out_nid = ALC882_DIGOUT_NID,
10070 .dig_in_nid = ALC882_DIGIN_NID,
10071 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10072 .channel_mode = alc882_ch_modes,
10073 .input_mux = &alc882_capture_source,
10074 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 10075 .setup = alc885_imac24_setup,
4953550a
TI
10076 .init_hook = alc885_imac24_init_hook,
10077 },
4b7e1803 10078 [ALC885_IMAC91] = {
b7cccc52 10079 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10080 .init_verbs = { alc885_imac91_init_verbs,
10081 alc880_gpio1_init_verbs },
10082 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10083 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10084 .channel_mode = alc885_mba21_ch_modes,
10085 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10086 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10087 .dig_out_nid = ALC882_DIGOUT_NID,
10088 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10089 .unsol_event = alc_automute_amp_unsol_event,
10090 .setup = alc885_imac91_setup,
10091 .init_hook = alc_automute_amp,
4b7e1803 10092 },
4953550a
TI
10093 [ALC882_TARGA] = {
10094 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10095 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10096 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10097 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10098 .dac_nids = alc882_dac_nids,
10099 .dig_out_nid = ALC882_DIGOUT_NID,
10100 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10101 .adc_nids = alc882_adc_nids,
10102 .capsrc_nids = alc882_capsrc_nids,
10103 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10104 .channel_mode = alc882_3ST_6ch_modes,
10105 .need_dac_fix = 1,
10106 .input_mux = &alc882_capture_source,
10107 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10108 .setup = alc882_targa_setup,
10109 .init_hook = alc882_targa_automute,
4953550a
TI
10110 },
10111 [ALC882_ASUS_A7J] = {
10112 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10113 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10114 alc882_asus_a7j_verbs},
4953550a
TI
10115 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10116 .dac_nids = alc882_dac_nids,
10117 .dig_out_nid = ALC882_DIGOUT_NID,
10118 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10119 .adc_nids = alc882_adc_nids,
10120 .capsrc_nids = alc882_capsrc_nids,
10121 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10122 .channel_mode = alc882_3ST_6ch_modes,
10123 .need_dac_fix = 1,
10124 .input_mux = &alc882_capture_source,
10125 },
10126 [ALC882_ASUS_A7M] = {
10127 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10128 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10129 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10130 alc882_asus_a7m_verbs },
10131 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10132 .dac_nids = alc882_dac_nids,
10133 .dig_out_nid = ALC882_DIGOUT_NID,
10134 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10135 .channel_mode = alc880_threestack_modes,
10136 .need_dac_fix = 1,
10137 .input_mux = &alc882_capture_source,
10138 },
9c7f852e
TI
10139 [ALC883_3ST_2ch_DIG] = {
10140 .mixers = { alc883_3ST_2ch_mixer },
10141 .init_verbs = { alc883_init_verbs },
10142 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10143 .dac_nids = alc883_dac_nids,
10144 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10145 .dig_in_nid = ALC883_DIGIN_NID,
10146 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10147 .channel_mode = alc883_3ST_2ch_modes,
10148 .input_mux = &alc883_capture_source,
10149 },
10150 [ALC883_3ST_6ch_DIG] = {
10151 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10152 .init_verbs = { alc883_init_verbs },
10153 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10154 .dac_nids = alc883_dac_nids,
10155 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10156 .dig_in_nid = ALC883_DIGIN_NID,
10157 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10158 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10159 .need_dac_fix = 1,
9c7f852e 10160 .input_mux = &alc883_capture_source,
f12ab1e0 10161 },
9c7f852e
TI
10162 [ALC883_3ST_6ch] = {
10163 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10164 .init_verbs = { alc883_init_verbs },
10165 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10166 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10167 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10168 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10169 .need_dac_fix = 1,
9c7f852e 10170 .input_mux = &alc883_capture_source,
f12ab1e0 10171 },
17bba1b7
J
10172 [ALC883_3ST_6ch_INTEL] = {
10173 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10174 .init_verbs = { alc883_init_verbs },
10175 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10176 .dac_nids = alc883_dac_nids,
10177 .dig_out_nid = ALC883_DIGOUT_NID,
10178 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10179 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10180 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10181 .channel_mode = alc883_3ST_6ch_intel_modes,
10182 .need_dac_fix = 1,
10183 .input_mux = &alc883_3stack_6ch_intel,
10184 },
87a8c370
JK
10185 [ALC889A_INTEL] = {
10186 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10187 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10188 alc_hp15_unsol_verbs },
87a8c370
JK
10189 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10190 .dac_nids = alc883_dac_nids,
10191 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10192 .adc_nids = alc889_adc_nids,
10193 .dig_out_nid = ALC883_DIGOUT_NID,
10194 .dig_in_nid = ALC883_DIGIN_NID,
10195 .slave_dig_outs = alc883_slave_dig_outs,
10196 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10197 .channel_mode = alc889_8ch_intel_modes,
10198 .capsrc_nids = alc889_capsrc_nids,
10199 .input_mux = &alc889_capture_source,
4f5d1706
TI
10200 .setup = alc889_automute_setup,
10201 .init_hook = alc_automute_amp,
6732bd0d 10202 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10203 .need_dac_fix = 1,
10204 },
10205 [ALC889_INTEL] = {
10206 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10207 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10208 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10209 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10210 .dac_nids = alc883_dac_nids,
10211 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10212 .adc_nids = alc889_adc_nids,
10213 .dig_out_nid = ALC883_DIGOUT_NID,
10214 .dig_in_nid = ALC883_DIGIN_NID,
10215 .slave_dig_outs = alc883_slave_dig_outs,
10216 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10217 .channel_mode = alc889_8ch_intel_modes,
10218 .capsrc_nids = alc889_capsrc_nids,
10219 .input_mux = &alc889_capture_source,
4f5d1706 10220 .setup = alc889_automute_setup,
6732bd0d
WF
10221 .init_hook = alc889_intel_init_hook,
10222 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10223 .need_dac_fix = 1,
10224 },
9c7f852e
TI
10225 [ALC883_6ST_DIG] = {
10226 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10227 .init_verbs = { alc883_init_verbs },
10228 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10229 .dac_nids = alc883_dac_nids,
10230 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10231 .dig_in_nid = ALC883_DIGIN_NID,
10232 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10233 .channel_mode = alc883_sixstack_modes,
10234 .input_mux = &alc883_capture_source,
10235 },
ccc656ce 10236 [ALC883_TARGA_DIG] = {
c259249f 10237 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10238 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10239 alc883_targa_verbs},
ccc656ce
KY
10240 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10241 .dac_nids = alc883_dac_nids,
10242 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10243 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10244 .channel_mode = alc883_3ST_6ch_modes,
10245 .need_dac_fix = 1,
10246 .input_mux = &alc883_capture_source,
c259249f 10247 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10248 .setup = alc882_targa_setup,
10249 .init_hook = alc882_targa_automute,
ccc656ce
KY
10250 },
10251 [ALC883_TARGA_2ch_DIG] = {
c259249f 10252 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10253 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10254 alc883_targa_verbs},
ccc656ce
KY
10255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10257 .adc_nids = alc883_adc_nids_alt,
10258 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10259 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10260 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10261 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10262 .channel_mode = alc883_3ST_2ch_modes,
10263 .input_mux = &alc883_capture_source,
c259249f 10264 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10265 .setup = alc882_targa_setup,
10266 .init_hook = alc882_targa_automute,
ccc656ce 10267 },
64a8be74 10268 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10269 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10270 alc883_chmode_mixer },
64a8be74 10271 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10272 alc883_targa_verbs },
64a8be74
DH
10273 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10274 .dac_nids = alc883_dac_nids,
10275 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10276 .adc_nids = alc883_adc_nids_rev,
10277 .capsrc_nids = alc883_capsrc_nids_rev,
10278 .dig_out_nid = ALC883_DIGOUT_NID,
10279 .dig_in_nid = ALC883_DIGIN_NID,
10280 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10281 .channel_mode = alc883_4ST_8ch_modes,
10282 .need_dac_fix = 1,
10283 .input_mux = &alc883_capture_source,
c259249f 10284 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10285 .setup = alc882_targa_setup,
10286 .init_hook = alc882_targa_automute,
64a8be74 10287 },
bab282b9 10288 [ALC883_ACER] = {
676a9b53 10289 .mixers = { alc883_base_mixer },
bab282b9
VA
10290 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10291 * and the headphone jack. Turn this on and rely on the
10292 * standard mute methods whenever the user wants to turn
10293 * these outputs off.
10294 */
10295 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10296 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10297 .dac_nids = alc883_dac_nids,
bab282b9
VA
10298 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10299 .channel_mode = alc883_3ST_2ch_modes,
10300 .input_mux = &alc883_capture_source,
10301 },
2880a867 10302 [ALC883_ACER_ASPIRE] = {
676a9b53 10303 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10304 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10305 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10306 .dac_nids = alc883_dac_nids,
10307 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10308 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10309 .channel_mode = alc883_3ST_2ch_modes,
10310 .input_mux = &alc883_capture_source,
a9fd4f3f 10311 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10312 .setup = alc883_acer_aspire_setup,
10313 .init_hook = alc_automute_amp,
d1a991a6 10314 },
5b2d1eca 10315 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10316 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10317 alc883_chmode_mixer },
10318 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10319 alc888_acer_aspire_4930g_verbs },
10320 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10321 .dac_nids = alc883_dac_nids,
10322 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10323 .adc_nids = alc883_adc_nids_rev,
10324 .capsrc_nids = alc883_capsrc_nids_rev,
10325 .dig_out_nid = ALC883_DIGOUT_NID,
10326 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10327 .channel_mode = alc883_3ST_6ch_modes,
10328 .need_dac_fix = 1,
973b8cb0 10329 .const_channel_count = 6,
5b2d1eca 10330 .num_mux_defs =
ef8ef5fb
VP
10331 ARRAY_SIZE(alc888_2_capture_sources),
10332 .input_mux = alc888_2_capture_sources,
d2fd4b09 10333 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10334 .setup = alc888_acer_aspire_4930g_setup,
10335 .init_hook = alc_automute_amp,
d2fd4b09
TV
10336 },
10337 [ALC888_ACER_ASPIRE_6530G] = {
10338 .mixers = { alc888_acer_aspire_6530_mixer },
10339 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10340 alc888_acer_aspire_6530g_verbs },
10341 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10342 .dac_nids = alc883_dac_nids,
10343 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10344 .adc_nids = alc883_adc_nids_rev,
10345 .capsrc_nids = alc883_capsrc_nids_rev,
10346 .dig_out_nid = ALC883_DIGOUT_NID,
10347 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10348 .channel_mode = alc883_3ST_2ch_modes,
10349 .num_mux_defs =
10350 ARRAY_SIZE(alc888_2_capture_sources),
10351 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10352 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10353 .setup = alc888_acer_aspire_6530g_setup,
10354 .init_hook = alc_automute_amp,
5b2d1eca 10355 },
3b315d70 10356 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10357 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10358 alc883_chmode_mixer },
10359 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10360 alc889_acer_aspire_8930g_verbs,
10361 alc889_eapd_verbs},
3b315d70
HM
10362 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10363 .dac_nids = alc883_dac_nids,
018df418
HM
10364 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10365 .adc_nids = alc889_adc_nids,
10366 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10367 .dig_out_nid = ALC883_DIGOUT_NID,
10368 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10369 .channel_mode = alc883_3ST_6ch_modes,
10370 .need_dac_fix = 1,
10371 .const_channel_count = 6,
10372 .num_mux_defs =
018df418
HM
10373 ARRAY_SIZE(alc889_capture_sources),
10374 .input_mux = alc889_capture_sources,
3b315d70 10375 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10376 .setup = alc889_acer_aspire_8930g_setup,
10377 .init_hook = alc_automute_amp,
f5de24b0 10378#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10379 .power_hook = alc_power_eapd,
f5de24b0 10380#endif
3b315d70 10381 },
fc86f954
DK
10382 [ALC888_ACER_ASPIRE_7730G] = {
10383 .mixers = { alc883_3ST_6ch_mixer,
10384 alc883_chmode_mixer },
10385 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10386 alc888_acer_aspire_7730G_verbs },
10387 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10388 .dac_nids = alc883_dac_nids,
10389 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10390 .adc_nids = alc883_adc_nids_rev,
10391 .capsrc_nids = alc883_capsrc_nids_rev,
10392 .dig_out_nid = ALC883_DIGOUT_NID,
10393 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10394 .channel_mode = alc883_3ST_6ch_modes,
10395 .need_dac_fix = 1,
10396 .const_channel_count = 6,
10397 .input_mux = &alc883_capture_source,
10398 .unsol_event = alc_automute_amp_unsol_event,
d9477207 10399 .setup = alc888_acer_aspire_7730g_setup,
fc86f954
DK
10400 .init_hook = alc_automute_amp,
10401 },
c07584c8
TD
10402 [ALC883_MEDION] = {
10403 .mixers = { alc883_fivestack_mixer,
10404 alc883_chmode_mixer },
10405 .init_verbs = { alc883_init_verbs,
b373bdeb 10406 alc883_medion_eapd_verbs },
c07584c8
TD
10407 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10408 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10409 .adc_nids = alc883_adc_nids_alt,
10410 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10411 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10412 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10413 .channel_mode = alc883_sixstack_modes,
10414 .input_mux = &alc883_capture_source,
b373bdeb 10415 },
7ad7b218
MC
10416 [ALC883_MEDION_WIM2160] = {
10417 .mixers = { alc883_medion_wim2160_mixer },
10418 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10419 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10420 .dac_nids = alc883_dac_nids,
10421 .dig_out_nid = ALC883_DIGOUT_NID,
10422 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10423 .adc_nids = alc883_adc_nids,
10424 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10425 .channel_mode = alc883_3ST_2ch_modes,
10426 .input_mux = &alc883_capture_source,
10427 .unsol_event = alc_automute_amp_unsol_event,
10428 .setup = alc883_medion_wim2160_setup,
10429 .init_hook = alc_automute_amp,
10430 },
b373bdeb 10431 [ALC883_LAPTOP_EAPD] = {
676a9b53 10432 .mixers = { alc883_base_mixer },
b373bdeb
AN
10433 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10434 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10435 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10436 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10437 .channel_mode = alc883_3ST_2ch_modes,
10438 .input_mux = &alc883_capture_source,
10439 },
a65cc60f 10440 [ALC883_CLEVO_M540R] = {
10441 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10442 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10443 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10444 .dac_nids = alc883_dac_nids,
10445 .dig_out_nid = ALC883_DIGOUT_NID,
10446 .dig_in_nid = ALC883_DIGIN_NID,
10447 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10448 .channel_mode = alc883_3ST_6ch_clevo_modes,
10449 .need_dac_fix = 1,
10450 .input_mux = &alc883_capture_source,
10451 /* This machine has the hardware HP auto-muting, thus
10452 * we need no software mute via unsol event
10453 */
10454 },
0c4cc443
HRK
10455 [ALC883_CLEVO_M720] = {
10456 .mixers = { alc883_clevo_m720_mixer },
10457 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10458 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10459 .dac_nids = alc883_dac_nids,
10460 .dig_out_nid = ALC883_DIGOUT_NID,
10461 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10462 .channel_mode = alc883_3ST_2ch_modes,
10463 .input_mux = &alc883_capture_source,
0c4cc443 10464 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10465 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10466 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10467 },
bc9f98a9
KY
10468 [ALC883_LENOVO_101E_2ch] = {
10469 .mixers = { alc883_lenovo_101e_2ch_mixer},
10470 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10471 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10472 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10473 .adc_nids = alc883_adc_nids_alt,
10474 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10475 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10476 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10477 .channel_mode = alc883_3ST_2ch_modes,
10478 .input_mux = &alc883_lenovo_101e_capture_source,
10479 .unsol_event = alc883_lenovo_101e_unsol_event,
10480 .init_hook = alc883_lenovo_101e_all_automute,
10481 },
272a527c
KY
10482 [ALC883_LENOVO_NB0763] = {
10483 .mixers = { alc883_lenovo_nb0763_mixer },
10484 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10485 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10486 .dac_nids = alc883_dac_nids,
272a527c
KY
10487 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10488 .channel_mode = alc883_3ST_2ch_modes,
10489 .need_dac_fix = 1,
10490 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10491 .unsol_event = alc_automute_amp_unsol_event,
dc427170 10492 .setup = alc883_lenovo_nb0763_setup,
4f5d1706 10493 .init_hook = alc_automute_amp,
272a527c
KY
10494 },
10495 [ALC888_LENOVO_MS7195_DIG] = {
10496 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10497 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10498 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10499 .dac_nids = alc883_dac_nids,
10500 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10501 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10502 .channel_mode = alc883_3ST_6ch_modes,
10503 .need_dac_fix = 1,
10504 .input_mux = &alc883_capture_source,
10505 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10506 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10507 },
10508 [ALC883_HAIER_W66] = {
c259249f 10509 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10510 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10511 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10512 .dac_nids = alc883_dac_nids,
10513 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10514 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10515 .channel_mode = alc883_3ST_2ch_modes,
10516 .input_mux = &alc883_capture_source,
a9fd4f3f 10517 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10518 .setup = alc883_haier_w66_setup,
10519 .init_hook = alc_automute_amp,
eea6419e 10520 },
4723c022 10521 [ALC888_3ST_HP] = {
eea6419e 10522 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10523 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525 .dac_nids = alc883_dac_nids,
4723c022
CM
10526 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10527 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10528 .need_dac_fix = 1,
10529 .input_mux = &alc883_capture_source,
a9fd4f3f 10530 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10531 .setup = alc888_3st_hp_setup,
10532 .init_hook = alc_automute_amp,
8341de60 10533 },
5795b9e6 10534 [ALC888_6ST_DELL] = {
f24dbdc6 10535 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10536 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10537 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10538 .dac_nids = alc883_dac_nids,
10539 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10540 .dig_in_nid = ALC883_DIGIN_NID,
10541 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10542 .channel_mode = alc883_sixstack_modes,
10543 .input_mux = &alc883_capture_source,
a9fd4f3f 10544 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10545 .setup = alc888_6st_dell_setup,
10546 .init_hook = alc_automute_amp,
5795b9e6 10547 },
a8848bd6
AS
10548 [ALC883_MITAC] = {
10549 .mixers = { alc883_mitac_mixer },
10550 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10551 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10552 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10553 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10554 .channel_mode = alc883_3ST_2ch_modes,
10555 .input_mux = &alc883_capture_source,
a9fd4f3f 10556 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10557 .setup = alc883_mitac_setup,
10558 .init_hook = alc_automute_amp,
a8848bd6 10559 },
fb97dc67
J
10560 [ALC883_FUJITSU_PI2515] = {
10561 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10562 .init_verbs = { alc883_init_verbs,
10563 alc883_2ch_fujitsu_pi2515_verbs},
10564 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10565 .dac_nids = alc883_dac_nids,
10566 .dig_out_nid = ALC883_DIGOUT_NID,
10567 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10568 .channel_mode = alc883_3ST_2ch_modes,
10569 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10570 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10571 .setup = alc883_2ch_fujitsu_pi2515_setup,
10572 .init_hook = alc_automute_amp,
fb97dc67 10573 },
ef8ef5fb
VP
10574 [ALC888_FUJITSU_XA3530] = {
10575 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10576 .init_verbs = { alc883_init_verbs,
10577 alc888_fujitsu_xa3530_verbs },
10578 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10579 .dac_nids = alc883_dac_nids,
10580 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10581 .adc_nids = alc883_adc_nids_rev,
10582 .capsrc_nids = alc883_capsrc_nids_rev,
10583 .dig_out_nid = ALC883_DIGOUT_NID,
10584 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10585 .channel_mode = alc888_4ST_8ch_intel_modes,
10586 .num_mux_defs =
10587 ARRAY_SIZE(alc888_2_capture_sources),
10588 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10589 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10590 .setup = alc888_fujitsu_xa3530_setup,
10591 .init_hook = alc_automute_amp,
ef8ef5fb 10592 },
e2757d5e
KY
10593 [ALC888_LENOVO_SKY] = {
10594 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10595 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10596 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10597 .dac_nids = alc883_dac_nids,
10598 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10599 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10600 .channel_mode = alc883_sixstack_modes,
10601 .need_dac_fix = 1,
10602 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10603 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10604 .setup = alc888_lenovo_sky_setup,
10605 .init_hook = alc_automute_amp,
e2757d5e
KY
10606 },
10607 [ALC888_ASUS_M90V] = {
10608 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10609 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10610 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10611 .dac_nids = alc883_dac_nids,
10612 .dig_out_nid = ALC883_DIGOUT_NID,
10613 .dig_in_nid = ALC883_DIGIN_NID,
10614 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10615 .channel_mode = alc883_3ST_6ch_modes,
10616 .need_dac_fix = 1,
10617 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10618 .unsol_event = alc_sku_unsol_event,
10619 .setup = alc883_mode2_setup,
10620 .init_hook = alc_inithook,
e2757d5e
KY
10621 },
10622 [ALC888_ASUS_EEE1601] = {
10623 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10624 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10625 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10626 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10627 .dac_nids = alc883_dac_nids,
10628 .dig_out_nid = ALC883_DIGOUT_NID,
10629 .dig_in_nid = ALC883_DIGIN_NID,
10630 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10631 .channel_mode = alc883_3ST_2ch_modes,
10632 .need_dac_fix = 1,
10633 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10634 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10635 .init_hook = alc883_eee1601_inithook,
10636 },
3ab90935
WF
10637 [ALC1200_ASUS_P5Q] = {
10638 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10639 .init_verbs = { alc883_init_verbs },
10640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10641 .dac_nids = alc883_dac_nids,
10642 .dig_out_nid = ALC1200_DIGOUT_NID,
10643 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10644 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10645 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10646 .channel_mode = alc883_sixstack_modes,
10647 .input_mux = &alc883_capture_source,
10648 },
eb4c41d3
TS
10649 [ALC889A_MB31] = {
10650 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10651 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10652 alc880_gpio1_init_verbs },
10653 .adc_nids = alc883_adc_nids,
10654 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10655 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10656 .dac_nids = alc883_dac_nids,
10657 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10658 .channel_mode = alc889A_mb31_6ch_modes,
10659 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10660 .input_mux = &alc889A_mb31_capture_source,
10661 .dig_out_nid = ALC883_DIGOUT_NID,
10662 .unsol_event = alc889A_mb31_unsol_event,
10663 .init_hook = alc889A_mb31_automute,
10664 },
3e1647c5
GG
10665 [ALC883_SONY_VAIO_TT] = {
10666 .mixers = { alc883_vaiott_mixer },
10667 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10668 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10669 .dac_nids = alc883_dac_nids,
10670 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10671 .channel_mode = alc883_3ST_2ch_modes,
10672 .input_mux = &alc883_capture_source,
10673 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10674 .setup = alc883_vaiott_setup,
10675 .init_hook = alc_automute_amp,
3e1647c5 10676 },
9c7f852e
TI
10677};
10678
10679
4953550a
TI
10680/*
10681 * Pin config fixes
10682 */
10683enum {
954a29c8 10684 PINFIX_ABIT_AW9D_MAX,
32eea388 10685 PINFIX_LENOVO_Y530,
954a29c8 10686 PINFIX_PB_M5210,
c3d226ab 10687 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10688};
10689
f8f25ba3
TI
10690static const struct alc_fixup alc882_fixups[] = {
10691 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10692 .type = ALC_FIXUP_PINS,
10693 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10694 { 0x15, 0x01080104 }, /* side */
10695 { 0x16, 0x01011012 }, /* rear */
10696 { 0x17, 0x01016011 }, /* clfe */
10697 { }
10698 }
f8f25ba3 10699 },
32eea388
DH
10700 [PINFIX_LENOVO_Y530] = {
10701 .type = ALC_FIXUP_PINS,
10702 .v.pins = (const struct alc_pincfg[]) {
10703 { 0x15, 0x99130112 }, /* rear int speakers */
10704 { 0x16, 0x99130111 }, /* subwoofer */
10705 { }
10706 }
10707 },
954a29c8 10708 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10709 .type = ALC_FIXUP_VERBS,
10710 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10711 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10712 {}
10713 }
954a29c8 10714 },
c3d226ab 10715 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10716 .type = ALC_FIXUP_SKU,
10717 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10718 },
4953550a
TI
10719};
10720
f8f25ba3 10721static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10722 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10723 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10724 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10725 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10726 {}
10727};
10728
9c7f852e
TI
10729/*
10730 * BIOS auto configuration
10731 */
05f5f477
TI
10732static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10733 const struct auto_pin_cfg *cfg)
10734{
10735 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10736}
10737
4953550a 10738static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10739 hda_nid_t nid, int pin_type,
489008cd 10740 hda_nid_t dac)
9c7f852e 10741{
f12ab1e0
TI
10742 int idx;
10743
489008cd 10744 /* set as output */
f6c7e546 10745 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10746
10747 if (dac == 0x25)
9c7f852e 10748 idx = 4;
489008cd
TI
10749 else if (dac >= 0x02 && dac <= 0x05)
10750 idx = dac - 2;
f9700d5a 10751 else
489008cd 10752 return;
9c7f852e 10753 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10754}
10755
4953550a 10756static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10757{
10758 struct alc_spec *spec = codec->spec;
10759 int i;
10760
10761 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10762 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10763 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10764 if (nid)
4953550a 10765 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10766 spec->multiout.dac_nids[i]);
9c7f852e
TI
10767 }
10768}
10769
4953550a 10770static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10771{
10772 struct alc_spec *spec = codec->spec;
489008cd 10773 hda_nid_t pin, dac;
5855fb80 10774 int i;
9c7f852e 10775
0a3fabe3
DH
10776 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
10777 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10778 pin = spec->autocfg.hp_pins[i];
10779 if (!pin)
10780 break;
10781 dac = spec->multiout.hp_nid;
10782 if (!dac)
10783 dac = spec->multiout.dac_nids[0]; /* to front */
10784 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10785 }
489008cd 10786 }
0a3fabe3
DH
10787
10788 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
10789 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10790 pin = spec->autocfg.speaker_pins[i];
10791 if (!pin)
10792 break;
10793 dac = spec->multiout.extra_out_nid[0];
10794 if (!dac)
10795 dac = spec->multiout.dac_nids[0]; /* to front */
10796 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10797 }
489008cd 10798 }
9c7f852e
TI
10799}
10800
4953550a 10801static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10802{
10803 struct alc_spec *spec = codec->spec;
66ceeb6b 10804 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10805 int i;
10806
66ceeb6b
TI
10807 for (i = 0; i < cfg->num_inputs; i++) {
10808 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10809 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10810 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10811 snd_hda_codec_write(codec, nid, 0,
10812 AC_VERB_SET_AMP_GAIN_MUTE,
10813 AMP_OUT_MUTE);
10814 }
10815}
10816
10817static void alc882_auto_init_input_src(struct hda_codec *codec)
10818{
10819 struct alc_spec *spec = codec->spec;
10820 int c;
10821
10822 for (c = 0; c < spec->num_adc_nids; c++) {
10823 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10824 hda_nid_t nid = spec->capsrc_nids[c];
10825 unsigned int mux_idx;
10826 const struct hda_input_mux *imux;
10827 int conns, mute, idx, item;
10828
10829 conns = snd_hda_get_connections(codec, nid, conn_list,
10830 ARRAY_SIZE(conn_list));
10831 if (conns < 0)
10832 continue;
10833 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10834 imux = &spec->input_mux[mux_idx];
5311114d
TI
10835 if (!imux->num_items && mux_idx > 0)
10836 imux = &spec->input_mux[0];
4953550a
TI
10837 for (idx = 0; idx < conns; idx++) {
10838 /* if the current connection is the selected one,
10839 * unmute it as default - otherwise mute it
10840 */
10841 mute = AMP_IN_MUTE(idx);
10842 for (item = 0; item < imux->num_items; item++) {
10843 if (imux->items[item].index == idx) {
10844 if (spec->cur_mux[c] == item)
10845 mute = AMP_IN_UNMUTE(idx);
10846 break;
10847 }
10848 }
10849 /* check if we have a selector or mixer
10850 * we could check for the widget type instead, but
10851 * just check for Amp-In presence (in case of mixer
10852 * without amp-in there is something wrong, this
10853 * function shouldn't be used or capsrc nid is wrong)
10854 */
10855 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10856 snd_hda_codec_write(codec, nid, 0,
10857 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10858 mute);
10859 else if (mute != AMP_IN_MUTE(idx))
10860 snd_hda_codec_write(codec, nid, 0,
10861 AC_VERB_SET_CONNECT_SEL,
10862 idx);
9c7f852e
TI
10863 }
10864 }
10865}
10866
4953550a
TI
10867/* add mic boosts if needed */
10868static int alc_auto_add_mic_boost(struct hda_codec *codec)
10869{
10870 struct alc_spec *spec = codec->spec;
66ceeb6b 10871 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10872 int i, err;
53e8c323 10873 int type_idx = 0;
4953550a 10874 hda_nid_t nid;
5322bf27 10875 const char *prev_label = NULL;
4953550a 10876
66ceeb6b 10877 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10878 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10879 break;
10880 nid = cfg->inputs[i].pin;
10881 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10882 const char *label;
10883 char boost_label[32];
10884
10885 label = hda_get_autocfg_input_label(codec, cfg, i);
10886 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10887 type_idx++;
10888 else
10889 type_idx = 0;
5322bf27
DH
10890 prev_label = label;
10891
10892 snprintf(boost_label, sizeof(boost_label),
10893 "%s Boost Volume", label);
10894 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10895 boost_label, type_idx,
4953550a 10896 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10897 if (err < 0)
10898 return err;
10899 }
4953550a
TI
10900 }
10901 return 0;
10902}
f511b01c 10903
9c7f852e 10904/* almost identical with ALC880 parser... */
4953550a 10905static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10906{
10907 struct alc_spec *spec = codec->spec;
05f5f477 10908 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10909 int err;
9c7f852e 10910
05f5f477
TI
10911 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10912 alc882_ignore);
9c7f852e
TI
10913 if (err < 0)
10914 return err;
05f5f477
TI
10915 if (!spec->autocfg.line_outs)
10916 return 0; /* can't find valid BIOS pin config */
776e184e 10917
05f5f477
TI
10918 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10919 if (err < 0)
10920 return err;
569ed348 10921 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10922 if (err < 0)
10923 return err;
10924 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10925 "Headphone");
05f5f477
TI
10926 if (err < 0)
10927 return err;
10928 err = alc880_auto_create_extra_out(spec,
10929 spec->autocfg.speaker_pins[0],
10930 "Speaker");
10931 if (err < 0)
10932 return err;
05f5f477 10933 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10934 if (err < 0)
10935 return err;
10936
05f5f477
TI
10937 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10938
757899ac 10939 alc_auto_parse_digital(codec);
05f5f477
TI
10940
10941 if (spec->kctls.list)
10942 add_mixer(spec, spec->kctls.list);
10943
10944 add_verb(spec, alc883_auto_init_verbs);
4953550a 10945 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10946 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10947 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10948
05f5f477
TI
10949 spec->num_mux_defs = 1;
10950 spec->input_mux = &spec->private_imux[0];
10951
6227cdce 10952 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10953
10954 err = alc_auto_add_mic_boost(codec);
10955 if (err < 0)
10956 return err;
61b9b9b1 10957
776e184e 10958 return 1; /* config found */
9c7f852e
TI
10959}
10960
10961/* additional initialization for auto-configuration model */
4953550a 10962static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10963{
f6c7e546 10964 struct alc_spec *spec = codec->spec;
4953550a
TI
10965 alc882_auto_init_multi_out(codec);
10966 alc882_auto_init_hp_out(codec);
10967 alc882_auto_init_analog_input(codec);
10968 alc882_auto_init_input_src(codec);
757899ac 10969 alc_auto_init_digital(codec);
f6c7e546 10970 if (spec->unsol_event)
7fb0d78f 10971 alc_inithook(codec);
9c7f852e
TI
10972}
10973
4953550a 10974static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10975{
10976 struct alc_spec *spec;
10977 int err, board_config;
10978
10979 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10980 if (spec == NULL)
10981 return -ENOMEM;
10982
10983 codec->spec = spec;
10984
4953550a
TI
10985 switch (codec->vendor_id) {
10986 case 0x10ec0882:
10987 case 0x10ec0885:
10988 break;
10989 default:
10990 /* ALC883 and variants */
10991 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10992 break;
10993 }
2c3bf9ab 10994
4953550a
TI
10995 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10996 alc882_models,
10997 alc882_cfg_tbl);
10998
10999 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11000 board_config = snd_hda_check_board_codec_sid_config(codec,
11001 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11002
11003 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11004 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11005 codec->chip_name);
11006 board_config = ALC882_AUTO;
9c7f852e
TI
11007 }
11008
b5bfbc67
TI
11009 if (board_config == ALC882_AUTO) {
11010 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11011 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11012 }
4953550a 11013
90622917
DH
11014 alc_auto_parse_customize_define(codec);
11015
4953550a 11016 if (board_config == ALC882_AUTO) {
9c7f852e 11017 /* automatic parse from the BIOS config */
4953550a 11018 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11019 if (err < 0) {
11020 alc_free(codec);
11021 return err;
f12ab1e0 11022 } else if (!err) {
9c7f852e
TI
11023 printk(KERN_INFO
11024 "hda_codec: Cannot set up configuration "
11025 "from BIOS. Using base mode...\n");
4953550a 11026 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11027 }
11028 }
11029
dc1eae25 11030 if (has_cdefine_beep(codec)) {
8af2591d
TI
11031 err = snd_hda_attach_beep_device(codec, 0x1);
11032 if (err < 0) {
11033 alc_free(codec);
11034 return err;
11035 }
680cd536
KK
11036 }
11037
4953550a 11038 if (board_config != ALC882_AUTO)
e9c364c0 11039 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11040
4953550a
TI
11041 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11042 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11043 /* FIXME: setup DAC5 */
11044 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11045 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11046
11047 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11048 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11049
4953550a 11050 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11051 int i, j;
4953550a
TI
11052 spec->num_adc_nids = 0;
11053 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11054 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11055 hda_nid_t cap;
d11f74c6 11056 hda_nid_t items[16];
4953550a
TI
11057 hda_nid_t nid = alc882_adc_nids[i];
11058 unsigned int wcap = get_wcaps(codec, nid);
11059 /* get type */
a22d543a 11060 wcap = get_wcaps_type(wcap);
4953550a
TI
11061 if (wcap != AC_WID_AUD_IN)
11062 continue;
11063 spec->private_adc_nids[spec->num_adc_nids] = nid;
11064 err = snd_hda_get_connections(codec, nid, &cap, 1);
11065 if (err < 0)
11066 continue;
d11f74c6
TI
11067 err = snd_hda_get_connections(codec, cap, items,
11068 ARRAY_SIZE(items));
11069 if (err < 0)
11070 continue;
11071 for (j = 0; j < imux->num_items; j++)
11072 if (imux->items[j].index >= err)
11073 break;
11074 if (j < imux->num_items)
11075 continue;
4953550a
TI
11076 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11077 spec->num_adc_nids++;
61b9b9b1 11078 }
4953550a
TI
11079 spec->adc_nids = spec->private_adc_nids;
11080 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11081 }
11082
b59bdf3b 11083 set_capture_mixer(codec);
da00c244 11084
dc1eae25 11085 if (has_cdefine_beep(codec))
da00c244 11086 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11087
b5bfbc67 11088 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11089
2134ea4f
TI
11090 spec->vmaster_nid = 0x0c;
11091
9c7f852e 11092 codec->patch_ops = alc_patch_ops;
4953550a
TI
11093 if (board_config == ALC882_AUTO)
11094 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11095
11096 alc_init_jacks(codec);
cb53c626
TI
11097#ifdef CONFIG_SND_HDA_POWER_SAVE
11098 if (!spec->loopback.amplist)
4953550a 11099 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11100#endif
9c7f852e
TI
11101
11102 return 0;
11103}
11104
4953550a 11105
9c7f852e
TI
11106/*
11107 * ALC262 support
11108 */
11109
11110#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11111#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11112
11113#define alc262_dac_nids alc260_dac_nids
11114#define alc262_adc_nids alc882_adc_nids
11115#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11116#define alc262_capsrc_nids alc882_capsrc_nids
11117#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11118
11119#define alc262_modes alc260_modes
11120#define alc262_capture_source alc882_capture_source
11121
4e555fe5
KY
11122static hda_nid_t alc262_dmic_adc_nids[1] = {
11123 /* ADC0 */
11124 0x09
11125};
11126
11127static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11128
9c7f852e
TI
11129static struct snd_kcontrol_new alc262_base_mixer[] = {
11130 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11131 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11132 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11133 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11134 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11135 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11138 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11139 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11140 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11141 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11142 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11143 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11144 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11145 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11146 { } /* end */
11147};
11148
ce875f07
TI
11149/* update HP, line and mono-out pins according to the master switch */
11150static void alc262_hp_master_update(struct hda_codec *codec)
11151{
11152 struct alc_spec *spec = codec->spec;
11153 int val = spec->master_sw;
11154
11155 /* HP & line-out */
11156 snd_hda_codec_write_cache(codec, 0x1b, 0,
11157 AC_VERB_SET_PIN_WIDGET_CONTROL,
11158 val ? PIN_HP : 0);
11159 snd_hda_codec_write_cache(codec, 0x15, 0,
11160 AC_VERB_SET_PIN_WIDGET_CONTROL,
11161 val ? PIN_HP : 0);
11162 /* mono (speaker) depending on the HP jack sense */
11163 val = val && !spec->jack_present;
11164 snd_hda_codec_write_cache(codec, 0x16, 0,
11165 AC_VERB_SET_PIN_WIDGET_CONTROL,
11166 val ? PIN_OUT : 0);
11167}
11168
11169static void alc262_hp_bpc_automute(struct hda_codec *codec)
11170{
11171 struct alc_spec *spec = codec->spec;
864f92be
WF
11172
11173 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11174 alc262_hp_master_update(codec);
11175}
11176
11177static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11178{
11179 if ((res >> 26) != ALC880_HP_EVENT)
11180 return;
11181 alc262_hp_bpc_automute(codec);
11182}
11183
11184static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11185{
11186 struct alc_spec *spec = codec->spec;
864f92be
WF
11187
11188 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11189 alc262_hp_master_update(codec);
11190}
11191
11192static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11193 unsigned int res)
11194{
11195 if ((res >> 26) != ALC880_HP_EVENT)
11196 return;
11197 alc262_hp_wildwest_automute(codec);
11198}
11199
b72519b5 11200#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11201
11202static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11203 struct snd_ctl_elem_value *ucontrol)
11204{
11205 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11206 struct alc_spec *spec = codec->spec;
11207 int val = !!*ucontrol->value.integer.value;
11208
11209 if (val == spec->master_sw)
11210 return 0;
11211 spec->master_sw = val;
11212 alc262_hp_master_update(codec);
11213 return 1;
11214}
11215
b72519b5
TI
11216#define ALC262_HP_MASTER_SWITCH \
11217 { \
11218 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11219 .name = "Master Playback Switch", \
11220 .info = snd_ctl_boolean_mono_info, \
11221 .get = alc262_hp_master_sw_get, \
11222 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11223 }, \
11224 { \
11225 .iface = NID_MAPPING, \
11226 .name = "Master Playback Switch", \
11227 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11228 }
11229
5b0cb1d8 11230
9c7f852e 11231static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11232 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11233 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11234 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11235 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11236 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11237 HDA_OUTPUT),
11238 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11239 HDA_OUTPUT),
9c7f852e
TI
11240 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11241 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11242 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11243 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11244 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11245 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11246 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11247 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11248 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11249 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11250 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11251 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11252 { } /* end */
11253};
11254
cd7509a4 11255static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11256 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11257 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11258 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11259 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11260 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11261 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11262 HDA_OUTPUT),
11263 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11264 HDA_OUTPUT),
cd7509a4
KY
11265 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11266 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11267 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11268 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11269 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11270 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11271 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11272 { } /* end */
11273};
11274
11275static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11276 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11277 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11278 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11279 { } /* end */
11280};
11281
66d2a9d6 11282/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11283static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11284{
11285 struct alc_spec *spec = codec->spec;
66d2a9d6 11286
a9fd4f3f 11287 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11288 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11289}
11290
66d2a9d6 11291static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11292 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11293 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11294 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11295 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11297 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11298 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11299 { } /* end */
11300};
11301
11302static struct hda_verb alc262_hp_t5735_verbs[] = {
11303 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11304 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11305
11306 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11307 { }
11308};
11309
8c427226 11310static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11311 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11312 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11313 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11314 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11315 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11316 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11317 { } /* end */
11318};
11319
11320static struct hda_verb alc262_hp_rp5700_verbs[] = {
11321 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11322 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11323 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11324 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11325 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11326 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11327 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11328 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11329 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11330 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11331 {}
11332};
11333
11334static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11335 .num_items = 1,
11336 .items = {
11337 { "Line", 0x1 },
11338 },
11339};
11340
42171c17
TI
11341/* bind hp and internal speaker mute (with plug check) as master switch */
11342static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11343{
42171c17
TI
11344 struct alc_spec *spec = codec->spec;
11345 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11346 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11347 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11348 unsigned int mute;
0724ea2a 11349
42171c17
TI
11350 /* HP */
11351 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11352 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11353 HDA_AMP_MUTE, mute);
11354 /* mute internal speaker per jack sense */
11355 if (spec->jack_present)
11356 mute = HDA_AMP_MUTE;
11357 if (line_nid)
11358 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11359 HDA_AMP_MUTE, mute);
11360 if (speaker_nid && speaker_nid != line_nid)
11361 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11362 HDA_AMP_MUTE, mute);
42171c17
TI
11363}
11364
11365#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11366
11367static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11368 struct snd_ctl_elem_value *ucontrol)
11369{
11370 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11371 struct alc_spec *spec = codec->spec;
11372 int val = !!*ucontrol->value.integer.value;
11373
11374 if (val == spec->master_sw)
11375 return 0;
11376 spec->master_sw = val;
11377 alc262_hippo_master_update(codec);
11378 return 1;
11379}
11380
11381#define ALC262_HIPPO_MASTER_SWITCH \
11382 { \
11383 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11384 .name = "Master Playback Switch", \
11385 .info = snd_ctl_boolean_mono_info, \
11386 .get = alc262_hippo_master_sw_get, \
11387 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11388 }, \
11389 { \
11390 .iface = NID_MAPPING, \
11391 .name = "Master Playback Switch", \
11392 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11393 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11394 }
42171c17
TI
11395
11396static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11397 ALC262_HIPPO_MASTER_SWITCH,
11398 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11399 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11400 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11401 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11402 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11405 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11406 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11407 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11408 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11409 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11410 { } /* end */
11411};
11412
11413static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11414 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11415 ALC262_HIPPO_MASTER_SWITCH,
11416 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11417 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11418 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11419 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11420 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11421 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11422 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11423 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11424 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11425 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11426 { } /* end */
11427};
11428
11429/* mute/unmute internal speaker according to the hp jack and mute state */
11430static void alc262_hippo_automute(struct hda_codec *codec)
11431{
11432 struct alc_spec *spec = codec->spec;
11433 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11434
864f92be 11435 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11436 alc262_hippo_master_update(codec);
0724ea2a 11437}
5b31954e 11438
42171c17
TI
11439static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11440{
11441 if ((res >> 26) != ALC880_HP_EVENT)
11442 return;
11443 alc262_hippo_automute(codec);
11444}
11445
4f5d1706 11446static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11447{
11448 struct alc_spec *spec = codec->spec;
11449
11450 spec->autocfg.hp_pins[0] = 0x15;
11451 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11452}
11453
4f5d1706 11454static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11455{
11456 struct alc_spec *spec = codec->spec;
11457
11458 spec->autocfg.hp_pins[0] = 0x1b;
11459 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11460}
11461
11462
272a527c 11463static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11464 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11465 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11467 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11468 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11469 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11470 { } /* end */
11471};
11472
83c34218 11473static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11474 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11475 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11476 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11477 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11478 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11479 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11480 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11481 { } /* end */
11482};
272a527c 11483
ba340e82
TV
11484static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11485 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11486 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11487 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11488 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11489 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11490 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11491 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11492 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11493 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11494 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11495 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11496 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11497 { } /* end */
11498};
11499
11500static struct hda_verb alc262_tyan_verbs[] = {
11501 /* Headphone automute */
11502 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11503 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11504 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11505
11506 /* P11 AUX_IN, white 4-pin connector */
11507 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11508 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11509 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11510 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11511
11512 {}
11513};
11514
11515/* unsolicited event for HP jack sensing */
4f5d1706 11516static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11517{
a9fd4f3f 11518 struct alc_spec *spec = codec->spec;
ba340e82 11519
a9fd4f3f
TI
11520 spec->autocfg.hp_pins[0] = 0x1b;
11521 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11522}
11523
ba340e82 11524
9c7f852e
TI
11525#define alc262_capture_mixer alc882_capture_mixer
11526#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11527
11528/*
11529 * generic initialization of ADC, input mixers and output mixers
11530 */
11531static struct hda_verb alc262_init_verbs[] = {
11532 /*
11533 * Unmute ADC0-2 and set the default input to mic-in
11534 */
11535 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11537 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11538 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11539 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11541
cb53c626 11542 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11543 * mixer widget
f12ab1e0
TI
11544 * Note: PASD motherboards uses the Line In 2 as the input for
11545 * front panel mic (mic 2)
9c7f852e
TI
11546 */
11547 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11548 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11549 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11550 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11551 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11552 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11553
11554 /*
df694daa
KY
11555 * Set up output mixers (0x0c - 0x0e)
11556 */
11557 /* set vol=0 to output mixers */
11558 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11561 /* set up input amps for analog loopback */
11562 /* Amp Indices: DAC = 0, mixer = 1 */
11563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11564 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11565 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11566 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11567 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11568 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11569
11570 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11572 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11573 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11574 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11575 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11576
11577 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11578 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11579 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11580 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11581 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11582
df694daa
KY
11583 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11584 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11585
df694daa
KY
11586 /* FIXME: use matrix-type input source selection */
11587 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11588 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11589 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11590 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11591 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11592 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11593 /* Input mixer2 */
11594 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11595 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11596 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11597 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11598 /* Input mixer3 */
11599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11600 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11601 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11602 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11603
11604 { }
11605};
1da177e4 11606
4e555fe5
KY
11607static struct hda_verb alc262_eapd_verbs[] = {
11608 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11609 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11610 { }
11611};
11612
ccc656ce
KY
11613static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11614 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11615 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11616 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11617
11618 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11619 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11620 {}
11621};
11622
272a527c
KY
11623static struct hda_verb alc262_sony_unsol_verbs[] = {
11624 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11625 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11626 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11627
11628 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11629 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11630 {}
272a527c
KY
11631};
11632
4e555fe5
KY
11633static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11634 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11635 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11636 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11639 { } /* end */
11640};
11641
11642static struct hda_verb alc262_toshiba_s06_verbs[] = {
11643 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11645 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11646 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11647 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11648 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11649 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11650 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11651 {}
11652};
11653
4f5d1706 11654static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11655{
a9fd4f3f
TI
11656 struct alc_spec *spec = codec->spec;
11657
11658 spec->autocfg.hp_pins[0] = 0x15;
11659 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11660 spec->ext_mic.pin = 0x18;
11661 spec->ext_mic.mux_idx = 0;
11662 spec->int_mic.pin = 0x12;
11663 spec->int_mic.mux_idx = 9;
11664 spec->auto_mic = 1;
4e555fe5
KY
11665}
11666
e8f9ae2a
PT
11667/*
11668 * nec model
11669 * 0x15 = headphone
11670 * 0x16 = internal speaker
11671 * 0x18 = external mic
11672 */
11673
11674static struct snd_kcontrol_new alc262_nec_mixer[] = {
11675 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11676 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11677
11678 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11680 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11681
11682 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11684 { } /* end */
11685};
11686
11687static struct hda_verb alc262_nec_verbs[] = {
11688 /* Unmute Speaker */
11689 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11690
11691 /* Headphone */
11692 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11693 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11694
11695 /* External mic to headphone */
11696 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11697 /* External mic to speaker */
11698 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11699 {}
11700};
11701
834be88d
TI
11702/*
11703 * fujitsu model
5d9fab2d
TV
11704 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11705 * 0x1b = port replicator headphone out
834be88d
TI
11706 */
11707
11708#define ALC_HP_EVENT 0x37
11709
11710static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11711 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11712 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11713 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11714 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11715 {}
11716};
11717
0e31daf7
J
11718static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11719 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11720 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11721 {}
11722};
11723
e2595322
DC
11724static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11725 /* Front Mic pin: input vref at 50% */
11726 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11727 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11728 {}
11729};
11730
834be88d 11731static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11732 .num_items = 3,
834be88d
TI
11733 .items = {
11734 { "Mic", 0x0 },
28c4edb7 11735 { "Internal Mic", 0x1 },
834be88d
TI
11736 { "CD", 0x4 },
11737 },
11738};
11739
9c7f852e
TI
11740static struct hda_input_mux alc262_HP_capture_source = {
11741 .num_items = 5,
11742 .items = {
11743 { "Mic", 0x0 },
accbe498 11744 { "Front Mic", 0x1 },
9c7f852e
TI
11745 { "Line", 0x2 },
11746 { "CD", 0x4 },
11747 { "AUX IN", 0x6 },
11748 },
11749};
11750
accbe498 11751static struct hda_input_mux alc262_HP_D7000_capture_source = {
11752 .num_items = 4,
11753 .items = {
11754 { "Mic", 0x0 },
11755 { "Front Mic", 0x2 },
11756 { "Line", 0x1 },
11757 { "CD", 0x4 },
11758 },
11759};
11760
ebc7a406 11761/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11762static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11763{
11764 struct alc_spec *spec = codec->spec;
11765 unsigned int mute;
11766
f12ab1e0 11767 if (force || !spec->sense_updated) {
864f92be
WF
11768 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11769 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11770 spec->sense_updated = 1;
11771 }
ebc7a406
TI
11772 /* unmute internal speaker only if both HPs are unplugged and
11773 * master switch is on
11774 */
11775 if (spec->jack_present)
11776 mute = HDA_AMP_MUTE;
11777 else
834be88d 11778 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11779 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11780 HDA_AMP_MUTE, mute);
834be88d
TI
11781}
11782
11783/* unsolicited event for HP jack sensing */
11784static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11785 unsigned int res)
11786{
11787 if ((res >> 26) != ALC_HP_EVENT)
11788 return;
11789 alc262_fujitsu_automute(codec, 1);
11790}
11791
ebc7a406
TI
11792static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11793{
11794 alc262_fujitsu_automute(codec, 1);
11795}
11796
834be88d 11797/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11798static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11799 .ops = &snd_hda_bind_vol,
11800 .values = {
11801 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11802 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11803 0
11804 },
11805};
834be88d 11806
0e31daf7
J
11807/* mute/unmute internal speaker according to the hp jack and mute state */
11808static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11809{
11810 struct alc_spec *spec = codec->spec;
11811 unsigned int mute;
11812
11813 if (force || !spec->sense_updated) {
864f92be 11814 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11815 spec->sense_updated = 1;
11816 }
11817 if (spec->jack_present) {
11818 /* mute internal speaker */
11819 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11820 HDA_AMP_MUTE, HDA_AMP_MUTE);
11821 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11822 HDA_AMP_MUTE, HDA_AMP_MUTE);
11823 } else {
11824 /* unmute internal speaker if necessary */
11825 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11826 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11827 HDA_AMP_MUTE, mute);
11828 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11829 HDA_AMP_MUTE, mute);
11830 }
11831}
11832
11833/* unsolicited event for HP jack sensing */
11834static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11835 unsigned int res)
11836{
11837 if ((res >> 26) != ALC_HP_EVENT)
11838 return;
11839 alc262_lenovo_3000_automute(codec, 1);
11840}
11841
8de56b7d
TI
11842static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11843 int dir, int idx, long *valp)
11844{
11845 int i, change = 0;
11846
11847 for (i = 0; i < 2; i++, valp++)
11848 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11849 HDA_AMP_MUTE,
11850 *valp ? 0 : HDA_AMP_MUTE);
11851 return change;
11852}
11853
834be88d
TI
11854/* bind hp and internal speaker mute (with plug check) */
11855static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11856 struct snd_ctl_elem_value *ucontrol)
11857{
11858 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11859 long *valp = ucontrol->value.integer.value;
11860 int change;
11861
8de56b7d
TI
11862 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11863 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11864 if (change)
11865 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11866 return change;
11867}
11868
11869static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11870 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11871 {
11872 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11873 .name = "Master Playback Switch",
5e26dfd0 11874 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11875 .info = snd_hda_mixer_amp_switch_info,
11876 .get = snd_hda_mixer_amp_switch_get,
11877 .put = alc262_fujitsu_master_sw_put,
11878 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11879 },
5b0cb1d8
JK
11880 {
11881 .iface = NID_MAPPING,
11882 .name = "Master Playback Switch",
11883 .private_value = 0x1b,
11884 },
834be88d
TI
11885 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11886 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11887 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11888 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11889 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11890 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11891 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11892 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11893 { } /* end */
11894};
11895
0e31daf7
J
11896/* bind hp and internal speaker mute (with plug check) */
11897static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11898 struct snd_ctl_elem_value *ucontrol)
11899{
11900 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11901 long *valp = ucontrol->value.integer.value;
11902 int change;
11903
8de56b7d 11904 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11905 if (change)
11906 alc262_lenovo_3000_automute(codec, 0);
11907 return change;
11908}
11909
11910static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11911 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11912 {
11913 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11914 .name = "Master Playback Switch",
5e26dfd0 11915 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11916 .info = snd_hda_mixer_amp_switch_info,
11917 .get = snd_hda_mixer_amp_switch_get,
11918 .put = alc262_lenovo_3000_master_sw_put,
11919 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11920 },
11921 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11922 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11923 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11924 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11925 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11926 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11927 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11928 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11929 { } /* end */
11930};
11931
9f99a638
HM
11932static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11933 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11934 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11935 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11937 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11938 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11939 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11940 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11941 { } /* end */
11942};
11943
304dcaac
TI
11944/* additional init verbs for Benq laptops */
11945static struct hda_verb alc262_EAPD_verbs[] = {
11946 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11947 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11948 {}
11949};
11950
83c34218
KY
11951static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11952 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11953 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11954
11955 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11956 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11957 {}
11958};
11959
f651b50b
TD
11960/* Samsung Q1 Ultra Vista model setup */
11961static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11962 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11963 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11964 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11965 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11966 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11967 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11968 { } /* end */
11969};
11970
11971static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11972 /* output mixer */
11973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11974 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11975 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11976 /* speaker */
11977 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11978 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11979 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11980 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11981 /* HP */
f651b50b 11982 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11984 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11985 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11986 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11987 /* internal mic */
11988 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11989 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11990 /* ADC, choose mic */
11991 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11998 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11999 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12000 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12001 {}
12002};
12003
f651b50b
TD
12004/* mute/unmute internal speaker according to the hp jack and mute state */
12005static void alc262_ultra_automute(struct hda_codec *codec)
12006{
12007 struct alc_spec *spec = codec->spec;
12008 unsigned int mute;
f651b50b 12009
bb9f76cd
TI
12010 mute = 0;
12011 /* auto-mute only when HP is used as HP */
12012 if (!spec->cur_mux[0]) {
864f92be 12013 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12014 if (spec->jack_present)
12015 mute = HDA_AMP_MUTE;
f651b50b 12016 }
bb9f76cd
TI
12017 /* mute/unmute internal speaker */
12018 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12019 HDA_AMP_MUTE, mute);
12020 /* mute/unmute HP */
12021 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12022 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12023}
12024
12025/* unsolicited event for HP jack sensing */
12026static void alc262_ultra_unsol_event(struct hda_codec *codec,
12027 unsigned int res)
12028{
12029 if ((res >> 26) != ALC880_HP_EVENT)
12030 return;
12031 alc262_ultra_automute(codec);
12032}
12033
bb9f76cd
TI
12034static struct hda_input_mux alc262_ultra_capture_source = {
12035 .num_items = 2,
12036 .items = {
12037 { "Mic", 0x1 },
12038 { "Headphone", 0x7 },
12039 },
12040};
12041
12042static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12043 struct snd_ctl_elem_value *ucontrol)
12044{
12045 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12046 struct alc_spec *spec = codec->spec;
12047 int ret;
12048
54cbc9ab 12049 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12050 if (!ret)
12051 return 0;
12052 /* reprogram the HP pin as mic or HP according to the input source */
12053 snd_hda_codec_write_cache(codec, 0x15, 0,
12054 AC_VERB_SET_PIN_WIDGET_CONTROL,
12055 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12056 alc262_ultra_automute(codec); /* mute/unmute HP */
12057 return ret;
12058}
12059
12060static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12061 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12062 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12063 {
12064 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12065 .name = "Capture Source",
54cbc9ab
TI
12066 .info = alc_mux_enum_info,
12067 .get = alc_mux_enum_get,
bb9f76cd
TI
12068 .put = alc262_ultra_mux_enum_put,
12069 },
5b0cb1d8
JK
12070 {
12071 .iface = NID_MAPPING,
12072 .name = "Capture Source",
12073 .private_value = 0x15,
12074 },
bb9f76cd
TI
12075 { } /* end */
12076};
12077
c3fc1f50
TI
12078/* We use two mixers depending on the output pin; 0x16 is a mono output
12079 * and thus it's bound with a different mixer.
12080 * This function returns which mixer amp should be used.
12081 */
12082static int alc262_check_volbit(hda_nid_t nid)
12083{
12084 if (!nid)
12085 return 0;
12086 else if (nid == 0x16)
12087 return 2;
12088 else
12089 return 1;
12090}
12091
12092static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12093 const char *pfx, int *vbits, int idx)
c3fc1f50 12094{
c3fc1f50
TI
12095 unsigned long val;
12096 int vbit;
12097
12098 vbit = alc262_check_volbit(nid);
12099 if (!vbit)
12100 return 0;
12101 if (*vbits & vbit) /* a volume control for this mixer already there */
12102 return 0;
12103 *vbits |= vbit;
c3fc1f50
TI
12104 if (vbit == 2)
12105 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12106 else
12107 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12108 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12109}
12110
12111static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12112 const char *pfx, int idx)
c3fc1f50 12113{
c3fc1f50
TI
12114 unsigned long val;
12115
12116 if (!nid)
12117 return 0;
c3fc1f50
TI
12118 if (nid == 0x16)
12119 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12120 else
12121 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12122 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12123}
12124
df694daa 12125/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12126static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12127 const struct auto_pin_cfg *cfg)
df694daa 12128{
c3fc1f50
TI
12129 const char *pfx;
12130 int vbits;
033688a5 12131 int i, err;
df694daa
KY
12132
12133 spec->multiout.num_dacs = 1; /* only use one dac */
12134 spec->multiout.dac_nids = spec->private_dac_nids;
12135 spec->multiout.dac_nids[0] = 2;
12136
bcb2f0f5
TI
12137 pfx = alc_get_line_out_pfx(cfg, true);
12138 if (!pfx)
c3fc1f50 12139 pfx = "Front";
033688a5
TI
12140 for (i = 0; i < 2; i++) {
12141 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12142 if (err < 0)
12143 return err;
12144 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12145 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12146 "Speaker", i);
12147 if (err < 0)
12148 return err;
12149 }
12150 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12151 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12152 "Headphone", i);
12153 if (err < 0)
12154 return err;
12155 }
12156 }
df694daa 12157
c3fc1f50
TI
12158 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12159 alc262_check_volbit(cfg->speaker_pins[0]) |
12160 alc262_check_volbit(cfg->hp_pins[0]);
12161 if (vbits == 1 || vbits == 2)
12162 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12163 vbits = 0;
033688a5
TI
12164 for (i = 0; i < 2; i++) {
12165 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12166 &vbits, i);
12167 if (err < 0)
12168 return err;
12169 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12170 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12171 "Speaker", &vbits, i);
12172 if (err < 0)
12173 return err;
12174 }
12175 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12176 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12177 "Headphone", &vbits, i);
12178 if (err < 0)
12179 return err;
12180 }
12181 }
f12ab1e0 12182 return 0;
df694daa
KY
12183}
12184
05f5f477 12185#define alc262_auto_create_input_ctls \
eaa9b3a7 12186 alc882_auto_create_input_ctls
df694daa
KY
12187
12188/*
12189 * generic initialization of ADC, input mixers and output mixers
12190 */
12191static struct hda_verb alc262_volume_init_verbs[] = {
12192 /*
12193 * Unmute ADC0-2 and set the default input to mic-in
12194 */
12195 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12197 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12198 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12199 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12200 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12201
cb53c626 12202 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12203 * mixer widget
f12ab1e0
TI
12204 * Note: PASD motherboards uses the Line In 2 as the input for
12205 * front panel mic (mic 2)
df694daa
KY
12206 */
12207 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12208 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12209 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12213
12214 /*
12215 * Set up output mixers (0x0c - 0x0f)
12216 */
12217 /* set vol=0 to output mixers */
12218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12219 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12220 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12221
df694daa
KY
12222 /* set up input amps for analog loopback */
12223 /* Amp Indices: DAC = 0, mixer = 1 */
12224 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12225 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12226 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12227 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12228 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12229 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12230
12231 /* FIXME: use matrix-type input source selection */
12232 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12233 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12234 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12235 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12236 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12237 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12238 /* Input mixer2 */
12239 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12243 /* Input mixer3 */
12244 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12245 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12248
12249 { }
12250};
12251
9c7f852e
TI
12252static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12253 /*
12254 * Unmute ADC0-2 and set the default input to mic-in
12255 */
12256 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12258 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12259 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12260 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12261 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12262
cb53c626 12263 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12264 * mixer widget
f12ab1e0
TI
12265 * Note: PASD motherboards uses the Line In 2 as the input for
12266 * front panel mic (mic 2)
9c7f852e
TI
12267 */
12268 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12269 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12270 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12271 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12272 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12273 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12274 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12275 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12276
9c7f852e
TI
12277 /*
12278 * Set up output mixers (0x0c - 0x0e)
12279 */
12280 /* set vol=0 to output mixers */
12281 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12282 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12283 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12284
12285 /* set up input amps for analog loopback */
12286 /* Amp Indices: DAC = 0, mixer = 1 */
12287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12289 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12290 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12291 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12292 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12293
ce875f07 12294 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12296 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12297
12298 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12299 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12300
12301 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12302 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12303
12304 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12305 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12306 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12307 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12308 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12309
0e4835c1 12310 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12311 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12312 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12313 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12314 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12315 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12316
12317
12318 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12319 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12320 /* Input mixer1: only unmute Mic */
9c7f852e 12321 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12322 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12323 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12324 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12325 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12326 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12327 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12328 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12329 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12330 /* Input mixer2 */
12331 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12332 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12333 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12334 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12335 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12336 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12337 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12338 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12339 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12340 /* Input mixer3 */
12341 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12342 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12343 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12344 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12345 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12346 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12347 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12348 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12349 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12350
ce875f07
TI
12351 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12352
9c7f852e
TI
12353 { }
12354};
12355
cd7509a4
KY
12356static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12357 /*
12358 * Unmute ADC0-2 and set the default input to mic-in
12359 */
12360 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12361 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12362 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12363 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12364 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12365 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12366
cb53c626 12367 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12368 * mixer widget
12369 * Note: PASD motherboards uses the Line In 2 as the input for front
12370 * panel mic (mic 2)
12371 */
12372 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12373 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12374 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12375 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12376 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12377 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12378 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12380 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12381 /*
12382 * Set up output mixers (0x0c - 0x0e)
12383 */
12384 /* set vol=0 to output mixers */
12385 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12386 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12387 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12388
12389 /* set up input amps for analog loopback */
12390 /* Amp Indices: DAC = 0, mixer = 1 */
12391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12395 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12397
12398
12399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12400 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12401 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12403 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12405 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12406
12407 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12408 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12409
12410 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12411 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12412
12413 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12414 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12415 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12416 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12417 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12418 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12419
12420 /* FIXME: use matrix-type input source selection */
12421 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12422 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12423 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12424 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12425 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12426 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12428 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12429 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12430 /* Input mixer2 */
12431 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12433 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12434 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12435 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12436 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12437 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12438 /* Input mixer3 */
12439 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12440 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12441 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12442 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12443 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12444 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12445 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12446
ce875f07
TI
12447 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12448
cd7509a4
KY
12449 { }
12450};
12451
9f99a638
HM
12452static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12453
12454 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12455 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12456 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12457
12458 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12459 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12460 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12461 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12462
12463 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12464 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12466 {}
12467};
12468
18675e42
TI
12469/*
12470 * Pin config fixes
12471 */
12472enum {
12473 PINFIX_FSC_H270,
12474};
12475
12476static const struct alc_fixup alc262_fixups[] = {
12477 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12478 .type = ALC_FIXUP_PINS,
12479 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12480 { 0x14, 0x99130110 }, /* speaker */
12481 { 0x15, 0x0221142f }, /* front HP */
12482 { 0x1b, 0x0121141f }, /* rear HP */
12483 { }
12484 }
12485 },
18675e42
TI
12486};
12487
12488static struct snd_pci_quirk alc262_fixup_tbl[] = {
12489 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12490 {}
12491};
12492
9f99a638 12493
cb53c626
TI
12494#ifdef CONFIG_SND_HDA_POWER_SAVE
12495#define alc262_loopbacks alc880_loopbacks
12496#endif
12497
def319f9 12498/* pcm configuration: identical with ALC880 */
df694daa
KY
12499#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12500#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12501#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12502#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12503
12504/*
12505 * BIOS auto configuration
12506 */
12507static int alc262_parse_auto_config(struct hda_codec *codec)
12508{
12509 struct alc_spec *spec = codec->spec;
12510 int err;
12511 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12512
f12ab1e0
TI
12513 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12514 alc262_ignore);
12515 if (err < 0)
df694daa 12516 return err;
e64f14f4 12517 if (!spec->autocfg.line_outs) {
0852d7a6 12518 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12519 spec->multiout.max_channels = 2;
12520 spec->no_analog = 1;
12521 goto dig_only;
12522 }
df694daa 12523 return 0; /* can't find valid BIOS pin config */
e64f14f4 12524 }
f12ab1e0
TI
12525 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12526 if (err < 0)
12527 return err;
05f5f477 12528 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12529 if (err < 0)
df694daa
KY
12530 return err;
12531
12532 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12533
e64f14f4 12534 dig_only:
757899ac 12535 alc_auto_parse_digital(codec);
df694daa 12536
603c4019 12537 if (spec->kctls.list)
d88897ea 12538 add_mixer(spec, spec->kctls.list);
df694daa 12539
d88897ea 12540 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12541 spec->num_mux_defs = 1;
61b9b9b1 12542 spec->input_mux = &spec->private_imux[0];
df694daa 12543
776e184e
TI
12544 err = alc_auto_add_mic_boost(codec);
12545 if (err < 0)
12546 return err;
12547
6227cdce 12548 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12549
df694daa
KY
12550 return 1;
12551}
12552
12553#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12554#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12555#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12556#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12557
12558
12559/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12560static void alc262_auto_init(struct hda_codec *codec)
df694daa 12561{
f6c7e546 12562 struct alc_spec *spec = codec->spec;
df694daa
KY
12563 alc262_auto_init_multi_out(codec);
12564 alc262_auto_init_hp_out(codec);
12565 alc262_auto_init_analog_input(codec);
f511b01c 12566 alc262_auto_init_input_src(codec);
757899ac 12567 alc_auto_init_digital(codec);
f6c7e546 12568 if (spec->unsol_event)
7fb0d78f 12569 alc_inithook(codec);
df694daa
KY
12570}
12571
12572/*
12573 * configuration and preset
12574 */
ea734963 12575static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12576 [ALC262_BASIC] = "basic",
12577 [ALC262_HIPPO] = "hippo",
12578 [ALC262_HIPPO_1] = "hippo_1",
12579 [ALC262_FUJITSU] = "fujitsu",
12580 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12581 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12582 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12583 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12584 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12585 [ALC262_BENQ_T31] = "benq-t31",
12586 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12587 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12588 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12589 [ALC262_ULTRA] = "ultra",
0e31daf7 12590 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12591 [ALC262_NEC] = "nec",
ba340e82 12592 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12593 [ALC262_AUTO] = "auto",
12594};
12595
12596static struct snd_pci_quirk alc262_cfg_tbl[] = {
12597 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12598 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12599 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12600 ALC262_HP_BPC),
12601 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12602 ALC262_HP_BPC),
5734a07c
TI
12603 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12604 ALC262_HP_BPC),
53eff7e1
TI
12605 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12606 ALC262_HP_BPC),
cd7509a4 12607 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12608 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12609 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12610 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12611 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12612 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12613 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12614 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12615 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12616 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12617 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12618 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12619 ALC262_HP_TC_T5735),
8c427226 12620 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12621 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12622 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12623 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12624 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12625 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12626 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12627 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12628#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12629 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12630 ALC262_SONY_ASSAMD),
c5b5165c 12631#endif
36ca6e13 12632 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12633 ALC262_TOSHIBA_RX1),
80ffe869 12634 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12635 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12636 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12637 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12638 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12639 ALC262_ULTRA),
3e420e78 12640 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12641 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12642 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12643 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12644 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12645 {}
12646};
12647
12648static struct alc_config_preset alc262_presets[] = {
12649 [ALC262_BASIC] = {
12650 .mixers = { alc262_base_mixer },
12651 .init_verbs = { alc262_init_verbs },
12652 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12653 .dac_nids = alc262_dac_nids,
12654 .hp_nid = 0x03,
12655 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12656 .channel_mode = alc262_modes,
a3bcba38 12657 .input_mux = &alc262_capture_source,
df694daa 12658 },
ccc656ce 12659 [ALC262_HIPPO] = {
42171c17 12660 .mixers = { alc262_hippo_mixer },
6732bd0d 12661 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12662 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12663 .dac_nids = alc262_dac_nids,
12664 .hp_nid = 0x03,
12665 .dig_out_nid = ALC262_DIGOUT_NID,
12666 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12667 .channel_mode = alc262_modes,
12668 .input_mux = &alc262_capture_source,
12669 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12670 .setup = alc262_hippo_setup,
12671 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12672 },
12673 [ALC262_HIPPO_1] = {
12674 .mixers = { alc262_hippo1_mixer },
12675 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12676 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12677 .dac_nids = alc262_dac_nids,
12678 .hp_nid = 0x02,
12679 .dig_out_nid = ALC262_DIGOUT_NID,
12680 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12681 .channel_mode = alc262_modes,
12682 .input_mux = &alc262_capture_source,
42171c17 12683 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12684 .setup = alc262_hippo1_setup,
12685 .init_hook = alc262_hippo_automute,
ccc656ce 12686 },
834be88d
TI
12687 [ALC262_FUJITSU] = {
12688 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12689 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12690 alc262_fujitsu_unsol_verbs },
834be88d
TI
12691 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12692 .dac_nids = alc262_dac_nids,
12693 .hp_nid = 0x03,
12694 .dig_out_nid = ALC262_DIGOUT_NID,
12695 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12696 .channel_mode = alc262_modes,
12697 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12698 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12699 .init_hook = alc262_fujitsu_init_hook,
834be88d 12700 },
9c7f852e
TI
12701 [ALC262_HP_BPC] = {
12702 .mixers = { alc262_HP_BPC_mixer },
12703 .init_verbs = { alc262_HP_BPC_init_verbs },
12704 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12705 .dac_nids = alc262_dac_nids,
12706 .hp_nid = 0x03,
12707 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12708 .channel_mode = alc262_modes,
12709 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12710 .unsol_event = alc262_hp_bpc_unsol_event,
12711 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12712 },
cd7509a4
KY
12713 [ALC262_HP_BPC_D7000_WF] = {
12714 .mixers = { alc262_HP_BPC_WildWest_mixer },
12715 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12716 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12717 .dac_nids = alc262_dac_nids,
12718 .hp_nid = 0x03,
12719 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12720 .channel_mode = alc262_modes,
accbe498 12721 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12722 .unsol_event = alc262_hp_wildwest_unsol_event,
12723 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12724 },
cd7509a4
KY
12725 [ALC262_HP_BPC_D7000_WL] = {
12726 .mixers = { alc262_HP_BPC_WildWest_mixer,
12727 alc262_HP_BPC_WildWest_option_mixer },
12728 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12729 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12730 .dac_nids = alc262_dac_nids,
12731 .hp_nid = 0x03,
12732 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12733 .channel_mode = alc262_modes,
accbe498 12734 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12735 .unsol_event = alc262_hp_wildwest_unsol_event,
12736 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12737 },
66d2a9d6
KY
12738 [ALC262_HP_TC_T5735] = {
12739 .mixers = { alc262_hp_t5735_mixer },
12740 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12741 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12742 .dac_nids = alc262_dac_nids,
12743 .hp_nid = 0x03,
12744 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12745 .channel_mode = alc262_modes,
12746 .input_mux = &alc262_capture_source,
dc99be47 12747 .unsol_event = alc_sku_unsol_event,
4f5d1706 12748 .setup = alc262_hp_t5735_setup,
dc99be47 12749 .init_hook = alc_inithook,
8c427226
KY
12750 },
12751 [ALC262_HP_RP5700] = {
12752 .mixers = { alc262_hp_rp5700_mixer },
12753 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12754 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12755 .dac_nids = alc262_dac_nids,
12756 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12757 .channel_mode = alc262_modes,
12758 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12759 },
304dcaac
TI
12760 [ALC262_BENQ_ED8] = {
12761 .mixers = { alc262_base_mixer },
12762 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12763 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12764 .dac_nids = alc262_dac_nids,
12765 .hp_nid = 0x03,
12766 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12767 .channel_mode = alc262_modes,
12768 .input_mux = &alc262_capture_source,
f12ab1e0 12769 },
272a527c
KY
12770 [ALC262_SONY_ASSAMD] = {
12771 .mixers = { alc262_sony_mixer },
12772 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12773 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12774 .dac_nids = alc262_dac_nids,
12775 .hp_nid = 0x02,
12776 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12777 .channel_mode = alc262_modes,
12778 .input_mux = &alc262_capture_source,
12779 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12780 .setup = alc262_hippo_setup,
12781 .init_hook = alc262_hippo_automute,
83c34218
KY
12782 },
12783 [ALC262_BENQ_T31] = {
12784 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12785 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12786 alc_hp15_unsol_verbs },
83c34218
KY
12787 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12788 .dac_nids = alc262_dac_nids,
12789 .hp_nid = 0x03,
12790 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12791 .channel_mode = alc262_modes,
12792 .input_mux = &alc262_capture_source,
12793 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12794 .setup = alc262_hippo_setup,
12795 .init_hook = alc262_hippo_automute,
ea1fb29a 12796 },
f651b50b 12797 [ALC262_ULTRA] = {
f9e336f6
TI
12798 .mixers = { alc262_ultra_mixer },
12799 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12800 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12801 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12802 .dac_nids = alc262_dac_nids,
f651b50b
TD
12803 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12804 .channel_mode = alc262_modes,
12805 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12806 .adc_nids = alc262_adc_nids, /* ADC0 */
12807 .capsrc_nids = alc262_capsrc_nids,
12808 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12809 .unsol_event = alc262_ultra_unsol_event,
12810 .init_hook = alc262_ultra_automute,
12811 },
0e31daf7
J
12812 [ALC262_LENOVO_3000] = {
12813 .mixers = { alc262_lenovo_3000_mixer },
12814 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12815 alc262_lenovo_3000_unsol_verbs,
12816 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12817 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12818 .dac_nids = alc262_dac_nids,
12819 .hp_nid = 0x03,
12820 .dig_out_nid = ALC262_DIGOUT_NID,
12821 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12822 .channel_mode = alc262_modes,
12823 .input_mux = &alc262_fujitsu_capture_source,
12824 .unsol_event = alc262_lenovo_3000_unsol_event,
12825 },
e8f9ae2a
PT
12826 [ALC262_NEC] = {
12827 .mixers = { alc262_nec_mixer },
12828 .init_verbs = { alc262_nec_verbs },
12829 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12830 .dac_nids = alc262_dac_nids,
12831 .hp_nid = 0x03,
12832 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12833 .channel_mode = alc262_modes,
12834 .input_mux = &alc262_capture_source,
12835 },
4e555fe5
KY
12836 [ALC262_TOSHIBA_S06] = {
12837 .mixers = { alc262_toshiba_s06_mixer },
12838 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12839 alc262_eapd_verbs },
12840 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12841 .capsrc_nids = alc262_dmic_capsrc_nids,
12842 .dac_nids = alc262_dac_nids,
12843 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12844 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12845 .dig_out_nid = ALC262_DIGOUT_NID,
12846 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12847 .channel_mode = alc262_modes,
4f5d1706
TI
12848 .unsol_event = alc_sku_unsol_event,
12849 .setup = alc262_toshiba_s06_setup,
12850 .init_hook = alc_inithook,
4e555fe5 12851 },
9f99a638
HM
12852 [ALC262_TOSHIBA_RX1] = {
12853 .mixers = { alc262_toshiba_rx1_mixer },
12854 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12855 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12856 .dac_nids = alc262_dac_nids,
12857 .hp_nid = 0x03,
12858 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12859 .channel_mode = alc262_modes,
12860 .input_mux = &alc262_capture_source,
12861 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12862 .setup = alc262_hippo_setup,
12863 .init_hook = alc262_hippo_automute,
9f99a638 12864 },
ba340e82
TV
12865 [ALC262_TYAN] = {
12866 .mixers = { alc262_tyan_mixer },
12867 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12868 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12869 .dac_nids = alc262_dac_nids,
12870 .hp_nid = 0x02,
12871 .dig_out_nid = ALC262_DIGOUT_NID,
12872 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12873 .channel_mode = alc262_modes,
12874 .input_mux = &alc262_capture_source,
a9fd4f3f 12875 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12876 .setup = alc262_tyan_setup,
12877 .init_hook = alc_automute_amp,
ba340e82 12878 },
df694daa
KY
12879};
12880
12881static int patch_alc262(struct hda_codec *codec)
12882{
12883 struct alc_spec *spec;
12884 int board_config;
12885 int err;
12886
dc041e0b 12887 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12888 if (spec == NULL)
12889 return -ENOMEM;
12890
12891 codec->spec = spec;
12892#if 0
f12ab1e0
TI
12893 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12894 * under-run
12895 */
df694daa
KY
12896 {
12897 int tmp;
12898 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12899 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12900 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12901 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12902 }
12903#endif
da00c244 12904 alc_auto_parse_customize_define(codec);
df694daa 12905
2c3bf9ab
TI
12906 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12907
f5fcc13c
TI
12908 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12909 alc262_models,
12910 alc262_cfg_tbl);
cd7509a4 12911
f5fcc13c 12912 if (board_config < 0) {
9a11f1aa
TI
12913 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12914 codec->chip_name);
df694daa
KY
12915 board_config = ALC262_AUTO;
12916 }
12917
b5bfbc67
TI
12918 if (board_config == ALC262_AUTO) {
12919 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12920 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12921 }
18675e42 12922
df694daa
KY
12923 if (board_config == ALC262_AUTO) {
12924 /* automatic parse from the BIOS config */
12925 err = alc262_parse_auto_config(codec);
12926 if (err < 0) {
12927 alc_free(codec);
12928 return err;
f12ab1e0 12929 } else if (!err) {
9c7f852e
TI
12930 printk(KERN_INFO
12931 "hda_codec: Cannot set up configuration "
12932 "from BIOS. Using base mode...\n");
df694daa
KY
12933 board_config = ALC262_BASIC;
12934 }
12935 }
12936
dc1eae25 12937 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12938 err = snd_hda_attach_beep_device(codec, 0x1);
12939 if (err < 0) {
12940 alc_free(codec);
12941 return err;
12942 }
680cd536
KK
12943 }
12944
df694daa 12945 if (board_config != ALC262_AUTO)
e9c364c0 12946 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12947
df694daa
KY
12948 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12949 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12950
df694daa
KY
12951 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12952 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12953
f12ab1e0 12954 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12955 int i;
12956 /* check whether the digital-mic has to be supported */
12957 for (i = 0; i < spec->input_mux->num_items; i++) {
12958 if (spec->input_mux->items[i].index >= 9)
12959 break;
12960 }
12961 if (i < spec->input_mux->num_items) {
12962 /* use only ADC0 */
12963 spec->adc_nids = alc262_dmic_adc_nids;
12964 spec->num_adc_nids = 1;
12965 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12966 } else {
8c927b4a
TI
12967 /* all analog inputs */
12968 /* check whether NID 0x07 is valid */
12969 unsigned int wcap = get_wcaps(codec, 0x07);
12970
12971 /* get type */
a22d543a 12972 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12973 if (wcap != AC_WID_AUD_IN) {
12974 spec->adc_nids = alc262_adc_nids_alt;
12975 spec->num_adc_nids =
12976 ARRAY_SIZE(alc262_adc_nids_alt);
12977 spec->capsrc_nids = alc262_capsrc_nids_alt;
12978 } else {
12979 spec->adc_nids = alc262_adc_nids;
12980 spec->num_adc_nids =
12981 ARRAY_SIZE(alc262_adc_nids);
12982 spec->capsrc_nids = alc262_capsrc_nids;
12983 }
df694daa
KY
12984 }
12985 }
e64f14f4 12986 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12987 set_capture_mixer(codec);
dc1eae25 12988 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12989 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12990
b5bfbc67 12991 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 12992
2134ea4f
TI
12993 spec->vmaster_nid = 0x0c;
12994
df694daa
KY
12995 codec->patch_ops = alc_patch_ops;
12996 if (board_config == ALC262_AUTO)
ae6b813a 12997 spec->init_hook = alc262_auto_init;
bf1b0225
KY
12998
12999 alc_init_jacks(codec);
cb53c626
TI
13000#ifdef CONFIG_SND_HDA_POWER_SAVE
13001 if (!spec->loopback.amplist)
13002 spec->loopback.amplist = alc262_loopbacks;
13003#endif
ea1fb29a 13004
df694daa
KY
13005 return 0;
13006}
13007
a361d84b
KY
13008/*
13009 * ALC268 channel source setting (2 channel)
13010 */
13011#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13012#define alc268_modes alc260_modes
ea1fb29a 13013
a361d84b
KY
13014static hda_nid_t alc268_dac_nids[2] = {
13015 /* front, hp */
13016 0x02, 0x03
13017};
13018
13019static hda_nid_t alc268_adc_nids[2] = {
13020 /* ADC0-1 */
13021 0x08, 0x07
13022};
13023
13024static hda_nid_t alc268_adc_nids_alt[1] = {
13025 /* ADC0 */
13026 0x08
13027};
13028
e1406348
TI
13029static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13030
a361d84b
KY
13031static struct snd_kcontrol_new alc268_base_mixer[] = {
13032 /* output mixer control */
13033 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13034 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13035 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13036 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13037 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13038 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13039 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13040 { }
13041};
13042
42171c17
TI
13043static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13044 /* output mixer control */
13045 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13046 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13047 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13048 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13049 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13050 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13051 { }
13052};
13053
aef9d318
TI
13054/* bind Beep switches of both NID 0x0f and 0x10 */
13055static struct hda_bind_ctls alc268_bind_beep_sw = {
13056 .ops = &snd_hda_bind_sw,
13057 .values = {
13058 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13059 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13060 0
13061 },
13062};
13063
13064static struct snd_kcontrol_new alc268_beep_mixer[] = {
13065 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13066 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13067 { }
13068};
13069
d1a991a6
KY
13070static struct hda_verb alc268_eapd_verbs[] = {
13071 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13072 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13073 { }
13074};
13075
d273809e 13076/* Toshiba specific */
d273809e
TI
13077static struct hda_verb alc268_toshiba_verbs[] = {
13078 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13079 { } /* end */
13080};
13081
13082/* Acer specific */
889c4395 13083/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13084static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13085 .ops = &snd_hda_bind_vol,
13086 .values = {
13087 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13088 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13089 0
13090 },
13091};
13092
889c4395
TI
13093/* mute/unmute internal speaker according to the hp jack and mute state */
13094static void alc268_acer_automute(struct hda_codec *codec, int force)
13095{
13096 struct alc_spec *spec = codec->spec;
13097 unsigned int mute;
13098
13099 if (force || !spec->sense_updated) {
864f92be 13100 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
13101 spec->sense_updated = 1;
13102 }
13103 if (spec->jack_present)
13104 mute = HDA_AMP_MUTE; /* mute internal speaker */
13105 else /* unmute internal speaker if necessary */
13106 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13107 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13108 HDA_AMP_MUTE, mute);
13109}
13110
13111
13112/* bind hp and internal speaker mute (with plug check) */
13113static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13114 struct snd_ctl_elem_value *ucontrol)
13115{
13116 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13117 long *valp = ucontrol->value.integer.value;
13118 int change;
13119
8de56b7d 13120 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13121 if (change)
13122 alc268_acer_automute(codec, 0);
13123 return change;
13124}
d273809e 13125
8ef355da
KY
13126static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13127 /* output mixer control */
13128 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13129 {
13130 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13131 .name = "Master Playback Switch",
5e26dfd0 13132 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13133 .info = snd_hda_mixer_amp_switch_info,
13134 .get = snd_hda_mixer_amp_switch_get,
13135 .put = alc268_acer_master_sw_put,
13136 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13137 },
13138 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13139 { }
13140};
13141
d273809e
TI
13142static struct snd_kcontrol_new alc268_acer_mixer[] = {
13143 /* output mixer control */
13144 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13145 {
13146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13147 .name = "Master Playback Switch",
5e26dfd0 13148 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13149 .info = snd_hda_mixer_amp_switch_info,
13150 .get = snd_hda_mixer_amp_switch_get,
13151 .put = alc268_acer_master_sw_put,
13152 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13153 },
5f99f86a
DH
13154 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13155 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13156 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13157 { }
13158};
13159
c238b4f4
TI
13160static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13161 /* output mixer control */
13162 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13163 {
13164 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13165 .name = "Master Playback Switch",
5e26dfd0 13166 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13167 .info = snd_hda_mixer_amp_switch_info,
13168 .get = snd_hda_mixer_amp_switch_get,
13169 .put = alc268_acer_master_sw_put,
13170 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13171 },
5f99f86a
DH
13172 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13173 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13174 { }
13175};
13176
8ef355da
KY
13177static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13178 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13179 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13180 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13181 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13182 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13183 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13184 { }
13185};
13186
d273809e 13187static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13188 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13189 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13190 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13191 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13192 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13193 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13194 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13195 { }
13196};
13197
13198/* unsolicited event for HP jack sensing */
42171c17 13199#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13200#define alc268_toshiba_setup alc262_hippo_setup
13201#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13202
13203static void alc268_acer_unsol_event(struct hda_codec *codec,
13204 unsigned int res)
13205{
889c4395 13206 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13207 return;
13208 alc268_acer_automute(codec, 1);
13209}
13210
889c4395
TI
13211static void alc268_acer_init_hook(struct hda_codec *codec)
13212{
13213 alc268_acer_automute(codec, 1);
13214}
13215
8ef355da
KY
13216/* toggle speaker-output according to the hp-jack state */
13217static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13218{
13219 unsigned int present;
13220 unsigned char bits;
13221
864f92be 13222 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13223 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13224 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13225 HDA_AMP_MUTE, bits);
8ef355da 13226 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13227 HDA_AMP_MUTE, bits);
8ef355da
KY
13228}
13229
8ef355da
KY
13230static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13231 unsigned int res)
13232{
4f5d1706
TI
13233 switch (res >> 26) {
13234 case ALC880_HP_EVENT:
8ef355da 13235 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13236 break;
13237 case ALC880_MIC_EVENT:
13238 alc_mic_automute(codec);
13239 break;
13240 }
13241}
13242
13243static void alc268_acer_lc_setup(struct hda_codec *codec)
13244{
13245 struct alc_spec *spec = codec->spec;
13246 spec->ext_mic.pin = 0x18;
13247 spec->ext_mic.mux_idx = 0;
13248 spec->int_mic.pin = 0x12;
13249 spec->int_mic.mux_idx = 6;
13250 spec->auto_mic = 1;
8ef355da
KY
13251}
13252
13253static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13254{
13255 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13256 alc_mic_automute(codec);
8ef355da
KY
13257}
13258
3866f0b0
TI
13259static struct snd_kcontrol_new alc268_dell_mixer[] = {
13260 /* output mixer control */
13261 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13262 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13263 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13264 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13265 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13266 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13267 { }
13268};
13269
13270static struct hda_verb alc268_dell_verbs[] = {
13271 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13272 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13273 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13274 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13275 { }
13276};
13277
13278/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13279static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13280{
a9fd4f3f 13281 struct alc_spec *spec = codec->spec;
3866f0b0 13282
a9fd4f3f
TI
13283 spec->autocfg.hp_pins[0] = 0x15;
13284 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13285 spec->ext_mic.pin = 0x18;
13286 spec->ext_mic.mux_idx = 0;
13287 spec->int_mic.pin = 0x19;
13288 spec->int_mic.mux_idx = 1;
13289 spec->auto_mic = 1;
3866f0b0
TI
13290}
13291
eb5a6621
HRK
13292static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13293 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13294 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13295 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13296 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13297 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13298 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13299 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13300 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13301 { }
13302};
13303
13304static struct hda_verb alc267_quanta_il1_verbs[] = {
13305 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13306 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13307 { }
13308};
13309
4f5d1706 13310static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13311{
a9fd4f3f 13312 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13313 spec->autocfg.hp_pins[0] = 0x15;
13314 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13315 spec->ext_mic.pin = 0x18;
13316 spec->ext_mic.mux_idx = 0;
13317 spec->int_mic.pin = 0x19;
13318 spec->int_mic.mux_idx = 1;
13319 spec->auto_mic = 1;
eb5a6621
HRK
13320}
13321
a361d84b
KY
13322/*
13323 * generic initialization of ADC, input mixers and output mixers
13324 */
13325static struct hda_verb alc268_base_init_verbs[] = {
13326 /* Unmute DAC0-1 and set vol = 0 */
13327 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13328 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13329
13330 /*
13331 * Set up output mixers (0x0c - 0x0e)
13332 */
13333 /* set vol=0 to output mixers */
13334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13335 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13336
13337 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13338 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13339
13340 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13341 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13342 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13343 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13344 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13345 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13346 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13347 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13348
13349 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13350 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13351 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13352 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13353 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13354
13355 /* set PCBEEP vol = 0, mute connections */
13356 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13357 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13358 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13359
a9b3aa8a 13360 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13361
a9b3aa8a
JZ
13362 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13364 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13365 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13366
a361d84b
KY
13367 { }
13368};
13369
13370/*
13371 * generic initialization of ADC, input mixers and output mixers
13372 */
13373static struct hda_verb alc268_volume_init_verbs[] = {
13374 /* set output DAC */
4cfb91c6
TI
13375 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13376 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13377
13378 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13379 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13380 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13381 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13382 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13383
a361d84b 13384 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13385 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13386 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13387
13388 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13389 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13390
aef9d318
TI
13391 /* set PCBEEP vol = 0, mute connections */
13392 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13393 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13394 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13395
13396 { }
13397};
13398
fdbc6626
TI
13399static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13400 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13401 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13402 { } /* end */
13403};
13404
a361d84b
KY
13405static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13406 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13407 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13408 _DEFINE_CAPSRC(1),
a361d84b
KY
13409 { } /* end */
13410};
13411
13412static struct snd_kcontrol_new alc268_capture_mixer[] = {
13413 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13414 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13415 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13416 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13417 _DEFINE_CAPSRC(2),
a361d84b
KY
13418 { } /* end */
13419};
13420
13421static struct hda_input_mux alc268_capture_source = {
13422 .num_items = 4,
13423 .items = {
13424 { "Mic", 0x0 },
13425 { "Front Mic", 0x1 },
13426 { "Line", 0x2 },
13427 { "CD", 0x3 },
13428 },
13429};
13430
0ccb541c 13431static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13432 .num_items = 3,
13433 .items = {
13434 { "Mic", 0x0 },
13435 { "Internal Mic", 0x1 },
13436 { "Line", 0x2 },
13437 },
13438};
13439
13440static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13441 .num_items = 3,
13442 .items = {
13443 { "Mic", 0x0 },
13444 { "Internal Mic", 0x6 },
13445 { "Line", 0x2 },
13446 },
13447};
13448
86c53bd2
JW
13449#ifdef CONFIG_SND_DEBUG
13450static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13451 /* Volume widgets */
13452 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13453 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13454 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13455 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13456 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13457 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13458 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13459 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13460 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13461 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13462 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13463 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13464 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13465 /* The below appears problematic on some hardwares */
13466 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13467 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13468 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13469 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13470 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13471
13472 /* Modes for retasking pin widgets */
13473 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13474 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13475 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13476 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13477
13478 /* Controls for GPIO pins, assuming they are configured as outputs */
13479 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13480 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13481 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13482 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13483
13484 /* Switches to allow the digital SPDIF output pin to be enabled.
13485 * The ALC268 does not have an SPDIF input.
13486 */
13487 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13488
13489 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13490 * this output to turn on an external amplifier.
13491 */
13492 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13493 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13494
13495 { } /* end */
13496};
13497#endif
13498
a361d84b
KY
13499/* create input playback/capture controls for the given pin */
13500static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13501 const char *ctlname, int idx)
13502{
3f3b7c1a 13503 hda_nid_t dac;
a361d84b
KY
13504 int err;
13505
3f3b7c1a
TI
13506 switch (nid) {
13507 case 0x14:
13508 case 0x16:
13509 dac = 0x02;
13510 break;
13511 case 0x15:
b08b1637
TI
13512 case 0x1a: /* ALC259/269 only */
13513 case 0x1b: /* ALC259/269 only */
531d8791 13514 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13515 dac = 0x03;
13516 break;
13517 default:
c7a9434d
TI
13518 snd_printd(KERN_WARNING "hda_codec: "
13519 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13520 return 0;
13521 }
13522 if (spec->multiout.dac_nids[0] != dac &&
13523 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13524 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13525 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13526 HDA_OUTPUT));
13527 if (err < 0)
13528 return err;
3f3b7c1a
TI
13529 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13530 }
13531
3f3b7c1a 13532 if (nid != 0x16)
0afe5f89 13533 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13534 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13535 else /* mono */
0afe5f89 13536 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13537 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13538 if (err < 0)
13539 return err;
13540 return 0;
13541}
13542
13543/* add playback controls from the parsed DAC table */
13544static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13545 const struct auto_pin_cfg *cfg)
13546{
13547 hda_nid_t nid;
13548 int err;
13549
a361d84b 13550 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13551
13552 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13553 if (nid) {
13554 const char *name;
13555 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13556 name = "Speaker";
13557 else
13558 name = "Front";
13559 err = alc268_new_analog_output(spec, nid, name, 0);
13560 if (err < 0)
13561 return err;
13562 }
a361d84b
KY
13563
13564 nid = cfg->speaker_pins[0];
13565 if (nid == 0x1d) {
0afe5f89 13566 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13567 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13568 if (err < 0)
13569 return err;
7bfb9c03 13570 } else if (nid) {
3f3b7c1a
TI
13571 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13572 if (err < 0)
13573 return err;
a361d84b
KY
13574 }
13575 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13576 if (nid) {
13577 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13578 if (err < 0)
13579 return err;
13580 }
a361d84b
KY
13581
13582 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13583 if (nid == 0x16) {
0afe5f89 13584 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13585 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13586 if (err < 0)
13587 return err;
13588 }
ea1fb29a 13589 return 0;
a361d84b
KY
13590}
13591
13592/* create playback/capture controls for input pins */
05f5f477 13593static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13594 const struct auto_pin_cfg *cfg)
13595{
05f5f477 13596 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13597}
13598
e9af4f36
TI
13599static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13600 hda_nid_t nid, int pin_type)
13601{
13602 int idx;
13603
13604 alc_set_pin_output(codec, nid, pin_type);
13605 if (nid == 0x14 || nid == 0x16)
13606 idx = 0;
13607 else
13608 idx = 1;
13609 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13610}
13611
13612static void alc268_auto_init_multi_out(struct hda_codec *codec)
13613{
13614 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13615 int i;
13616
13617 for (i = 0; i < spec->autocfg.line_outs; i++) {
13618 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13619 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13620 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13621 }
13622}
13623
13624static void alc268_auto_init_hp_out(struct hda_codec *codec)
13625{
13626 struct alc_spec *spec = codec->spec;
13627 hda_nid_t pin;
e1ca7b4e 13628 int i;
e9af4f36 13629
e1ca7b4e
TI
13630 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13631 pin = spec->autocfg.hp_pins[i];
e9af4f36 13632 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13633 }
13634 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13635 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13636 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13637 }
13638 if (spec->autocfg.mono_out_pin)
13639 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13640 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13641}
13642
a361d84b
KY
13643static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13644{
13645 struct alc_spec *spec = codec->spec;
13646 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13647 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13648 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13649 unsigned int dac_vol1, dac_vol2;
13650
e9af4f36 13651 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13652 snd_hda_codec_write(codec, speaker_nid, 0,
13653 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13654 /* mute mixer inputs from 0x1d */
a361d84b
KY
13655 snd_hda_codec_write(codec, 0x0f, 0,
13656 AC_VERB_SET_AMP_GAIN_MUTE,
13657 AMP_IN_UNMUTE(1));
13658 snd_hda_codec_write(codec, 0x10, 0,
13659 AC_VERB_SET_AMP_GAIN_MUTE,
13660 AMP_IN_UNMUTE(1));
13661 } else {
e9af4f36 13662 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13663 snd_hda_codec_write(codec, 0x0f, 0,
13664 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13665 snd_hda_codec_write(codec, 0x10, 0,
13666 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13667 }
13668
13669 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13670 if (line_nid == 0x14)
a361d84b
KY
13671 dac_vol2 = AMP_OUT_ZERO;
13672 else if (line_nid == 0x15)
13673 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13674 if (hp_nid == 0x14)
a361d84b
KY
13675 dac_vol2 = AMP_OUT_ZERO;
13676 else if (hp_nid == 0x15)
13677 dac_vol1 = AMP_OUT_ZERO;
13678 if (line_nid != 0x16 || hp_nid != 0x16 ||
13679 spec->autocfg.line_out_pins[1] != 0x16 ||
13680 spec->autocfg.line_out_pins[2] != 0x16)
13681 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13682
13683 snd_hda_codec_write(codec, 0x02, 0,
13684 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13685 snd_hda_codec_write(codec, 0x03, 0,
13686 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13687}
13688
def319f9 13689/* pcm configuration: identical with ALC880 */
a361d84b
KY
13690#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13691#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13692#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13693#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13694
13695/*
13696 * BIOS auto configuration
13697 */
13698static int alc268_parse_auto_config(struct hda_codec *codec)
13699{
13700 struct alc_spec *spec = codec->spec;
13701 int err;
13702 static hda_nid_t alc268_ignore[] = { 0 };
13703
13704 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13705 alc268_ignore);
13706 if (err < 0)
13707 return err;
7e0e44d4
TI
13708 if (!spec->autocfg.line_outs) {
13709 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13710 spec->multiout.max_channels = 2;
13711 spec->no_analog = 1;
13712 goto dig_only;
13713 }
a361d84b 13714 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13715 }
a361d84b
KY
13716 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13717 if (err < 0)
13718 return err;
05f5f477 13719 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13720 if (err < 0)
13721 return err;
13722
13723 spec->multiout.max_channels = 2;
13724
7e0e44d4 13725 dig_only:
a361d84b 13726 /* digital only support output */
757899ac 13727 alc_auto_parse_digital(codec);
603c4019 13728 if (spec->kctls.list)
d88897ea 13729 add_mixer(spec, spec->kctls.list);
a361d84b 13730
892981ff 13731 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13732 add_mixer(spec, alc268_beep_mixer);
aef9d318 13733
d88897ea 13734 add_verb(spec, alc268_volume_init_verbs);
5908589f 13735 spec->num_mux_defs = 2;
61b9b9b1 13736 spec->input_mux = &spec->private_imux[0];
a361d84b 13737
776e184e
TI
13738 err = alc_auto_add_mic_boost(codec);
13739 if (err < 0)
13740 return err;
13741
6227cdce 13742 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13743
a361d84b
KY
13744 return 1;
13745}
13746
a361d84b
KY
13747#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13748
13749/* init callback for auto-configuration model -- overriding the default init */
13750static void alc268_auto_init(struct hda_codec *codec)
13751{
f6c7e546 13752 struct alc_spec *spec = codec->spec;
a361d84b
KY
13753 alc268_auto_init_multi_out(codec);
13754 alc268_auto_init_hp_out(codec);
13755 alc268_auto_init_mono_speaker_out(codec);
13756 alc268_auto_init_analog_input(codec);
757899ac 13757 alc_auto_init_digital(codec);
f6c7e546 13758 if (spec->unsol_event)
7fb0d78f 13759 alc_inithook(codec);
a361d84b
KY
13760}
13761
13762/*
13763 * configuration and preset
13764 */
ea734963 13765static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13766 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13767 [ALC268_3ST] = "3stack",
983f8ae4 13768 [ALC268_TOSHIBA] = "toshiba",
d273809e 13769 [ALC268_ACER] = "acer",
c238b4f4 13770 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13771 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13772 [ALC268_DELL] = "dell",
f12462c5 13773 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13774#ifdef CONFIG_SND_DEBUG
13775 [ALC268_TEST] = "test",
13776#endif
a361d84b
KY
13777 [ALC268_AUTO] = "auto",
13778};
13779
13780static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13781 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13782 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13783 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13784 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13785 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13786 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13787 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13788 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13789 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13790 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13791 /* almost compatible with toshiba but with optional digital outs;
13792 * auto-probing seems working fine
13793 */
8871e5b9 13794 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13795 ALC268_AUTO),
a361d84b 13796 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13797 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13798 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13799 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13800 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13801 {}
13802};
13803
3abf2f36
TI
13804/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13805static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13806 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13807 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13808 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13809 ALC268_TOSHIBA),
13810 {}
13811};
13812
a361d84b 13813static struct alc_config_preset alc268_presets[] = {
eb5a6621 13814 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13815 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13816 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13817 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13818 alc267_quanta_il1_verbs },
13819 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13820 .dac_nids = alc268_dac_nids,
13821 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13822 .adc_nids = alc268_adc_nids_alt,
13823 .hp_nid = 0x03,
13824 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13825 .channel_mode = alc268_modes,
4f5d1706
TI
13826 .unsol_event = alc_sku_unsol_event,
13827 .setup = alc267_quanta_il1_setup,
13828 .init_hook = alc_inithook,
eb5a6621 13829 },
a361d84b 13830 [ALC268_3ST] = {
aef9d318
TI
13831 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13832 alc268_beep_mixer },
a361d84b
KY
13833 .init_verbs = { alc268_base_init_verbs },
13834 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13835 .dac_nids = alc268_dac_nids,
13836 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13837 .adc_nids = alc268_adc_nids_alt,
e1406348 13838 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13839 .hp_nid = 0x03,
13840 .dig_out_nid = ALC268_DIGOUT_NID,
13841 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13842 .channel_mode = alc268_modes,
13843 .input_mux = &alc268_capture_source,
13844 },
d1a991a6 13845 [ALC268_TOSHIBA] = {
42171c17 13846 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13847 alc268_beep_mixer },
d273809e
TI
13848 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13849 alc268_toshiba_verbs },
d1a991a6
KY
13850 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13851 .dac_nids = alc268_dac_nids,
13852 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13853 .adc_nids = alc268_adc_nids_alt,
e1406348 13854 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13855 .hp_nid = 0x03,
13856 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13857 .channel_mode = alc268_modes,
13858 .input_mux = &alc268_capture_source,
d273809e 13859 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13860 .setup = alc268_toshiba_setup,
13861 .init_hook = alc268_toshiba_automute,
d273809e
TI
13862 },
13863 [ALC268_ACER] = {
432fd133 13864 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13865 alc268_beep_mixer },
d273809e
TI
13866 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13867 alc268_acer_verbs },
13868 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13869 .dac_nids = alc268_dac_nids,
13870 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13871 .adc_nids = alc268_adc_nids_alt,
e1406348 13872 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13873 .hp_nid = 0x02,
13874 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13875 .channel_mode = alc268_modes,
0ccb541c 13876 .input_mux = &alc268_acer_capture_source,
d273809e 13877 .unsol_event = alc268_acer_unsol_event,
889c4395 13878 .init_hook = alc268_acer_init_hook,
d1a991a6 13879 },
c238b4f4
TI
13880 [ALC268_ACER_DMIC] = {
13881 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13882 alc268_beep_mixer },
13883 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13884 alc268_acer_verbs },
13885 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13886 .dac_nids = alc268_dac_nids,
13887 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13888 .adc_nids = alc268_adc_nids_alt,
13889 .capsrc_nids = alc268_capsrc_nids,
13890 .hp_nid = 0x02,
13891 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13892 .channel_mode = alc268_modes,
13893 .input_mux = &alc268_acer_dmic_capture_source,
13894 .unsol_event = alc268_acer_unsol_event,
13895 .init_hook = alc268_acer_init_hook,
13896 },
8ef355da
KY
13897 [ALC268_ACER_ASPIRE_ONE] = {
13898 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13899 alc268_beep_mixer,
fdbc6626 13900 alc268_capture_nosrc_mixer },
8ef355da
KY
13901 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13902 alc268_acer_aspire_one_verbs },
13903 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13904 .dac_nids = alc268_dac_nids,
13905 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13906 .adc_nids = alc268_adc_nids_alt,
13907 .capsrc_nids = alc268_capsrc_nids,
13908 .hp_nid = 0x03,
13909 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13910 .channel_mode = alc268_modes,
8ef355da 13911 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13912 .setup = alc268_acer_lc_setup,
8ef355da
KY
13913 .init_hook = alc268_acer_lc_init_hook,
13914 },
3866f0b0 13915 [ALC268_DELL] = {
fdbc6626
TI
13916 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13917 alc268_capture_nosrc_mixer },
3866f0b0
TI
13918 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13919 alc268_dell_verbs },
13920 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13921 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13922 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13923 .adc_nids = alc268_adc_nids_alt,
13924 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13925 .hp_nid = 0x02,
13926 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13927 .channel_mode = alc268_modes,
a9fd4f3f 13928 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13929 .setup = alc268_dell_setup,
13930 .init_hook = alc_inithook,
3866f0b0 13931 },
f12462c5 13932 [ALC268_ZEPTO] = {
aef9d318
TI
13933 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13934 alc268_beep_mixer },
f12462c5
MT
13935 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13936 alc268_toshiba_verbs },
13937 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13938 .dac_nids = alc268_dac_nids,
13939 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13940 .adc_nids = alc268_adc_nids_alt,
e1406348 13941 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13942 .hp_nid = 0x03,
13943 .dig_out_nid = ALC268_DIGOUT_NID,
13944 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13945 .channel_mode = alc268_modes,
13946 .input_mux = &alc268_capture_source,
4f5d1706
TI
13947 .setup = alc268_toshiba_setup,
13948 .init_hook = alc268_toshiba_automute,
f12462c5 13949 },
86c53bd2
JW
13950#ifdef CONFIG_SND_DEBUG
13951 [ALC268_TEST] = {
13952 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13953 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13954 alc268_volume_init_verbs },
13955 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13956 .dac_nids = alc268_dac_nids,
13957 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13958 .adc_nids = alc268_adc_nids_alt,
e1406348 13959 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13960 .hp_nid = 0x03,
13961 .dig_out_nid = ALC268_DIGOUT_NID,
13962 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13963 .channel_mode = alc268_modes,
13964 .input_mux = &alc268_capture_source,
13965 },
13966#endif
a361d84b
KY
13967};
13968
13969static int patch_alc268(struct hda_codec *codec)
13970{
13971 struct alc_spec *spec;
13972 int board_config;
22971e3a 13973 int i, has_beep, err;
a361d84b 13974
ef86f581 13975 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13976 if (spec == NULL)
13977 return -ENOMEM;
13978
13979 codec->spec = spec;
13980
13981 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13982 alc268_models,
13983 alc268_cfg_tbl);
13984
3abf2f36
TI
13985 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13986 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13987 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13988
a361d84b 13989 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13990 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13991 codec->chip_name);
a361d84b
KY
13992 board_config = ALC268_AUTO;
13993 }
13994
13995 if (board_config == ALC268_AUTO) {
13996 /* automatic parse from the BIOS config */
13997 err = alc268_parse_auto_config(codec);
13998 if (err < 0) {
13999 alc_free(codec);
14000 return err;
14001 } else if (!err) {
14002 printk(KERN_INFO
14003 "hda_codec: Cannot set up configuration "
14004 "from BIOS. Using base mode...\n");
14005 board_config = ALC268_3ST;
14006 }
14007 }
14008
14009 if (board_config != ALC268_AUTO)
e9c364c0 14010 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14011
a361d84b
KY
14012 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14013 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14014 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14015
a361d84b
KY
14016 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14017
22971e3a
TI
14018 has_beep = 0;
14019 for (i = 0; i < spec->num_mixers; i++) {
14020 if (spec->mixers[i] == alc268_beep_mixer) {
14021 has_beep = 1;
14022 break;
14023 }
14024 }
14025
14026 if (has_beep) {
14027 err = snd_hda_attach_beep_device(codec, 0x1);
14028 if (err < 0) {
14029 alc_free(codec);
14030 return err;
14031 }
14032 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14033 /* override the amp caps for beep generator */
14034 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14035 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14036 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14037 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14038 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14039 }
aef9d318 14040
7e0e44d4 14041 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14042 /* check whether NID 0x07 is valid */
14043 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 14044 int i;
3866f0b0 14045
defb5ab2 14046 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14047 /* get type */
a22d543a 14048 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14049 if (spec->auto_mic ||
14050 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14051 spec->adc_nids = alc268_adc_nids_alt;
14052 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14053 if (spec->auto_mic)
14054 fixup_automic_adc(codec);
fdbc6626
TI
14055 if (spec->auto_mic || spec->input_mux->num_items == 1)
14056 add_mixer(spec, alc268_capture_nosrc_mixer);
14057 else
14058 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14059 } else {
14060 spec->adc_nids = alc268_adc_nids;
14061 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14062 add_mixer(spec, alc268_capture_mixer);
a361d84b 14063 }
85860c06
TI
14064 /* set default input source */
14065 for (i = 0; i < spec->num_adc_nids; i++)
14066 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14067 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
14068 i < spec->num_mux_defs ?
14069 spec->input_mux[i].items[0].index :
85860c06 14070 spec->input_mux->items[0].index);
a361d84b 14071 }
2134ea4f
TI
14072
14073 spec->vmaster_nid = 0x02;
14074
a361d84b
KY
14075 codec->patch_ops = alc_patch_ops;
14076 if (board_config == ALC268_AUTO)
14077 spec->init_hook = alc268_auto_init;
ea1fb29a 14078
bf1b0225
KY
14079 alc_init_jacks(codec);
14080
a361d84b
KY
14081 return 0;
14082}
14083
f6a92248
KY
14084/*
14085 * ALC269 channel source setting (2 channel)
14086 */
14087#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14088
14089#define alc269_dac_nids alc260_dac_nids
14090
14091static hda_nid_t alc269_adc_nids[1] = {
14092 /* ADC1 */
f53281e6
KY
14093 0x08,
14094};
14095
e01bf509
TI
14096static hda_nid_t alc269_capsrc_nids[1] = {
14097 0x23,
14098};
14099
84898e87
KY
14100static hda_nid_t alc269vb_adc_nids[1] = {
14101 /* ADC1 */
14102 0x09,
14103};
14104
14105static hda_nid_t alc269vb_capsrc_nids[1] = {
14106 0x22,
14107};
14108
6694635d
TI
14109static hda_nid_t alc269_adc_candidates[] = {
14110 0x08, 0x09, 0x07,
14111};
e01bf509 14112
f6a92248
KY
14113#define alc269_modes alc260_modes
14114#define alc269_capture_source alc880_lg_lw_capture_source
14115
14116static struct snd_kcontrol_new alc269_base_mixer[] = {
14117 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14118 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14119 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14120 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14121 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14122 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14123 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14124 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14125 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14126 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14127 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14128 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14129 { } /* end */
14130};
14131
60db6b53
KY
14132static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14133 /* output mixer control */
14134 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14135 {
14136 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14137 .name = "Master Playback Switch",
5e26dfd0 14138 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14139 .info = snd_hda_mixer_amp_switch_info,
14140 .get = snd_hda_mixer_amp_switch_get,
14141 .put = alc268_acer_master_sw_put,
14142 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14143 },
14144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14146 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14147 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14148 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14149 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14150 { }
14151};
14152
64154835
TV
14153static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14154 /* output mixer control */
14155 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14156 {
14157 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14158 .name = "Master Playback Switch",
5e26dfd0 14159 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14160 .info = snd_hda_mixer_amp_switch_info,
14161 .get = snd_hda_mixer_amp_switch_get,
14162 .put = alc268_acer_master_sw_put,
14163 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14164 },
14165 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14166 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14167 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14168 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14169 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14170 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14171 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14172 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14173 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14174 { }
14175};
14176
84898e87 14177static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14178 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14179 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14180 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14181 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14182 { } /* end */
14183};
14184
84898e87
KY
14185static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14186 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14187 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14188 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14189 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14190 { } /* end */
14191};
14192
fe3eb0a7
KY
14193static struct snd_kcontrol_new alc269_asus_mixer[] = {
14194 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14195 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14196 { } /* end */
14197};
14198
f53281e6 14199/* capture mixer elements */
84898e87
KY
14200static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14201 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14202 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14203 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14204 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14205 { } /* end */
14206};
14207
14208static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14209 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14210 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14212 { } /* end */
14213};
14214
84898e87
KY
14215static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14216 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14217 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14218 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14219 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14220 { } /* end */
14221};
14222
14223static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14224 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14225 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14226 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14227 { } /* end */
14228};
14229
26f5df26 14230/* FSC amilo */
84898e87 14231#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14232
60db6b53
KY
14233static struct hda_verb alc269_quanta_fl1_verbs[] = {
14234 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14235 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14237 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14238 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14239 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14240 { }
14241};
f6a92248 14242
64154835
TV
14243static struct hda_verb alc269_lifebook_verbs[] = {
14244 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14245 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14246 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14247 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14248 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14249 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14250 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14251 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14252 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14253 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14254 { }
14255};
14256
60db6b53
KY
14257/* toggle speaker-output according to the hp-jack state */
14258static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14259{
14260 unsigned int present;
14261 unsigned char bits;
f6a92248 14262
864f92be 14263 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14264 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14265 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14266 HDA_AMP_MUTE, bits);
60db6b53 14267 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14268 HDA_AMP_MUTE, bits);
f6a92248 14269
60db6b53
KY
14270 snd_hda_codec_write(codec, 0x20, 0,
14271 AC_VERB_SET_COEF_INDEX, 0x0c);
14272 snd_hda_codec_write(codec, 0x20, 0,
14273 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14274
60db6b53
KY
14275 snd_hda_codec_write(codec, 0x20, 0,
14276 AC_VERB_SET_COEF_INDEX, 0x0c);
14277 snd_hda_codec_write(codec, 0x20, 0,
14278 AC_VERB_SET_PROC_COEF, 0x480);
14279}
f6a92248 14280
64154835
TV
14281/* toggle speaker-output according to the hp-jacks state */
14282static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14283{
14284 unsigned int present;
14285 unsigned char bits;
14286
14287 /* Check laptop headphone socket */
864f92be 14288 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14289
14290 /* Check port replicator headphone socket */
864f92be 14291 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14292
5dbd5ec6 14293 bits = present ? HDA_AMP_MUTE : 0;
64154835 14294 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14295 HDA_AMP_MUTE, bits);
64154835 14296 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14297 HDA_AMP_MUTE, bits);
64154835
TV
14298
14299 snd_hda_codec_write(codec, 0x20, 0,
14300 AC_VERB_SET_COEF_INDEX, 0x0c);
14301 snd_hda_codec_write(codec, 0x20, 0,
14302 AC_VERB_SET_PROC_COEF, 0x680);
14303
14304 snd_hda_codec_write(codec, 0x20, 0,
14305 AC_VERB_SET_COEF_INDEX, 0x0c);
14306 snd_hda_codec_write(codec, 0x20, 0,
14307 AC_VERB_SET_PROC_COEF, 0x480);
14308}
14309
64154835
TV
14310static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14311{
14312 unsigned int present_laptop;
14313 unsigned int present_dock;
14314
864f92be
WF
14315 present_laptop = snd_hda_jack_detect(codec, 0x18);
14316 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14317
14318 /* Laptop mic port overrides dock mic port, design decision */
14319 if (present_dock)
14320 snd_hda_codec_write(codec, 0x23, 0,
14321 AC_VERB_SET_CONNECT_SEL, 0x3);
14322 if (present_laptop)
14323 snd_hda_codec_write(codec, 0x23, 0,
14324 AC_VERB_SET_CONNECT_SEL, 0x0);
14325 if (!present_dock && !present_laptop)
14326 snd_hda_codec_write(codec, 0x23, 0,
14327 AC_VERB_SET_CONNECT_SEL, 0x1);
14328}
14329
60db6b53
KY
14330static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14331 unsigned int res)
14332{
4f5d1706
TI
14333 switch (res >> 26) {
14334 case ALC880_HP_EVENT:
60db6b53 14335 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14336 break;
14337 case ALC880_MIC_EVENT:
14338 alc_mic_automute(codec);
14339 break;
14340 }
60db6b53 14341}
f6a92248 14342
64154835
TV
14343static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14344 unsigned int res)
14345{
14346 if ((res >> 26) == ALC880_HP_EVENT)
14347 alc269_lifebook_speaker_automute(codec);
14348 if ((res >> 26) == ALC880_MIC_EVENT)
14349 alc269_lifebook_mic_autoswitch(codec);
14350}
14351
4f5d1706
TI
14352static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14353{
14354 struct alc_spec *spec = codec->spec;
20645d70
TI
14355 spec->autocfg.hp_pins[0] = 0x15;
14356 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14357 spec->ext_mic.pin = 0x18;
14358 spec->ext_mic.mux_idx = 0;
14359 spec->int_mic.pin = 0x19;
14360 spec->int_mic.mux_idx = 1;
14361 spec->auto_mic = 1;
14362}
14363
60db6b53
KY
14364static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14365{
14366 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14367 alc_mic_automute(codec);
60db6b53 14368}
f6a92248 14369
64154835
TV
14370static void alc269_lifebook_init_hook(struct hda_codec *codec)
14371{
14372 alc269_lifebook_speaker_automute(codec);
14373 alc269_lifebook_mic_autoswitch(codec);
14374}
14375
84898e87 14376static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14377 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14378 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14379 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14380 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14381 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14382 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14383 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14384 {}
14385};
14386
84898e87 14387static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14388 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14389 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14390 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14391 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14392 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14393 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14394 {}
14395};
14396
84898e87
KY
14397static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14398 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14399 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14400 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14401 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14402 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14403 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14404 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14405 {}
14406};
14407
14408static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14409 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14410 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14411 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14412 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14413 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14414 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14415 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14416 {}
14417};
14418
fe3eb0a7
KY
14419static struct hda_verb alc271_acer_dmic_verbs[] = {
14420 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14421 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14422 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14423 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14424 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14425 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14426 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14427 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14428 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14429 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14430 { }
14431};
14432
f53281e6
KY
14433/* toggle speaker-output according to the hp-jack state */
14434static void alc269_speaker_automute(struct hda_codec *codec)
14435{
ebb83eeb
KY
14436 struct alc_spec *spec = codec->spec;
14437 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14438 unsigned int present;
60db6b53 14439 unsigned char bits;
f53281e6 14440
ebb83eeb 14441 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14442 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14443 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14444 HDA_AMP_MUTE, bits);
f53281e6 14445 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14446 HDA_AMP_MUTE, bits);
cd372fb3 14447 snd_hda_input_jack_report(codec, nid);
f53281e6
KY
14448}
14449
f53281e6 14450/* unsolicited event for HP jack sensing */
84898e87 14451static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14452 unsigned int res)
f53281e6 14453{
4f5d1706
TI
14454 switch (res >> 26) {
14455 case ALC880_HP_EVENT:
f53281e6 14456 alc269_speaker_automute(codec);
4f5d1706
TI
14457 break;
14458 case ALC880_MIC_EVENT:
14459 alc_mic_automute(codec);
14460 break;
14461 }
f53281e6
KY
14462}
14463
226b1ec8 14464static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14465{
4f5d1706 14466 struct alc_spec *spec = codec->spec;
20645d70
TI
14467 spec->autocfg.hp_pins[0] = 0x15;
14468 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14469 spec->ext_mic.pin = 0x18;
14470 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14471 spec->int_mic.pin = 0x19;
14472 spec->int_mic.mux_idx = 1;
4f5d1706 14473 spec->auto_mic = 1;
f53281e6
KY
14474}
14475
226b1ec8 14476static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14477{
14478 struct alc_spec *spec = codec->spec;
20645d70
TI
14479 spec->autocfg.hp_pins[0] = 0x15;
14480 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14481 spec->ext_mic.pin = 0x18;
14482 spec->ext_mic.mux_idx = 0;
14483 spec->int_mic.pin = 0x12;
226b1ec8 14484 spec->int_mic.mux_idx = 5;
84898e87
KY
14485 spec->auto_mic = 1;
14486}
14487
226b1ec8 14488static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14489{
4f5d1706 14490 struct alc_spec *spec = codec->spec;
226b1ec8 14491 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14492 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14493 spec->ext_mic.pin = 0x18;
14494 spec->ext_mic.mux_idx = 0;
14495 spec->int_mic.pin = 0x19;
14496 spec->int_mic.mux_idx = 1;
14497 spec->auto_mic = 1;
f53281e6
KY
14498}
14499
226b1ec8
KY
14500static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14501{
14502 struct alc_spec *spec = codec->spec;
14503 spec->autocfg.hp_pins[0] = 0x21;
14504 spec->autocfg.speaker_pins[0] = 0x14;
14505 spec->ext_mic.pin = 0x18;
14506 spec->ext_mic.mux_idx = 0;
14507 spec->int_mic.pin = 0x12;
14508 spec->int_mic.mux_idx = 6;
14509 spec->auto_mic = 1;
14510}
14511
84898e87 14512static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14513{
14514 alc269_speaker_automute(codec);
4f5d1706 14515 alc_mic_automute(codec);
f53281e6
KY
14516}
14517
60db6b53
KY
14518/*
14519 * generic initialization of ADC, input mixers and output mixers
14520 */
14521static struct hda_verb alc269_init_verbs[] = {
14522 /*
14523 * Unmute ADC0 and set the default input to mic-in
14524 */
84898e87 14525 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14526
14527 /*
84898e87 14528 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14529 */
14530 /* set vol=0 to output mixers */
14531 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14532 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14533
14534 /* set up input amps for analog loopback */
14535 /* Amp Indices: DAC = 0, mixer = 1 */
14536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14537 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14538 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14539 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14540 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14541 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14542
14543 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14545 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14546 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14547 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14548 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14549 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14550
14551 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14553
84898e87
KY
14554 /* FIXME: use Mux-type input source selection */
14555 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14556 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14557 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14558
84898e87
KY
14559 /* set EAPD */
14560 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14561 { }
14562};
14563
14564static struct hda_verb alc269vb_init_verbs[] = {
14565 /*
14566 * Unmute ADC0 and set the default input to mic-in
14567 */
14568 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14569
14570 /*
14571 * Set up output mixers (0x02 - 0x03)
14572 */
14573 /* set vol=0 to output mixers */
14574 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14575 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14576
14577 /* set up input amps for analog loopback */
14578 /* Amp Indices: DAC = 0, mixer = 1 */
14579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14580 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14581 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14582 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14583 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14584 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14585
14586 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14587 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14588 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14589 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14590 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14591 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14592 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14593
14594 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14595 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14596
14597 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14598 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14599 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14600 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14601
14602 /* set EAPD */
14603 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14604 { }
14605};
14606
9d0b71b1
TI
14607#define alc269_auto_create_multi_out_ctls \
14608 alc268_auto_create_multi_out_ctls
05f5f477
TI
14609#define alc269_auto_create_input_ctls \
14610 alc268_auto_create_input_ctls
f6a92248
KY
14611
14612#ifdef CONFIG_SND_HDA_POWER_SAVE
14613#define alc269_loopbacks alc880_loopbacks
14614#endif
14615
def319f9 14616/* pcm configuration: identical with ALC880 */
f6a92248
KY
14617#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14618#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14619#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14620#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14621
f03d3115
TI
14622static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14623 .substreams = 1,
14624 .channels_min = 2,
14625 .channels_max = 8,
14626 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14627 /* NID is set in alc_build_pcms */
14628 .ops = {
14629 .open = alc880_playback_pcm_open,
14630 .prepare = alc880_playback_pcm_prepare,
14631 .cleanup = alc880_playback_pcm_cleanup
14632 },
14633};
14634
14635static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14636 .substreams = 1,
14637 .channels_min = 2,
14638 .channels_max = 2,
14639 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14640 /* NID is set in alc_build_pcms */
14641};
14642
ad35879a
TI
14643#ifdef CONFIG_SND_HDA_POWER_SAVE
14644static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14645{
14646 switch (codec->subsystem_id) {
14647 case 0x103c1586:
14648 return 1;
14649 }
14650 return 0;
14651}
14652
14653static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14654{
14655 /* update mute-LED according to the speaker mute state */
14656 if (nid == 0x01 || nid == 0x14) {
14657 int pinval;
14658 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14659 HDA_AMP_MUTE)
14660 pinval = 0x24;
14661 else
14662 pinval = 0x20;
14663 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14664 snd_hda_codec_update_cache(codec, 0x19, 0,
14665 AC_VERB_SET_PIN_WIDGET_CONTROL,
14666 pinval);
ad35879a
TI
14667 }
14668 return alc_check_power_status(codec, nid);
14669}
14670#endif /* CONFIG_SND_HDA_POWER_SAVE */
14671
840b64c0
TI
14672static int alc275_setup_dual_adc(struct hda_codec *codec)
14673{
14674 struct alc_spec *spec = codec->spec;
14675
14676 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14677 return 0;
14678 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14679 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14680 if (spec->ext_mic.pin <= 0x12) {
14681 spec->private_adc_nids[0] = 0x08;
14682 spec->private_adc_nids[1] = 0x11;
14683 spec->private_capsrc_nids[0] = 0x23;
14684 spec->private_capsrc_nids[1] = 0x22;
14685 } else {
14686 spec->private_adc_nids[0] = 0x11;
14687 spec->private_adc_nids[1] = 0x08;
14688 spec->private_capsrc_nids[0] = 0x22;
14689 spec->private_capsrc_nids[1] = 0x23;
14690 }
14691 spec->adc_nids = spec->private_adc_nids;
14692 spec->capsrc_nids = spec->private_capsrc_nids;
14693 spec->num_adc_nids = 2;
14694 spec->dual_adc_switch = 1;
14695 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14696 spec->adc_nids[0], spec->adc_nids[1]);
14697 return 1;
14698 }
14699 return 0;
14700}
14701
d433a678
TI
14702/* different alc269-variants */
14703enum {
14704 ALC269_TYPE_NORMAL,
48c88e82 14705 ALC269_TYPE_ALC258,
d433a678 14706 ALC269_TYPE_ALC259,
48c88e82
KY
14707 ALC269_TYPE_ALC269VB,
14708 ALC269_TYPE_ALC270,
d433a678
TI
14709 ALC269_TYPE_ALC271X,
14710};
14711
f6a92248
KY
14712/*
14713 * BIOS auto configuration
14714 */
14715static int alc269_parse_auto_config(struct hda_codec *codec)
14716{
14717 struct alc_spec *spec = codec->spec;
cfb9fb55 14718 int err;
f6a92248
KY
14719 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14720
14721 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14722 alc269_ignore);
14723 if (err < 0)
14724 return err;
14725
14726 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14727 if (err < 0)
14728 return err;
f3550d1b
TI
14729 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14730 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14731 else
14732 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14733 0x22, 0);
f6a92248
KY
14734 if (err < 0)
14735 return err;
14736
14737 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14738
757899ac 14739 alc_auto_parse_digital(codec);
f6a92248 14740
603c4019 14741 if (spec->kctls.list)
d88897ea 14742 add_mixer(spec, spec->kctls.list);
f6a92248 14743
d433a678 14744 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14745 add_verb(spec, alc269vb_init_verbs);
6227cdce 14746 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14747 } else {
14748 add_verb(spec, alc269_init_verbs);
6227cdce 14749 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14750 }
14751
f6a92248 14752 spec->num_mux_defs = 1;
61b9b9b1 14753 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14754
14755 if (!alc275_setup_dual_adc(codec))
14756 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14757 sizeof(alc269_adc_candidates));
6694635d 14758
e01bf509 14759 /* set default input source */
840b64c0 14760 if (!spec->dual_adc_switch)
748cce43
TI
14761 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14762 spec->input_mux->items[0].index);
f6a92248
KY
14763
14764 err = alc_auto_add_mic_boost(codec);
14765 if (err < 0)
14766 return err;
14767
7e0e44d4 14768 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14769 set_capture_mixer(codec);
f53281e6 14770
f6a92248
KY
14771 return 1;
14772}
14773
e9af4f36
TI
14774#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14775#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14776#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14777
14778
14779/* init callback for auto-configuration model -- overriding the default init */
14780static void alc269_auto_init(struct hda_codec *codec)
14781{
f6c7e546 14782 struct alc_spec *spec = codec->spec;
f6a92248
KY
14783 alc269_auto_init_multi_out(codec);
14784 alc269_auto_init_hp_out(codec);
14785 alc269_auto_init_analog_input(codec);
757899ac 14786 alc_auto_init_digital(codec);
f6c7e546 14787 if (spec->unsol_event)
7fb0d78f 14788 alc_inithook(codec);
f6a92248
KY
14789}
14790
0ec33d1f
TI
14791#ifdef SND_HDA_NEEDS_RESUME
14792static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14793{
14794 int val = alc_read_coef_idx(codec, 0x04);
14795 if (power_up)
14796 val |= 1 << 11;
14797 else
14798 val &= ~(1 << 11);
14799 alc_write_coef_idx(codec, 0x04, val);
14800}
14801
977ddd6b
KY
14802#ifdef CONFIG_SND_HDA_POWER_SAVE
14803static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14804{
14805 struct alc_spec *spec = codec->spec;
977ddd6b 14806
0ec33d1f
TI
14807 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14808 alc269_toggle_power_output(codec, 0);
977ddd6b 14809 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14810 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14811 msleep(150);
14812 }
14813
14814 alc_shutup(codec);
14815 if (spec && spec->power_hook)
14816 spec->power_hook(codec);
14817 return 0;
14818}
0ec33d1f
TI
14819#endif /* CONFIG_SND_HDA_POWER_SAVE */
14820
977ddd6b
KY
14821static int alc269_resume(struct hda_codec *codec)
14822{
977ddd6b 14823 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14824 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14825 msleep(150);
14826 }
14827
14828 codec->patch_ops.init(codec);
14829
14830 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14831 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14832 msleep(200);
14833 }
14834
0ec33d1f
TI
14835 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14836 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14837
14838 snd_hda_codec_resume_amp(codec);
14839 snd_hda_codec_resume_cache(codec);
9e5341b9 14840 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14841 return 0;
14842}
0ec33d1f 14843#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14844
1a99d4a4 14845static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14846 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14847{
14848 int coef;
14849
58701120 14850 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14851 return;
1a99d4a4
KY
14852 coef = alc_read_coef_idx(codec, 0x1e);
14853 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14854}
14855
ff818c24
TI
14856enum {
14857 ALC269_FIXUP_SONY_VAIO,
74dc8909 14858 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14859 ALC269_FIXUP_DELL_M101Z,
022c92be 14860 ALC269_FIXUP_SKU_IGNORE,
ac612407 14861 ALC269_FIXUP_ASUS_G73JW,
357f915e 14862 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14863 ALC275_FIXUP_SONY_HWEQ,
ff818c24
TI
14864};
14865
ff818c24
TI
14866static const struct alc_fixup alc269_fixups[] = {
14867 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14868 .type = ALC_FIXUP_VERBS,
14869 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14870 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14871 {}
14872 }
ff818c24 14873 },
74dc8909 14874 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14875 .type = ALC_FIXUP_VERBS,
14876 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14877 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14878 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14879 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14880 { }
b5bfbc67
TI
14881 },
14882 .chained = true,
14883 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14884 },
145a902b 14885 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14886 .type = ALC_FIXUP_VERBS,
14887 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14888 /* Enables internal speaker */
14889 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14890 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14891 {}
14892 }
14893 },
022c92be 14894 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14895 .type = ALC_FIXUP_SKU,
14896 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14897 },
ac612407 14898 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14899 .type = ALC_FIXUP_PINS,
14900 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14901 { 0x17, 0x99130111 }, /* subwoofer */
14902 { }
14903 }
14904 },
357f915e 14905 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14906 .type = ALC_FIXUP_VERBS,
14907 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14908 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14909 {}
14910 }
14911 },
1a99d4a4 14912 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14913 .type = ALC_FIXUP_FUNC,
14914 .v.func = alc269_fixup_hweq,
14915 .chained = true,
14916 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
1a99d4a4 14917 }
ff818c24
TI
14918};
14919
14920static struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14921 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14922 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14923 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14924 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14925 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
022c92be 14926 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14927 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14928 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14929 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14930 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14931 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14932 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14933 {}
14934};
14935
14936
f6a92248
KY
14937/*
14938 * configuration and preset
14939 */
ea734963 14940static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14941 [ALC269_BASIC] = "basic",
2922c9af 14942 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14943 [ALC269_AMIC] = "laptop-amic",
14944 [ALC269_DMIC] = "laptop-dmic",
64154835 14945 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14946 [ALC269_LIFEBOOK] = "lifebook",
14947 [ALC269_AUTO] = "auto",
f6a92248
KY
14948};
14949
14950static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14951 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14952 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14953 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14954 ALC269_AMIC),
14955 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14956 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14957 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14958 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14959 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14960 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14961 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14962 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14963 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14964 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14965 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14966 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14967 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14968 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14969 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14970 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14971 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14972 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14973 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14974 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14975 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14976 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14977 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14978 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14979 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14980 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14981 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14982 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14983 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14984 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14985 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14986 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14987 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14988 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14989 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14990 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14991 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14992 ALC269_DMIC),
60db6b53 14993 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14994 ALC269_DMIC),
14995 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14996 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14997 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14998 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14999 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15000 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15001 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15002 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15003 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15004 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
15005 {}
15006};
15007
15008static struct alc_config_preset alc269_presets[] = {
15009 [ALC269_BASIC] = {
f9e336f6 15010 .mixers = { alc269_base_mixer },
f6a92248
KY
15011 .init_verbs = { alc269_init_verbs },
15012 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15013 .dac_nids = alc269_dac_nids,
15014 .hp_nid = 0x03,
15015 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15016 .channel_mode = alc269_modes,
15017 .input_mux = &alc269_capture_source,
15018 },
60db6b53
KY
15019 [ALC269_QUANTA_FL1] = {
15020 .mixers = { alc269_quanta_fl1_mixer },
15021 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15022 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15023 .dac_nids = alc269_dac_nids,
15024 .hp_nid = 0x03,
15025 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15026 .channel_mode = alc269_modes,
15027 .input_mux = &alc269_capture_source,
15028 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15029 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15030 .init_hook = alc269_quanta_fl1_init_hook,
15031 },
84898e87
KY
15032 [ALC269_AMIC] = {
15033 .mixers = { alc269_laptop_mixer },
15034 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15035 .init_verbs = { alc269_init_verbs,
84898e87 15036 alc269_laptop_amic_init_verbs },
f53281e6
KY
15037 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15038 .dac_nids = alc269_dac_nids,
15039 .hp_nid = 0x03,
15040 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15041 .channel_mode = alc269_modes,
84898e87
KY
15042 .unsol_event = alc269_laptop_unsol_event,
15043 .setup = alc269_laptop_amic_setup,
15044 .init_hook = alc269_laptop_inithook,
f53281e6 15045 },
84898e87
KY
15046 [ALC269_DMIC] = {
15047 .mixers = { alc269_laptop_mixer },
15048 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15049 .init_verbs = { alc269_init_verbs,
84898e87
KY
15050 alc269_laptop_dmic_init_verbs },
15051 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15052 .dac_nids = alc269_dac_nids,
15053 .hp_nid = 0x03,
15054 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15055 .channel_mode = alc269_modes,
15056 .unsol_event = alc269_laptop_unsol_event,
15057 .setup = alc269_laptop_dmic_setup,
15058 .init_hook = alc269_laptop_inithook,
15059 },
15060 [ALC269VB_AMIC] = {
15061 .mixers = { alc269vb_laptop_mixer },
15062 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15063 .init_verbs = { alc269vb_init_verbs,
15064 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15065 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15066 .dac_nids = alc269_dac_nids,
15067 .hp_nid = 0x03,
15068 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15069 .channel_mode = alc269_modes,
84898e87 15070 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 15071 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
15072 .init_hook = alc269_laptop_inithook,
15073 },
15074 [ALC269VB_DMIC] = {
15075 .mixers = { alc269vb_laptop_mixer },
15076 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15077 .init_verbs = { alc269vb_init_verbs,
15078 alc269vb_laptop_dmic_init_verbs },
15079 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15080 .dac_nids = alc269_dac_nids,
15081 .hp_nid = 0x03,
15082 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15083 .channel_mode = alc269_modes,
15084 .unsol_event = alc269_laptop_unsol_event,
15085 .setup = alc269vb_laptop_dmic_setup,
15086 .init_hook = alc269_laptop_inithook,
f53281e6 15087 },
26f5df26 15088 [ALC269_FUJITSU] = {
45bdd1c1 15089 .mixers = { alc269_fujitsu_mixer },
84898e87 15090 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15091 .init_verbs = { alc269_init_verbs,
84898e87 15092 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15093 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15094 .dac_nids = alc269_dac_nids,
15095 .hp_nid = 0x03,
15096 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15097 .channel_mode = alc269_modes,
84898e87
KY
15098 .unsol_event = alc269_laptop_unsol_event,
15099 .setup = alc269_laptop_dmic_setup,
15100 .init_hook = alc269_laptop_inithook,
26f5df26 15101 },
64154835
TV
15102 [ALC269_LIFEBOOK] = {
15103 .mixers = { alc269_lifebook_mixer },
15104 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15105 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15106 .dac_nids = alc269_dac_nids,
15107 .hp_nid = 0x03,
15108 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15109 .channel_mode = alc269_modes,
15110 .input_mux = &alc269_capture_source,
15111 .unsol_event = alc269_lifebook_unsol_event,
15112 .init_hook = alc269_lifebook_init_hook,
15113 },
fe3eb0a7
KY
15114 [ALC271_ACER] = {
15115 .mixers = { alc269_asus_mixer },
15116 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15117 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15118 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15119 .dac_nids = alc269_dac_nids,
15120 .adc_nids = alc262_dmic_adc_nids,
15121 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15122 .capsrc_nids = alc262_dmic_capsrc_nids,
15123 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15124 .channel_mode = alc269_modes,
15125 .input_mux = &alc269_capture_source,
15126 .dig_out_nid = ALC880_DIGOUT_NID,
15127 .unsol_event = alc_sku_unsol_event,
15128 .setup = alc269vb_laptop_dmic_setup,
15129 .init_hook = alc_inithook,
15130 },
f6a92248
KY
15131};
15132
977ddd6b
KY
15133static int alc269_fill_coef(struct hda_codec *codec)
15134{
15135 int val;
15136
15137 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15138 alc_write_coef_idx(codec, 0xf, 0x960b);
15139 alc_write_coef_idx(codec, 0xe, 0x8817);
15140 }
15141
15142 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15143 alc_write_coef_idx(codec, 0xf, 0x960b);
15144 alc_write_coef_idx(codec, 0xe, 0x8814);
15145 }
15146
15147 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15148 val = alc_read_coef_idx(codec, 0x04);
15149 /* Power up output pin */
15150 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15151 }
15152
15153 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15154 val = alc_read_coef_idx(codec, 0xd);
15155 if ((val & 0x0c00) >> 10 != 0x1) {
15156 /* Capless ramp up clock control */
15157 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15158 }
15159 val = alc_read_coef_idx(codec, 0x17);
15160 if ((val & 0x01c0) >> 6 != 0x4) {
15161 /* Class D power on reset */
15162 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15163 }
15164 }
15165 return 0;
15166}
15167
f6a92248
KY
15168static int patch_alc269(struct hda_codec *codec)
15169{
15170 struct alc_spec *spec;
48c88e82 15171 int board_config, coef;
f6a92248
KY
15172 int err;
15173
15174 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15175 if (spec == NULL)
15176 return -ENOMEM;
15177
15178 codec->spec = spec;
15179
da00c244
KY
15180 alc_auto_parse_customize_define(codec);
15181
c793bec5
KY
15182 if (codec->vendor_id == 0x10ec0269) {
15183 coef = alc_read_coef_idx(codec, 0);
15184 if ((coef & 0x00f0) == 0x0010) {
15185 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15186 spec->cdefine.platform_type == 1) {
15187 alc_codec_rename(codec, "ALC271X");
15188 spec->codec_variant = ALC269_TYPE_ALC271X;
15189 } else if ((coef & 0xf000) == 0x1000) {
15190 spec->codec_variant = ALC269_TYPE_ALC270;
15191 } else if ((coef & 0xf000) == 0x2000) {
15192 alc_codec_rename(codec, "ALC259");
15193 spec->codec_variant = ALC269_TYPE_ALC259;
15194 } else if ((coef & 0xf000) == 0x3000) {
15195 alc_codec_rename(codec, "ALC258");
15196 spec->codec_variant = ALC269_TYPE_ALC258;
15197 } else {
15198 alc_codec_rename(codec, "ALC269VB");
15199 spec->codec_variant = ALC269_TYPE_ALC269VB;
15200 }
15201 } else
15202 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15203 alc269_fill_coef(codec);
15204 }
977ddd6b 15205
f6a92248
KY
15206 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15207 alc269_models,
15208 alc269_cfg_tbl);
15209
15210 if (board_config < 0) {
9a11f1aa
TI
15211 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15212 codec->chip_name);
f6a92248
KY
15213 board_config = ALC269_AUTO;
15214 }
15215
b5bfbc67
TI
15216 if (board_config == ALC269_AUTO) {
15217 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15218 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15219 }
ff818c24 15220
f6a92248
KY
15221 if (board_config == ALC269_AUTO) {
15222 /* automatic parse from the BIOS config */
15223 err = alc269_parse_auto_config(codec);
15224 if (err < 0) {
15225 alc_free(codec);
15226 return err;
15227 } else if (!err) {
15228 printk(KERN_INFO
15229 "hda_codec: Cannot set up configuration "
15230 "from BIOS. Using base mode...\n");
15231 board_config = ALC269_BASIC;
15232 }
15233 }
15234
dc1eae25 15235 if (has_cdefine_beep(codec)) {
8af2591d
TI
15236 err = snd_hda_attach_beep_device(codec, 0x1);
15237 if (err < 0) {
15238 alc_free(codec);
15239 return err;
15240 }
680cd536
KK
15241 }
15242
f6a92248 15243 if (board_config != ALC269_AUTO)
e9c364c0 15244 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15245
84898e87 15246 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15247 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15248 * fix the sample rate of analog I/O to 44.1kHz
15249 */
15250 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15251 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15252 } else if (spec->dual_adc_switch) {
15253 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15254 /* switch ADC dynamically */
15255 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15256 } else {
15257 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15258 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15259 }
f6a92248
KY
15260 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15261 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15262
6694635d 15263 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15264 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15265 spec->adc_nids = alc269_adc_nids;
15266 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15267 spec->capsrc_nids = alc269_capsrc_nids;
15268 } else {
15269 spec->adc_nids = alc269vb_adc_nids;
15270 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15271 spec->capsrc_nids = alc269vb_capsrc_nids;
15272 }
84898e87
KY
15273 }
15274
f9e336f6 15275 if (!spec->cap_mixer)
b59bdf3b 15276 set_capture_mixer(codec);
dc1eae25 15277 if (has_cdefine_beep(codec))
da00c244 15278 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15279
b5bfbc67 15280 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15281
100d5eb3
TI
15282 spec->vmaster_nid = 0x02;
15283
f6a92248 15284 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15285#ifdef CONFIG_SND_HDA_POWER_SAVE
15286 codec->patch_ops.suspend = alc269_suspend;
15287#endif
15288#ifdef SND_HDA_NEEDS_RESUME
15289 codec->patch_ops.resume = alc269_resume;
15290#endif
f6a92248
KY
15291 if (board_config == ALC269_AUTO)
15292 spec->init_hook = alc269_auto_init;
bf1b0225
KY
15293
15294 alc_init_jacks(codec);
f6a92248
KY
15295#ifdef CONFIG_SND_HDA_POWER_SAVE
15296 if (!spec->loopback.amplist)
15297 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15298 if (alc269_mic2_for_mute_led(codec))
15299 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15300#endif
15301
15302 return 0;
15303}
15304
df694daa
KY
15305/*
15306 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15307 */
15308
15309/*
15310 * set the path ways for 2 channel output
15311 * need to set the codec line out and mic 1 pin widgets to inputs
15312 */
15313static struct hda_verb alc861_threestack_ch2_init[] = {
15314 /* set pin widget 1Ah (line in) for input */
15315 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15316 /* set pin widget 18h (mic1/2) for input, for mic also enable
15317 * the vref
15318 */
df694daa
KY
15319 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15320
9c7f852e
TI
15321 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15322#if 0
15323 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15324 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15325#endif
df694daa
KY
15326 { } /* end */
15327};
15328/*
15329 * 6ch mode
15330 * need to set the codec line out and mic 1 pin widgets to outputs
15331 */
15332static struct hda_verb alc861_threestack_ch6_init[] = {
15333 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15334 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15335 /* set pin widget 18h (mic1) for output (CLFE)*/
15336 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15337
15338 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15339 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15340
9c7f852e
TI
15341 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15342#if 0
15343 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15344 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15345#endif
df694daa
KY
15346 { } /* end */
15347};
15348
15349static struct hda_channel_mode alc861_threestack_modes[2] = {
15350 { 2, alc861_threestack_ch2_init },
15351 { 6, alc861_threestack_ch6_init },
15352};
22309c3e
TI
15353/* Set mic1 as input and unmute the mixer */
15354static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15355 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15356 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15357 { } /* end */
15358};
15359/* Set mic1 as output and mute mixer */
15360static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15361 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15362 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15363 { } /* end */
15364};
15365
15366static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15367 { 2, alc861_uniwill_m31_ch2_init },
15368 { 4, alc861_uniwill_m31_ch4_init },
15369};
df694daa 15370
7cdbff94
MD
15371/* Set mic1 and line-in as input and unmute the mixer */
15372static struct hda_verb alc861_asus_ch2_init[] = {
15373 /* set pin widget 1Ah (line in) for input */
15374 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15375 /* set pin widget 18h (mic1/2) for input, for mic also enable
15376 * the vref
15377 */
7cdbff94
MD
15378 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15379
15380 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15381#if 0
15382 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15383 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15384#endif
15385 { } /* end */
15386};
15387/* Set mic1 nad line-in as output and mute mixer */
15388static struct hda_verb alc861_asus_ch6_init[] = {
15389 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15390 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15391 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15392 /* set pin widget 18h (mic1) for output (CLFE)*/
15393 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15394 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15395 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15396 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15397
15398 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15399#if 0
15400 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15401 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15402#endif
15403 { } /* end */
15404};
15405
15406static struct hda_channel_mode alc861_asus_modes[2] = {
15407 { 2, alc861_asus_ch2_init },
15408 { 6, alc861_asus_ch6_init },
15409};
15410
df694daa
KY
15411/* patch-ALC861 */
15412
15413static struct snd_kcontrol_new alc861_base_mixer[] = {
15414 /* output mixer control */
15415 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15416 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15417 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15418 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15419 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15420
15421 /*Input mixer control */
15422 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15423 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15424 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15425 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15426 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15427 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15428 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15429 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15430 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15431 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15432
df694daa
KY
15433 { } /* end */
15434};
15435
15436static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15437 /* output mixer control */
15438 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15439 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15440 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15441 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15442 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15443
15444 /* Input mixer control */
15445 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15446 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15447 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15448 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15449 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15450 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15452 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15453 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15454 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15455
df694daa
KY
15456 {
15457 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15458 .name = "Channel Mode",
15459 .info = alc_ch_mode_info,
15460 .get = alc_ch_mode_get,
15461 .put = alc_ch_mode_put,
15462 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15463 },
15464 { } /* end */
a53d1aec
TD
15465};
15466
d1d985f0 15467static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15468 /* output mixer control */
15469 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15470 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15471 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15472
a53d1aec 15473 { } /* end */
f12ab1e0 15474};
a53d1aec 15475
22309c3e
TI
15476static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15477 /* output mixer control */
15478 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15479 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15480 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15481 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15482 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15483
15484 /* Input mixer control */
15485 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15486 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15487 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15488 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15489 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15490 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15491 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15492 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15493 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15494 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15495
22309c3e
TI
15496 {
15497 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15498 .name = "Channel Mode",
15499 .info = alc_ch_mode_info,
15500 .get = alc_ch_mode_get,
15501 .put = alc_ch_mode_put,
15502 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15503 },
15504 { } /* end */
f12ab1e0 15505};
7cdbff94
MD
15506
15507static struct snd_kcontrol_new alc861_asus_mixer[] = {
15508 /* output mixer control */
15509 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15510 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15511 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15512 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15513 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15514
15515 /* Input mixer control */
15516 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15517 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15518 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15519 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15520 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15521 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15523 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15524 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15525 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15526
7cdbff94
MD
15527 {
15528 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15529 .name = "Channel Mode",
15530 .info = alc_ch_mode_info,
15531 .get = alc_ch_mode_get,
15532 .put = alc_ch_mode_put,
15533 .private_value = ARRAY_SIZE(alc861_asus_modes),
15534 },
15535 { }
56bb0cab
TI
15536};
15537
15538/* additional mixer */
d1d985f0 15539static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15540 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15541 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15542 { }
15543};
7cdbff94 15544
df694daa
KY
15545/*
15546 * generic initialization of ADC, input mixers and output mixers
15547 */
15548static struct hda_verb alc861_base_init_verbs[] = {
15549 /*
15550 * Unmute ADC0 and set the default input to mic-in
15551 */
15552 /* port-A for surround (rear panel) */
15553 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15554 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15555 /* port-B for mic-in (rear panel) with vref */
15556 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15557 /* port-C for line-in (rear panel) */
15558 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15559 /* port-D for Front */
15560 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15561 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15562 /* port-E for HP out (front panel) */
15563 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15564 /* route front PCM to HP */
9dece1d7 15565 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15566 /* port-F for mic-in (front panel) with vref */
15567 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15568 /* port-G for CLFE (rear panel) */
15569 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15570 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15571 /* port-H for side (rear panel) */
15572 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15573 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15574 /* CD-in */
15575 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15576 /* route front mic to ADC1*/
15577 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15578 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15579
df694daa
KY
15580 /* Unmute DAC0~3 & spdif out*/
15581 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15582 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15583 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15584 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15585 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15586
df694daa
KY
15587 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15588 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15589 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15590 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15591 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15592
df694daa
KY
15593 /* Unmute Stereo Mixer 15 */
15594 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15595 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15596 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15597 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15598
15599 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15600 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15601 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15602 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15603 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15604 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15605 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15606 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15607 /* hp used DAC 3 (Front) */
15608 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15609 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15610
15611 { }
15612};
15613
15614static struct hda_verb alc861_threestack_init_verbs[] = {
15615 /*
15616 * Unmute ADC0 and set the default input to mic-in
15617 */
15618 /* port-A for surround (rear panel) */
15619 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15620 /* port-B for mic-in (rear panel) with vref */
15621 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15622 /* port-C for line-in (rear panel) */
15623 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15624 /* port-D for Front */
15625 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15626 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15627 /* port-E for HP out (front panel) */
15628 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15629 /* route front PCM to HP */
9dece1d7 15630 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15631 /* port-F for mic-in (front panel) with vref */
15632 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15633 /* port-G for CLFE (rear panel) */
15634 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15635 /* port-H for side (rear panel) */
15636 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15637 /* CD-in */
15638 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15639 /* route front mic to ADC1*/
15640 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15641 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15642 /* Unmute DAC0~3 & spdif out*/
15643 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15644 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15645 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15646 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15647 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15648
df694daa
KY
15649 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15650 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15651 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15652 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15653 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15654
df694daa
KY
15655 /* Unmute Stereo Mixer 15 */
15656 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15657 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15658 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15659 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15660
15661 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15662 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15663 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15664 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15666 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15667 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15669 /* hp used DAC 3 (Front) */
15670 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15671 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15672 { }
15673};
22309c3e
TI
15674
15675static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15676 /*
15677 * Unmute ADC0 and set the default input to mic-in
15678 */
15679 /* port-A for surround (rear panel) */
15680 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15681 /* port-B for mic-in (rear panel) with vref */
15682 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15683 /* port-C for line-in (rear panel) */
15684 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15685 /* port-D for Front */
15686 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15687 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15688 /* port-E for HP out (front panel) */
f12ab1e0
TI
15689 /* this has to be set to VREF80 */
15690 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15691 /* route front PCM to HP */
9dece1d7 15692 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15693 /* port-F for mic-in (front panel) with vref */
15694 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15695 /* port-G for CLFE (rear panel) */
15696 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15697 /* port-H for side (rear panel) */
15698 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15699 /* CD-in */
15700 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15701 /* route front mic to ADC1*/
15702 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15703 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15704 /* Unmute DAC0~3 & spdif out*/
15705 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15706 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15707 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15708 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15709 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15710
22309c3e
TI
15711 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15712 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15713 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15714 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15715 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15716
22309c3e
TI
15717 /* Unmute Stereo Mixer 15 */
15718 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15720 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15721 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15722
15723 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15724 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15725 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15726 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15727 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15731 /* hp used DAC 3 (Front) */
15732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15733 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15734 { }
15735};
15736
7cdbff94
MD
15737static struct hda_verb alc861_asus_init_verbs[] = {
15738 /*
15739 * Unmute ADC0 and set the default input to mic-in
15740 */
f12ab1e0
TI
15741 /* port-A for surround (rear panel)
15742 * according to codec#0 this is the HP jack
15743 */
7cdbff94
MD
15744 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15745 /* route front PCM to HP */
15746 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15747 /* port-B for mic-in (rear panel) with vref */
15748 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15749 /* port-C for line-in (rear panel) */
15750 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15751 /* port-D for Front */
15752 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15753 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15754 /* port-E for HP out (front panel) */
f12ab1e0
TI
15755 /* this has to be set to VREF80 */
15756 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15757 /* route front PCM to HP */
9dece1d7 15758 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15759 /* port-F for mic-in (front panel) with vref */
15760 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15761 /* port-G for CLFE (rear panel) */
15762 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15763 /* port-H for side (rear panel) */
15764 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15765 /* CD-in */
15766 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15767 /* route front mic to ADC1*/
15768 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15769 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15770 /* Unmute DAC0~3 & spdif out*/
15771 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15772 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15773 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15774 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15775 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15776 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15777 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15778 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15779 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15780 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15781
7cdbff94
MD
15782 /* Unmute Stereo Mixer 15 */
15783 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15784 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15785 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15786 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15787
15788 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15789 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15790 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15791 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15792 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15793 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15794 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15795 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15796 /* hp used DAC 3 (Front) */
15797 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15798 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15799 { }
15800};
15801
56bb0cab
TI
15802/* additional init verbs for ASUS laptops */
15803static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15804 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15805 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15806 { }
15807};
7cdbff94 15808
df694daa
KY
15809/*
15810 * generic initialization of ADC, input mixers and output mixers
15811 */
15812static struct hda_verb alc861_auto_init_verbs[] = {
15813 /*
15814 * Unmute ADC0 and set the default input to mic-in
15815 */
f12ab1e0 15816 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15817 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15818
df694daa
KY
15819 /* Unmute DAC0~3 & spdif out*/
15820 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15821 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15822 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15823 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15824 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15825
df694daa
KY
15826 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15827 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15828 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15829 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15830 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15831
df694daa
KY
15832 /* Unmute Stereo Mixer 15 */
15833 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15834 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15835 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15836 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15837
1c20930a
TI
15838 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15839 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15840 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15841 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15842 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15843 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15844 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15845 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15846
15847 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15848 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15849 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15850 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15851 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15852 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15853 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15854 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15855
f12ab1e0 15856 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15857
15858 { }
15859};
15860
a53d1aec
TD
15861static struct hda_verb alc861_toshiba_init_verbs[] = {
15862 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15863
a53d1aec
TD
15864 { }
15865};
15866
15867/* toggle speaker-output according to the hp-jack state */
15868static void alc861_toshiba_automute(struct hda_codec *codec)
15869{
864f92be 15870 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15871
47fd830a
TI
15872 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15873 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15874 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15875 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15876}
15877
15878static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15879 unsigned int res)
15880{
a53d1aec
TD
15881 if ((res >> 26) == ALC880_HP_EVENT)
15882 alc861_toshiba_automute(codec);
15883}
15884
def319f9 15885/* pcm configuration: identical with ALC880 */
df694daa
KY
15886#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15887#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15888#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15889#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15890
15891
15892#define ALC861_DIGOUT_NID 0x07
15893
15894static struct hda_channel_mode alc861_8ch_modes[1] = {
15895 { 8, NULL }
15896};
15897
15898static hda_nid_t alc861_dac_nids[4] = {
15899 /* front, surround, clfe, side */
15900 0x03, 0x06, 0x05, 0x04
15901};
15902
9c7f852e
TI
15903static hda_nid_t alc660_dac_nids[3] = {
15904 /* front, clfe, surround */
15905 0x03, 0x05, 0x06
15906};
15907
df694daa
KY
15908static hda_nid_t alc861_adc_nids[1] = {
15909 /* ADC0-2 */
15910 0x08,
15911};
15912
15913static struct hda_input_mux alc861_capture_source = {
15914 .num_items = 5,
15915 .items = {
15916 { "Mic", 0x0 },
15917 { "Front Mic", 0x3 },
15918 { "Line", 0x1 },
15919 { "CD", 0x4 },
15920 { "Mixer", 0x5 },
15921 },
15922};
15923
1c20930a
TI
15924static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15925{
15926 struct alc_spec *spec = codec->spec;
15927 hda_nid_t mix, srcs[5];
15928 int i, j, num;
15929
15930 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15931 return 0;
15932 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15933 if (num < 0)
15934 return 0;
15935 for (i = 0; i < num; i++) {
15936 unsigned int type;
a22d543a 15937 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15938 if (type != AC_WID_AUD_OUT)
15939 continue;
15940 for (j = 0; j < spec->multiout.num_dacs; j++)
15941 if (spec->multiout.dac_nids[j] == srcs[i])
15942 break;
15943 if (j >= spec->multiout.num_dacs)
15944 return srcs[i];
15945 }
15946 return 0;
15947}
15948
df694daa 15949/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15950static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15951 const struct auto_pin_cfg *cfg)
df694daa 15952{
1c20930a 15953 struct alc_spec *spec = codec->spec;
df694daa 15954 int i;
1c20930a 15955 hda_nid_t nid, dac;
df694daa
KY
15956
15957 spec->multiout.dac_nids = spec->private_dac_nids;
15958 for (i = 0; i < cfg->line_outs; i++) {
15959 nid = cfg->line_out_pins[i];
1c20930a
TI
15960 dac = alc861_look_for_dac(codec, nid);
15961 if (!dac)
15962 continue;
15963 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15964 }
df694daa
KY
15965 return 0;
15966}
15967
bcb2f0f5
TI
15968static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15969 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15970{
bcb2f0f5 15971 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15972 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15973}
15974
bcb2f0f5
TI
15975#define alc861_create_out_sw(codec, pfx, nid, chs) \
15976 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15977
df694daa 15978/* add playback controls from the parsed DAC table */
1c20930a 15979static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15980 const struct auto_pin_cfg *cfg)
15981{
1c20930a 15982 struct alc_spec *spec = codec->spec;
ea734963 15983 static const char * const chname[4] = {
f12ab1e0
TI
15984 "Front", "Surround", NULL /*CLFE*/, "Side"
15985 };
bcb2f0f5 15986 const char *pfx = alc_get_line_out_pfx(cfg, true);
df694daa 15987 hda_nid_t nid;
1c20930a
TI
15988 int i, err;
15989
df694daa
KY
15990 for (i = 0; i < cfg->line_outs; i++) {
15991 nid = spec->multiout.dac_nids[i];
f12ab1e0 15992 if (!nid)
df694daa 15993 continue;
bcb2f0f5 15994 if (!pfx && i == 2) {
df694daa 15995 /* Center/LFE */
1c20930a 15996 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15997 if (err < 0)
df694daa 15998 return err;
1c20930a 15999 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 16000 if (err < 0)
df694daa
KY
16001 return err;
16002 } else {
bcb2f0f5
TI
16003 const char *name = pfx;
16004 if (!name)
16005 name = chname[i];
16006 err = __alc861_create_out_sw(codec, name, nid, i, 3);
f12ab1e0 16007 if (err < 0)
df694daa
KY
16008 return err;
16009 }
16010 }
16011 return 0;
16012}
16013
1c20930a 16014static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16015{
1c20930a 16016 struct alc_spec *spec = codec->spec;
df694daa
KY
16017 int err;
16018 hda_nid_t nid;
16019
f12ab1e0 16020 if (!pin)
df694daa
KY
16021 return 0;
16022
16023 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16024 nid = alc861_look_for_dac(codec, pin);
16025 if (nid) {
16026 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16027 if (err < 0)
16028 return err;
16029 spec->multiout.hp_nid = nid;
16030 }
df694daa
KY
16031 }
16032 return 0;
16033}
16034
16035/* create playback/capture controls for input pins */
05f5f477 16036static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16037 const struct auto_pin_cfg *cfg)
df694daa 16038{
05f5f477 16039 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16040}
16041
f12ab1e0
TI
16042static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16043 hda_nid_t nid,
1c20930a 16044 int pin_type, hda_nid_t dac)
df694daa 16045{
1c20930a
TI
16046 hda_nid_t mix, srcs[5];
16047 int i, num;
16048
564c5bea
JL
16049 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16050 pin_type);
1c20930a 16051 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16052 AMP_OUT_UNMUTE);
1c20930a
TI
16053 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16054 return;
16055 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16056 if (num < 0)
16057 return;
16058 for (i = 0; i < num; i++) {
16059 unsigned int mute;
16060 if (srcs[i] == dac || srcs[i] == 0x15)
16061 mute = AMP_IN_UNMUTE(i);
16062 else
16063 mute = AMP_IN_MUTE(i);
16064 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16065 mute);
16066 }
df694daa
KY
16067}
16068
16069static void alc861_auto_init_multi_out(struct hda_codec *codec)
16070{
16071 struct alc_spec *spec = codec->spec;
16072 int i;
16073
16074 for (i = 0; i < spec->autocfg.line_outs; i++) {
16075 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16076 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16077 if (nid)
baba8ee9 16078 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16079 spec->multiout.dac_nids[i]);
df694daa
KY
16080 }
16081}
16082
16083static void alc861_auto_init_hp_out(struct hda_codec *codec)
16084{
16085 struct alc_spec *spec = codec->spec;
df694daa 16086
15870f05
TI
16087 if (spec->autocfg.hp_outs)
16088 alc861_auto_set_output_and_unmute(codec,
16089 spec->autocfg.hp_pins[0],
16090 PIN_HP,
1c20930a 16091 spec->multiout.hp_nid);
15870f05
TI
16092 if (spec->autocfg.speaker_outs)
16093 alc861_auto_set_output_and_unmute(codec,
16094 spec->autocfg.speaker_pins[0],
16095 PIN_OUT,
1c20930a 16096 spec->multiout.dac_nids[0]);
df694daa
KY
16097}
16098
16099static void alc861_auto_init_analog_input(struct hda_codec *codec)
16100{
16101 struct alc_spec *spec = codec->spec;
66ceeb6b 16102 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16103 int i;
16104
66ceeb6b
TI
16105 for (i = 0; i < cfg->num_inputs; i++) {
16106 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16107 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16108 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16109 }
16110}
16111
16112/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16113/* return 1 if successful, 0 if the proper config is not found,
16114 * or a negative error code
16115 */
df694daa
KY
16116static int alc861_parse_auto_config(struct hda_codec *codec)
16117{
16118 struct alc_spec *spec = codec->spec;
16119 int err;
16120 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16121
f12ab1e0
TI
16122 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16123 alc861_ignore);
16124 if (err < 0)
df694daa 16125 return err;
f12ab1e0 16126 if (!spec->autocfg.line_outs)
df694daa
KY
16127 return 0; /* can't find valid BIOS pin config */
16128
1c20930a 16129 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
16130 if (err < 0)
16131 return err;
1c20930a 16132 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16133 if (err < 0)
16134 return err;
1c20930a 16135 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16136 if (err < 0)
16137 return err;
05f5f477 16138 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16139 if (err < 0)
df694daa
KY
16140 return err;
16141
16142 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16143
757899ac 16144 alc_auto_parse_digital(codec);
df694daa 16145
603c4019 16146 if (spec->kctls.list)
d88897ea 16147 add_mixer(spec, spec->kctls.list);
df694daa 16148
d88897ea 16149 add_verb(spec, alc861_auto_init_verbs);
df694daa 16150
a1e8d2da 16151 spec->num_mux_defs = 1;
61b9b9b1 16152 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16153
16154 spec->adc_nids = alc861_adc_nids;
16155 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16156 set_capture_mixer(codec);
df694daa 16157
6227cdce 16158 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16159
df694daa
KY
16160 return 1;
16161}
16162
ae6b813a
TI
16163/* additional initialization for auto-configuration model */
16164static void alc861_auto_init(struct hda_codec *codec)
df694daa 16165{
f6c7e546 16166 struct alc_spec *spec = codec->spec;
df694daa
KY
16167 alc861_auto_init_multi_out(codec);
16168 alc861_auto_init_hp_out(codec);
16169 alc861_auto_init_analog_input(codec);
757899ac 16170 alc_auto_init_digital(codec);
f6c7e546 16171 if (spec->unsol_event)
7fb0d78f 16172 alc_inithook(codec);
df694daa
KY
16173}
16174
cb53c626
TI
16175#ifdef CONFIG_SND_HDA_POWER_SAVE
16176static struct hda_amp_list alc861_loopbacks[] = {
16177 { 0x15, HDA_INPUT, 0 },
16178 { 0x15, HDA_INPUT, 1 },
16179 { 0x15, HDA_INPUT, 2 },
16180 { 0x15, HDA_INPUT, 3 },
16181 { } /* end */
16182};
16183#endif
16184
df694daa
KY
16185
16186/*
16187 * configuration and preset
16188 */
ea734963 16189static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16190 [ALC861_3ST] = "3stack",
16191 [ALC660_3ST] = "3stack-660",
16192 [ALC861_3ST_DIG] = "3stack-dig",
16193 [ALC861_6ST_DIG] = "6stack-dig",
16194 [ALC861_UNIWILL_M31] = "uniwill-m31",
16195 [ALC861_TOSHIBA] = "toshiba",
16196 [ALC861_ASUS] = "asus",
16197 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16198 [ALC861_AUTO] = "auto",
16199};
16200
16201static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16202 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16203 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16204 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16205 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16206 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16207 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16208 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16209 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16210 * Any other models that need this preset?
16211 */
16212 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16213 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16214 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16215 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16216 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16217 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16218 /* FIXME: the below seems conflict */
16219 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16220 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16221 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16222 {}
16223};
16224
16225static struct alc_config_preset alc861_presets[] = {
16226 [ALC861_3ST] = {
16227 .mixers = { alc861_3ST_mixer },
16228 .init_verbs = { alc861_threestack_init_verbs },
16229 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16230 .dac_nids = alc861_dac_nids,
16231 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16232 .channel_mode = alc861_threestack_modes,
4e195a7b 16233 .need_dac_fix = 1,
df694daa
KY
16234 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16235 .adc_nids = alc861_adc_nids,
16236 .input_mux = &alc861_capture_source,
16237 },
16238 [ALC861_3ST_DIG] = {
16239 .mixers = { alc861_base_mixer },
16240 .init_verbs = { alc861_threestack_init_verbs },
16241 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16242 .dac_nids = alc861_dac_nids,
16243 .dig_out_nid = ALC861_DIGOUT_NID,
16244 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16245 .channel_mode = alc861_threestack_modes,
4e195a7b 16246 .need_dac_fix = 1,
df694daa
KY
16247 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16248 .adc_nids = alc861_adc_nids,
16249 .input_mux = &alc861_capture_source,
16250 },
16251 [ALC861_6ST_DIG] = {
16252 .mixers = { alc861_base_mixer },
16253 .init_verbs = { alc861_base_init_verbs },
16254 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16255 .dac_nids = alc861_dac_nids,
16256 .dig_out_nid = ALC861_DIGOUT_NID,
16257 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16258 .channel_mode = alc861_8ch_modes,
16259 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16260 .adc_nids = alc861_adc_nids,
16261 .input_mux = &alc861_capture_source,
16262 },
9c7f852e
TI
16263 [ALC660_3ST] = {
16264 .mixers = { alc861_3ST_mixer },
16265 .init_verbs = { alc861_threestack_init_verbs },
16266 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16267 .dac_nids = alc660_dac_nids,
16268 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16269 .channel_mode = alc861_threestack_modes,
4e195a7b 16270 .need_dac_fix = 1,
9c7f852e
TI
16271 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16272 .adc_nids = alc861_adc_nids,
16273 .input_mux = &alc861_capture_source,
16274 },
22309c3e
TI
16275 [ALC861_UNIWILL_M31] = {
16276 .mixers = { alc861_uniwill_m31_mixer },
16277 .init_verbs = { alc861_uniwill_m31_init_verbs },
16278 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16279 .dac_nids = alc861_dac_nids,
16280 .dig_out_nid = ALC861_DIGOUT_NID,
16281 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16282 .channel_mode = alc861_uniwill_m31_modes,
16283 .need_dac_fix = 1,
16284 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16285 .adc_nids = alc861_adc_nids,
16286 .input_mux = &alc861_capture_source,
16287 },
a53d1aec
TD
16288 [ALC861_TOSHIBA] = {
16289 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16290 .init_verbs = { alc861_base_init_verbs,
16291 alc861_toshiba_init_verbs },
a53d1aec
TD
16292 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16293 .dac_nids = alc861_dac_nids,
16294 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16295 .channel_mode = alc883_3ST_2ch_modes,
16296 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16297 .adc_nids = alc861_adc_nids,
16298 .input_mux = &alc861_capture_source,
16299 .unsol_event = alc861_toshiba_unsol_event,
16300 .init_hook = alc861_toshiba_automute,
16301 },
7cdbff94
MD
16302 [ALC861_ASUS] = {
16303 .mixers = { alc861_asus_mixer },
16304 .init_verbs = { alc861_asus_init_verbs },
16305 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16306 .dac_nids = alc861_dac_nids,
16307 .dig_out_nid = ALC861_DIGOUT_NID,
16308 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16309 .channel_mode = alc861_asus_modes,
16310 .need_dac_fix = 1,
16311 .hp_nid = 0x06,
16312 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16313 .adc_nids = alc861_adc_nids,
16314 .input_mux = &alc861_capture_source,
16315 },
56bb0cab
TI
16316 [ALC861_ASUS_LAPTOP] = {
16317 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16318 .init_verbs = { alc861_asus_init_verbs,
16319 alc861_asus_laptop_init_verbs },
16320 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16321 .dac_nids = alc861_dac_nids,
16322 .dig_out_nid = ALC861_DIGOUT_NID,
16323 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16324 .channel_mode = alc883_3ST_2ch_modes,
16325 .need_dac_fix = 1,
16326 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16327 .adc_nids = alc861_adc_nids,
16328 .input_mux = &alc861_capture_source,
16329 },
16330};
df694daa 16331
cfc9b06f
TI
16332/* Pin config fixes */
16333enum {
16334 PINFIX_FSC_AMILO_PI1505,
16335};
16336
cfc9b06f
TI
16337static const struct alc_fixup alc861_fixups[] = {
16338 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16339 .type = ALC_FIXUP_PINS,
16340 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16341 { 0x0b, 0x0221101f }, /* HP */
16342 { 0x0f, 0x90170310 }, /* speaker */
16343 { }
16344 }
cfc9b06f
TI
16345 },
16346};
16347
16348static struct snd_pci_quirk alc861_fixup_tbl[] = {
16349 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16350 {}
16351};
df694daa
KY
16352
16353static int patch_alc861(struct hda_codec *codec)
16354{
16355 struct alc_spec *spec;
16356 int board_config;
16357 int err;
16358
dc041e0b 16359 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16360 if (spec == NULL)
16361 return -ENOMEM;
16362
f12ab1e0 16363 codec->spec = spec;
df694daa 16364
f5fcc13c
TI
16365 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16366 alc861_models,
16367 alc861_cfg_tbl);
9c7f852e 16368
f5fcc13c 16369 if (board_config < 0) {
9a11f1aa
TI
16370 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16371 codec->chip_name);
df694daa
KY
16372 board_config = ALC861_AUTO;
16373 }
16374
b5bfbc67
TI
16375 if (board_config == ALC861_AUTO) {
16376 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16377 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16378 }
cfc9b06f 16379
df694daa
KY
16380 if (board_config == ALC861_AUTO) {
16381 /* automatic parse from the BIOS config */
16382 err = alc861_parse_auto_config(codec);
16383 if (err < 0) {
16384 alc_free(codec);
16385 return err;
f12ab1e0 16386 } else if (!err) {
9c7f852e
TI
16387 printk(KERN_INFO
16388 "hda_codec: Cannot set up configuration "
16389 "from BIOS. Using base mode...\n");
df694daa
KY
16390 board_config = ALC861_3ST_DIG;
16391 }
16392 }
16393
680cd536
KK
16394 err = snd_hda_attach_beep_device(codec, 0x23);
16395 if (err < 0) {
16396 alc_free(codec);
16397 return err;
16398 }
16399
df694daa 16400 if (board_config != ALC861_AUTO)
e9c364c0 16401 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16402
df694daa
KY
16403 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16404 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16405
df694daa
KY
16406 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16407 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16408
c7a8eb10
TI
16409 if (!spec->cap_mixer)
16410 set_capture_mixer(codec);
45bdd1c1
TI
16411 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16412
2134ea4f
TI
16413 spec->vmaster_nid = 0x03;
16414
b5bfbc67 16415 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16416
df694daa 16417 codec->patch_ops = alc_patch_ops;
c97259df 16418 if (board_config == ALC861_AUTO) {
ae6b813a 16419 spec->init_hook = alc861_auto_init;
c97259df
DC
16420#ifdef CONFIG_SND_HDA_POWER_SAVE
16421 spec->power_hook = alc_power_eapd;
16422#endif
16423 }
cb53c626
TI
16424#ifdef CONFIG_SND_HDA_POWER_SAVE
16425 if (!spec->loopback.amplist)
16426 spec->loopback.amplist = alc861_loopbacks;
16427#endif
ea1fb29a 16428
1da177e4
LT
16429 return 0;
16430}
16431
f32610ed
JS
16432/*
16433 * ALC861-VD support
16434 *
16435 * Based on ALC882
16436 *
16437 * In addition, an independent DAC
16438 */
16439#define ALC861VD_DIGOUT_NID 0x06
16440
16441static hda_nid_t alc861vd_dac_nids[4] = {
16442 /* front, surr, clfe, side surr */
16443 0x02, 0x03, 0x04, 0x05
16444};
16445
16446/* dac_nids for ALC660vd are in a different order - according to
16447 * Realtek's driver.
def319f9 16448 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16449 * of ALC660vd codecs, but for now there is only 3stack mixer
16450 * - and it is the same as in 861vd.
16451 * adc_nids in ALC660vd are (is) the same as in 861vd
16452 */
16453static hda_nid_t alc660vd_dac_nids[3] = {
16454 /* front, rear, clfe, rear_surr */
16455 0x02, 0x04, 0x03
16456};
16457
16458static hda_nid_t alc861vd_adc_nids[1] = {
16459 /* ADC0 */
16460 0x09,
16461};
16462
e1406348
TI
16463static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16464
f32610ed
JS
16465/* input MUX */
16466/* FIXME: should be a matrix-type input source selection */
16467static struct hda_input_mux alc861vd_capture_source = {
16468 .num_items = 4,
16469 .items = {
16470 { "Mic", 0x0 },
16471 { "Front Mic", 0x1 },
16472 { "Line", 0x2 },
16473 { "CD", 0x4 },
16474 },
16475};
16476
272a527c 16477static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16478 .num_items = 2,
272a527c 16479 .items = {
8607f7c4 16480 { "Mic", 0x0 },
28c4edb7 16481 { "Internal Mic", 0x1 },
272a527c
KY
16482 },
16483};
16484
d1a991a6
KY
16485static struct hda_input_mux alc861vd_hp_capture_source = {
16486 .num_items = 2,
16487 .items = {
16488 { "Front Mic", 0x0 },
16489 { "ATAPI Mic", 0x1 },
16490 },
16491};
16492
f32610ed
JS
16493/*
16494 * 2ch mode
16495 */
16496static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16497 { 2, NULL }
16498};
16499
16500/*
16501 * 6ch mode
16502 */
16503static struct hda_verb alc861vd_6stack_ch6_init[] = {
16504 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16505 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16506 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16507 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16508 { } /* end */
16509};
16510
16511/*
16512 * 8ch mode
16513 */
16514static struct hda_verb alc861vd_6stack_ch8_init[] = {
16515 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16516 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16517 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16518 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16519 { } /* end */
16520};
16521
16522static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16523 { 6, alc861vd_6stack_ch6_init },
16524 { 8, alc861vd_6stack_ch8_init },
16525};
16526
16527static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16528 {
16529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16530 .name = "Channel Mode",
16531 .info = alc_ch_mode_info,
16532 .get = alc_ch_mode_get,
16533 .put = alc_ch_mode_put,
16534 },
16535 { } /* end */
16536};
16537
f32610ed
JS
16538/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16539 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16540 */
16541static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16542 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16543 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16544
16545 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16546 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16547
16548 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16549 HDA_OUTPUT),
16550 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16551 HDA_OUTPUT),
16552 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16553 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16554
16555 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16556 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16557
16558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16559
5f99f86a 16560 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16561 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16562 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16563
5f99f86a 16564 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16565 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16566 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16567
16568 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16569 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16570
16571 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16572 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16573
f32610ed
JS
16574 { } /* end */
16575};
16576
16577static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16578 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16579 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16580
16581 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16582
5f99f86a 16583 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16584 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16585 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16586
5f99f86a 16587 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16588 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16589 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16590
16591 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16592 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16593
16594 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16595 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16596
f32610ed
JS
16597 { } /* end */
16598};
16599
bdd148a3
KY
16600static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16601 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16602 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16603 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16604
16605 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16606
5f99f86a 16607 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16609 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16610
5f99f86a 16611 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16612 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16613 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16614
16615 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16616 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16617
16618 { } /* end */
16619};
16620
b419f346 16621/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16622 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16623 */
16624static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16625 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16626 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16627 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16628 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16629 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16630 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16631 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16632 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16633 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16634 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16635 { } /* end */
16636};
16637
d1a991a6
KY
16638/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16639 * Front Mic=0x18, ATAPI Mic = 0x19,
16640 */
16641static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16642 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16643 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16644 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16645 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16646 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16647 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16648 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16649 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16650
d1a991a6
KY
16651 { } /* end */
16652};
16653
f32610ed
JS
16654/*
16655 * generic initialization of ADC, input mixers and output mixers
16656 */
16657static struct hda_verb alc861vd_volume_init_verbs[] = {
16658 /*
16659 * Unmute ADC0 and set the default input to mic-in
16660 */
16661 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16662 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16663
16664 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16665 * the analog-loopback mixer widget
16666 */
16667 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16668 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16669 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16670 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16671 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16672 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16673
16674 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16679
16680 /*
16681 * Set up output mixers (0x02 - 0x05)
16682 */
16683 /* set vol=0 to output mixers */
16684 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16685 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16686 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16687 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16688
16689 /* set up input amps for analog loopback */
16690 /* Amp Indices: DAC = 0, mixer = 1 */
16691 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16692 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16693 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16694 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16695 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16696 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16697 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16698 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16699
16700 { }
16701};
16702
16703/*
16704 * 3-stack pin configuration:
16705 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16706 */
16707static struct hda_verb alc861vd_3stack_init_verbs[] = {
16708 /*
16709 * Set pin mode and muting
16710 */
16711 /* set front pin widgets 0x14 for output */
16712 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16713 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16714 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16715
16716 /* Mic (rear) pin: input vref at 80% */
16717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16718 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16719 /* Front Mic pin: input vref at 80% */
16720 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16721 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16722 /* Line In pin: input */
16723 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16724 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16725 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16727 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16728 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16729 /* CD pin widget for input */
16730 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16731
16732 { }
16733};
16734
16735/*
16736 * 6-stack pin configuration:
16737 */
16738static struct hda_verb alc861vd_6stack_init_verbs[] = {
16739 /*
16740 * Set pin mode and muting
16741 */
16742 /* set front pin widgets 0x14 for output */
16743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16744 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16745 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16746
16747 /* Rear Pin: output 1 (0x0d) */
16748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16750 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16751 /* CLFE Pin: output 2 (0x0e) */
16752 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16753 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16754 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16755 /* Side Pin: output 3 (0x0f) */
16756 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16757 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16758 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16759
16760 /* Mic (rear) pin: input vref at 80% */
16761 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16762 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16763 /* Front Mic pin: input vref at 80% */
16764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16765 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16766 /* Line In pin: input */
16767 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16768 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16769 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16770 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16771 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16772 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16773 /* CD pin widget for input */
16774 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16775
16776 { }
16777};
16778
bdd148a3
KY
16779static struct hda_verb alc861vd_eapd_verbs[] = {
16780 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16781 { }
16782};
16783
f9423e7a
KY
16784static struct hda_verb alc660vd_eapd_verbs[] = {
16785 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16786 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16787 { }
16788};
16789
bdd148a3
KY
16790static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16791 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16792 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16793 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16794 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16795 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16796 {}
16797};
16798
4f5d1706 16799static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16800{
a9fd4f3f 16801 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16802 spec->autocfg.hp_pins[0] = 0x1b;
16803 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16804}
16805
16806static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16807{
a9fd4f3f 16808 alc_automute_amp(codec);
eeb43387 16809 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16810}
16811
16812static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16813 unsigned int res)
16814{
16815 switch (res >> 26) {
bdd148a3 16816 case ALC880_MIC_EVENT:
eeb43387 16817 alc88x_simple_mic_automute(codec);
bdd148a3 16818 break;
a9fd4f3f
TI
16819 default:
16820 alc_automute_amp_unsol_event(codec, res);
16821 break;
bdd148a3
KY
16822 }
16823}
16824
272a527c
KY
16825static struct hda_verb alc861vd_dallas_verbs[] = {
16826 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16827 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16828 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16829 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16830
16831 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16832 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16833 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16834 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16835 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16836 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16837 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16838 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16839
272a527c
KY
16840 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16841 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16842 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16843 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16844 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16845 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16846 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16847 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16848
16849 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16850 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16851 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16852 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16853 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16854 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16855 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16856 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16857
16858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16860 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16861 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16862
16863 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16864 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16865 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16866
16867 { } /* end */
16868};
16869
16870/* toggle speaker-output according to the hp-jack state */
4f5d1706 16871static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16872{
a9fd4f3f 16873 struct alc_spec *spec = codec->spec;
272a527c 16874
a9fd4f3f
TI
16875 spec->autocfg.hp_pins[0] = 0x15;
16876 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16877}
16878
cb53c626
TI
16879#ifdef CONFIG_SND_HDA_POWER_SAVE
16880#define alc861vd_loopbacks alc880_loopbacks
16881#endif
16882
def319f9 16883/* pcm configuration: identical with ALC880 */
f32610ed
JS
16884#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16885#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16886#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16887#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16888
16889/*
16890 * configuration and preset
16891 */
ea734963 16892static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16893 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16894 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16895 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16896 [ALC861VD_3ST] = "3stack",
16897 [ALC861VD_3ST_DIG] = "3stack-digout",
16898 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16899 [ALC861VD_LENOVO] = "lenovo",
272a527c 16900 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16901 [ALC861VD_HP] = "hp",
f32610ed
JS
16902 [ALC861VD_AUTO] = "auto",
16903};
16904
16905static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16906 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16907 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16908 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16909 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16910 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16911 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16912 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16913 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16914 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16915 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16916 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16917 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16918 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16919 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16920 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16921 {}
16922};
16923
16924static struct alc_config_preset alc861vd_presets[] = {
16925 [ALC660VD_3ST] = {
16926 .mixers = { alc861vd_3st_mixer },
16927 .init_verbs = { alc861vd_volume_init_verbs,
16928 alc861vd_3stack_init_verbs },
16929 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16930 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16931 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16932 .channel_mode = alc861vd_3stack_2ch_modes,
16933 .input_mux = &alc861vd_capture_source,
16934 },
6963f84c
MC
16935 [ALC660VD_3ST_DIG] = {
16936 .mixers = { alc861vd_3st_mixer },
16937 .init_verbs = { alc861vd_volume_init_verbs,
16938 alc861vd_3stack_init_verbs },
16939 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16940 .dac_nids = alc660vd_dac_nids,
16941 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16942 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16943 .channel_mode = alc861vd_3stack_2ch_modes,
16944 .input_mux = &alc861vd_capture_source,
16945 },
f32610ed
JS
16946 [ALC861VD_3ST] = {
16947 .mixers = { alc861vd_3st_mixer },
16948 .init_verbs = { alc861vd_volume_init_verbs,
16949 alc861vd_3stack_init_verbs },
16950 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16951 .dac_nids = alc861vd_dac_nids,
16952 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16953 .channel_mode = alc861vd_3stack_2ch_modes,
16954 .input_mux = &alc861vd_capture_source,
16955 },
16956 [ALC861VD_3ST_DIG] = {
16957 .mixers = { alc861vd_3st_mixer },
16958 .init_verbs = { alc861vd_volume_init_verbs,
16959 alc861vd_3stack_init_verbs },
16960 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16961 .dac_nids = alc861vd_dac_nids,
16962 .dig_out_nid = ALC861VD_DIGOUT_NID,
16963 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16964 .channel_mode = alc861vd_3stack_2ch_modes,
16965 .input_mux = &alc861vd_capture_source,
16966 },
16967 [ALC861VD_6ST_DIG] = {
16968 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16969 .init_verbs = { alc861vd_volume_init_verbs,
16970 alc861vd_6stack_init_verbs },
16971 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16972 .dac_nids = alc861vd_dac_nids,
16973 .dig_out_nid = ALC861VD_DIGOUT_NID,
16974 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16975 .channel_mode = alc861vd_6stack_modes,
16976 .input_mux = &alc861vd_capture_source,
16977 },
bdd148a3
KY
16978 [ALC861VD_LENOVO] = {
16979 .mixers = { alc861vd_lenovo_mixer },
16980 .init_verbs = { alc861vd_volume_init_verbs,
16981 alc861vd_3stack_init_verbs,
16982 alc861vd_eapd_verbs,
16983 alc861vd_lenovo_unsol_verbs },
16984 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16985 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16986 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16987 .channel_mode = alc861vd_3stack_2ch_modes,
16988 .input_mux = &alc861vd_capture_source,
16989 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16990 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16991 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16992 },
272a527c
KY
16993 [ALC861VD_DALLAS] = {
16994 .mixers = { alc861vd_dallas_mixer },
16995 .init_verbs = { alc861vd_dallas_verbs },
16996 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16997 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16998 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16999 .channel_mode = alc861vd_3stack_2ch_modes,
17000 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 17001 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
17002 .setup = alc861vd_dallas_setup,
17003 .init_hook = alc_automute_amp,
d1a991a6
KY
17004 },
17005 [ALC861VD_HP] = {
17006 .mixers = { alc861vd_hp_mixer },
17007 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17008 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17009 .dac_nids = alc861vd_dac_nids,
d1a991a6 17010 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17011 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17012 .channel_mode = alc861vd_3stack_2ch_modes,
17013 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 17014 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
17015 .setup = alc861vd_dallas_setup,
17016 .init_hook = alc_automute_amp,
ea1fb29a 17017 },
13c94744
TI
17018 [ALC660VD_ASUS_V1S] = {
17019 .mixers = { alc861vd_lenovo_mixer },
17020 .init_verbs = { alc861vd_volume_init_verbs,
17021 alc861vd_3stack_init_verbs,
17022 alc861vd_eapd_verbs,
17023 alc861vd_lenovo_unsol_verbs },
17024 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17025 .dac_nids = alc660vd_dac_nids,
17026 .dig_out_nid = ALC861VD_DIGOUT_NID,
17027 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17028 .channel_mode = alc861vd_3stack_2ch_modes,
17029 .input_mux = &alc861vd_capture_source,
17030 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17031 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17032 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17033 },
f32610ed
JS
17034};
17035
17036/*
17037 * BIOS auto configuration
17038 */
05f5f477
TI
17039static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17040 const struct auto_pin_cfg *cfg)
17041{
7167594a 17042 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17043}
17044
17045
f32610ed
JS
17046static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17047 hda_nid_t nid, int pin_type, int dac_idx)
17048{
f6c7e546 17049 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17050}
17051
17052static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17053{
17054 struct alc_spec *spec = codec->spec;
17055 int i;
17056
17057 for (i = 0; i <= HDA_SIDE; i++) {
17058 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17059 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17060 if (nid)
17061 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17062 pin_type, i);
f32610ed
JS
17063 }
17064}
17065
17066
17067static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17068{
17069 struct alc_spec *spec = codec->spec;
17070 hda_nid_t pin;
17071
17072 pin = spec->autocfg.hp_pins[0];
def319f9 17073 if (pin) /* connect to front and use dac 0 */
f32610ed 17074 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17075 pin = spec->autocfg.speaker_pins[0];
17076 if (pin)
17077 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17078}
17079
f32610ed
JS
17080#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17081
17082static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17083{
17084 struct alc_spec *spec = codec->spec;
66ceeb6b 17085 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17086 int i;
17087
66ceeb6b
TI
17088 for (i = 0; i < cfg->num_inputs; i++) {
17089 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17090 if (alc_is_input_pin(codec, nid)) {
30ea098f 17091 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17092 if (nid != ALC861VD_PIN_CD_NID &&
17093 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17094 snd_hda_codec_write(codec, nid, 0,
17095 AC_VERB_SET_AMP_GAIN_MUTE,
17096 AMP_OUT_MUTE);
17097 }
17098 }
17099}
17100
f511b01c
TI
17101#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17102
f32610ed
JS
17103#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17104#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17105
17106/* add playback controls from the parsed DAC table */
569ed348 17107/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17108 * different NIDs for mute/unmute switch and volume control */
17109static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17110 const struct auto_pin_cfg *cfg)
17111{
ea734963
TI
17112 static const char * const chname[4] = {
17113 "Front", "Surround", "CLFE", "Side"
17114 };
bcb2f0f5 17115 const char *pfx = alc_get_line_out_pfx(cfg, true);
f32610ed
JS
17116 hda_nid_t nid_v, nid_s;
17117 int i, err;
17118
17119 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 17120 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17121 continue;
17122 nid_v = alc861vd_idx_to_mixer_vol(
17123 alc880_dac_to_idx(
17124 spec->multiout.dac_nids[i]));
17125 nid_s = alc861vd_idx_to_mixer_switch(
17126 alc880_dac_to_idx(
17127 spec->multiout.dac_nids[i]));
17128
bcb2f0f5 17129 if (!pfx && i == 2) {
f32610ed 17130 /* Center/LFE */
0afe5f89
TI
17131 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17132 "Center",
f12ab1e0
TI
17133 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17134 HDA_OUTPUT));
17135 if (err < 0)
f32610ed 17136 return err;
0afe5f89
TI
17137 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17138 "LFE",
f12ab1e0
TI
17139 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17140 HDA_OUTPUT));
17141 if (err < 0)
f32610ed 17142 return err;
0afe5f89
TI
17143 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17144 "Center",
f12ab1e0
TI
17145 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17146 HDA_INPUT));
17147 if (err < 0)
f32610ed 17148 return err;
0afe5f89
TI
17149 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17150 "LFE",
f12ab1e0
TI
17151 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17152 HDA_INPUT));
17153 if (err < 0)
f32610ed
JS
17154 return err;
17155 } else {
bcb2f0f5
TI
17156 const char *name = pfx;
17157 if (!name)
17158 name = chname[i];
17159 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17160 name, i,
f12ab1e0
TI
17161 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17162 HDA_OUTPUT));
17163 if (err < 0)
f32610ed 17164 return err;
bcb2f0f5
TI
17165 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17166 name, i,
bdd148a3 17167 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17168 HDA_INPUT));
17169 if (err < 0)
f32610ed
JS
17170 return err;
17171 }
17172 }
17173 return 0;
17174}
17175
17176/* add playback controls for speaker and HP outputs */
17177/* Based on ALC880 version. But ALC861VD has separate,
17178 * different NIDs for mute/unmute switch and volume control */
17179static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17180 hda_nid_t pin, const char *pfx)
17181{
17182 hda_nid_t nid_v, nid_s;
17183 int err;
f32610ed 17184
f12ab1e0 17185 if (!pin)
f32610ed
JS
17186 return 0;
17187
17188 if (alc880_is_fixed_pin(pin)) {
17189 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17190 /* specify the DAC as the extra output */
f12ab1e0 17191 if (!spec->multiout.hp_nid)
f32610ed
JS
17192 spec->multiout.hp_nid = nid_v;
17193 else
17194 spec->multiout.extra_out_nid[0] = nid_v;
17195 /* control HP volume/switch on the output mixer amp */
17196 nid_v = alc861vd_idx_to_mixer_vol(
17197 alc880_fixed_pin_idx(pin));
17198 nid_s = alc861vd_idx_to_mixer_switch(
17199 alc880_fixed_pin_idx(pin));
17200
0afe5f89 17201 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17202 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17203 if (err < 0)
f32610ed 17204 return err;
0afe5f89 17205 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17206 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17207 if (err < 0)
f32610ed
JS
17208 return err;
17209 } else if (alc880_is_multi_pin(pin)) {
17210 /* set manual connection */
17211 /* we have only a switch on HP-out PIN */
0afe5f89 17212 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17213 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17214 if (err < 0)
f32610ed
JS
17215 return err;
17216 }
17217 return 0;
17218}
17219
17220/* parse the BIOS configuration and set up the alc_spec
17221 * return 1 if successful, 0 if the proper config is not found,
17222 * or a negative error code
17223 * Based on ALC880 version - had to change it to override
17224 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17225static int alc861vd_parse_auto_config(struct hda_codec *codec)
17226{
17227 struct alc_spec *spec = codec->spec;
17228 int err;
17229 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17230
f12ab1e0
TI
17231 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17232 alc861vd_ignore);
17233 if (err < 0)
f32610ed 17234 return err;
f12ab1e0 17235 if (!spec->autocfg.line_outs)
f32610ed
JS
17236 return 0; /* can't find valid BIOS pin config */
17237
f12ab1e0
TI
17238 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17239 if (err < 0)
17240 return err;
17241 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17242 if (err < 0)
17243 return err;
17244 err = alc861vd_auto_create_extra_out(spec,
17245 spec->autocfg.speaker_pins[0],
17246 "Speaker");
17247 if (err < 0)
17248 return err;
17249 err = alc861vd_auto_create_extra_out(spec,
17250 spec->autocfg.hp_pins[0],
17251 "Headphone");
17252 if (err < 0)
17253 return err;
05f5f477 17254 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17255 if (err < 0)
f32610ed
JS
17256 return err;
17257
17258 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17259
757899ac 17260 alc_auto_parse_digital(codec);
f32610ed 17261
603c4019 17262 if (spec->kctls.list)
d88897ea 17263 add_mixer(spec, spec->kctls.list);
f32610ed 17264
d88897ea 17265 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17266
17267 spec->num_mux_defs = 1;
61b9b9b1 17268 spec->input_mux = &spec->private_imux[0];
f32610ed 17269
776e184e
TI
17270 err = alc_auto_add_mic_boost(codec);
17271 if (err < 0)
17272 return err;
17273
6227cdce 17274 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17275
f32610ed
JS
17276 return 1;
17277}
17278
17279/* additional initialization for auto-configuration model */
17280static void alc861vd_auto_init(struct hda_codec *codec)
17281{
f6c7e546 17282 struct alc_spec *spec = codec->spec;
f32610ed
JS
17283 alc861vd_auto_init_multi_out(codec);
17284 alc861vd_auto_init_hp_out(codec);
17285 alc861vd_auto_init_analog_input(codec);
f511b01c 17286 alc861vd_auto_init_input_src(codec);
757899ac 17287 alc_auto_init_digital(codec);
f6c7e546 17288 if (spec->unsol_event)
7fb0d78f 17289 alc_inithook(codec);
f32610ed
JS
17290}
17291
f8f25ba3
TI
17292enum {
17293 ALC660VD_FIX_ASUS_GPIO1
17294};
17295
17296/* reset GPIO1 */
f8f25ba3
TI
17297static const struct alc_fixup alc861vd_fixups[] = {
17298 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17299 .type = ALC_FIXUP_VERBS,
17300 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17301 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17302 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17303 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17304 { }
17305 }
f8f25ba3
TI
17306 },
17307};
17308
17309static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17310 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17311 {}
17312};
17313
f32610ed
JS
17314static int patch_alc861vd(struct hda_codec *codec)
17315{
17316 struct alc_spec *spec;
17317 int err, board_config;
17318
17319 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17320 if (spec == NULL)
17321 return -ENOMEM;
17322
17323 codec->spec = spec;
17324
17325 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17326 alc861vd_models,
17327 alc861vd_cfg_tbl);
17328
17329 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17330 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17331 codec->chip_name);
f32610ed
JS
17332 board_config = ALC861VD_AUTO;
17333 }
17334
b5bfbc67
TI
17335 if (board_config == ALC861VD_AUTO) {
17336 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17337 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17338 }
f8f25ba3 17339
f32610ed
JS
17340 if (board_config == ALC861VD_AUTO) {
17341 /* automatic parse from the BIOS config */
17342 err = alc861vd_parse_auto_config(codec);
17343 if (err < 0) {
17344 alc_free(codec);
17345 return err;
f12ab1e0 17346 } else if (!err) {
f32610ed
JS
17347 printk(KERN_INFO
17348 "hda_codec: Cannot set up configuration "
17349 "from BIOS. Using base mode...\n");
17350 board_config = ALC861VD_3ST;
17351 }
17352 }
17353
680cd536
KK
17354 err = snd_hda_attach_beep_device(codec, 0x23);
17355 if (err < 0) {
17356 alc_free(codec);
17357 return err;
17358 }
17359
f32610ed 17360 if (board_config != ALC861VD_AUTO)
e9c364c0 17361 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17362
2f893286 17363 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17364 /* always turn on EAPD */
d88897ea 17365 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17366 }
17367
f32610ed
JS
17368 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17369 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17370
f32610ed
JS
17371 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17372 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17373
dd704698
TI
17374 if (!spec->adc_nids) {
17375 spec->adc_nids = alc861vd_adc_nids;
17376 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17377 }
17378 if (!spec->capsrc_nids)
17379 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17380
b59bdf3b 17381 set_capture_mixer(codec);
45bdd1c1 17382 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17383
2134ea4f
TI
17384 spec->vmaster_nid = 0x02;
17385
b5bfbc67 17386 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17387
f32610ed
JS
17388 codec->patch_ops = alc_patch_ops;
17389
17390 if (board_config == ALC861VD_AUTO)
17391 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17392#ifdef CONFIG_SND_HDA_POWER_SAVE
17393 if (!spec->loopback.amplist)
17394 spec->loopback.amplist = alc861vd_loopbacks;
17395#endif
f32610ed
JS
17396
17397 return 0;
17398}
17399
bc9f98a9
KY
17400/*
17401 * ALC662 support
17402 *
17403 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17404 * configuration. Each pin widget can choose any input DACs and a mixer.
17405 * Each ADC is connected from a mixer of all inputs. This makes possible
17406 * 6-channel independent captures.
17407 *
17408 * In addition, an independent DAC for the multi-playback (not used in this
17409 * driver yet).
17410 */
17411#define ALC662_DIGOUT_NID 0x06
17412#define ALC662_DIGIN_NID 0x0a
17413
17414static hda_nid_t alc662_dac_nids[4] = {
17415 /* front, rear, clfe, rear_surr */
17416 0x02, 0x03, 0x04
17417};
17418
622e84cd
KY
17419static hda_nid_t alc272_dac_nids[2] = {
17420 0x02, 0x03
17421};
17422
b59bdf3b 17423static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17424 /* ADC1-2 */
b59bdf3b 17425 0x09, 0x08
bc9f98a9 17426};
e1406348 17427
622e84cd
KY
17428static hda_nid_t alc272_adc_nids[1] = {
17429 /* ADC1-2 */
17430 0x08,
17431};
17432
b59bdf3b 17433static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17434static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17435
e1406348 17436
bc9f98a9
KY
17437/* input MUX */
17438/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17439static struct hda_input_mux alc662_capture_source = {
17440 .num_items = 4,
17441 .items = {
17442 { "Mic", 0x0 },
17443 { "Front Mic", 0x1 },
17444 { "Line", 0x2 },
17445 { "CD", 0x4 },
17446 },
17447};
17448
17449static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17450 .num_items = 2,
17451 .items = {
17452 { "Mic", 0x1 },
17453 { "Line", 0x2 },
17454 },
17455};
291702f0 17456
6dda9f4a
KY
17457static struct hda_input_mux alc663_capture_source = {
17458 .num_items = 3,
17459 .items = {
17460 { "Mic", 0x0 },
17461 { "Front Mic", 0x1 },
17462 { "Line", 0x2 },
17463 },
17464};
17465
4f5d1706 17466#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17467static struct hda_input_mux alc272_nc10_capture_source = {
17468 .num_items = 16,
17469 .items = {
17470 { "Autoselect Mic", 0x0 },
17471 { "Internal Mic", 0x1 },
17472 { "In-0x02", 0x2 },
17473 { "In-0x03", 0x3 },
17474 { "In-0x04", 0x4 },
17475 { "In-0x05", 0x5 },
17476 { "In-0x06", 0x6 },
17477 { "In-0x07", 0x7 },
17478 { "In-0x08", 0x8 },
17479 { "In-0x09", 0x9 },
17480 { "In-0x0a", 0x0a },
17481 { "In-0x0b", 0x0b },
17482 { "In-0x0c", 0x0c },
17483 { "In-0x0d", 0x0d },
17484 { "In-0x0e", 0x0e },
17485 { "In-0x0f", 0x0f },
17486 },
17487};
17488#endif
17489
bc9f98a9
KY
17490/*
17491 * 2ch mode
17492 */
17493static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17494 { 2, NULL }
17495};
17496
17497/*
17498 * 2ch mode
17499 */
17500static struct hda_verb alc662_3ST_ch2_init[] = {
17501 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17502 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17503 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17504 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17505 { } /* end */
17506};
17507
17508/*
17509 * 6ch mode
17510 */
17511static struct hda_verb alc662_3ST_ch6_init[] = {
17512 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17513 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17514 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17515 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17516 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17517 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17518 { } /* end */
17519};
17520
17521static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17522 { 2, alc662_3ST_ch2_init },
17523 { 6, alc662_3ST_ch6_init },
17524};
17525
17526/*
17527 * 2ch mode
17528 */
17529static struct hda_verb alc662_sixstack_ch6_init[] = {
17530 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17531 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17532 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17533 { } /* end */
17534};
17535
17536/*
17537 * 6ch mode
17538 */
17539static struct hda_verb alc662_sixstack_ch8_init[] = {
17540 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17541 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17542 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17543 { } /* end */
17544};
17545
17546static struct hda_channel_mode alc662_5stack_modes[2] = {
17547 { 2, alc662_sixstack_ch6_init },
17548 { 6, alc662_sixstack_ch8_init },
17549};
17550
17551/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17552 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17553 */
17554
17555static struct snd_kcontrol_new alc662_base_mixer[] = {
17556 /* output mixer control */
17557 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17558 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17559 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17560 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17561 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17562 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17563 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17564 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17565 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17566
17567 /*Input mixer control */
17568 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17569 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17570 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17571 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17572 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17573 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17574 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17575 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17576 { } /* end */
17577};
17578
17579static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17580 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17581 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17582 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17583 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17584 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17585 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17586 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17589 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17590 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17591 { } /* end */
17592};
17593
17594static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17595 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17596 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17597 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17598 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17599 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17600 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17601 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17602 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17604 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17605 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17606 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17607 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17609 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17610 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17611 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17612 { } /* end */
17613};
17614
17615static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17616 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17617 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17618 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17619 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17620 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17624 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17625 { } /* end */
17626};
17627
291702f0 17628static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17629 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17630 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17631
5f99f86a 17632 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17633 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17634 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17635
5f99f86a 17636 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17637 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17638 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17639 { } /* end */
17640};
17641
8c427226 17642static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17643 ALC262_HIPPO_MASTER_SWITCH,
17644 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17645 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17646 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17647 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17648 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17649 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17650 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17652 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17653 { } /* end */
17654};
17655
f1d4e28b
KY
17656static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17657 .ops = &snd_hda_bind_vol,
17658 .values = {
17659 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17660 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17661 0
17662 },
17663};
17664
17665static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17666 .ops = &snd_hda_bind_sw,
17667 .values = {
17668 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17669 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17670 0
17671 },
17672};
17673
6dda9f4a 17674static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17675 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17676 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17679 { } /* end */
17680};
17681
17682static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17683 .ops = &snd_hda_bind_sw,
17684 .values = {
17685 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17686 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17687 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17688 0
17689 },
17690};
17691
17692static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17693 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17694 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17695 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17696 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17697 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17698 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17699
17700 { } /* end */
17701};
17702
17703static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17704 .ops = &snd_hda_bind_sw,
17705 .values = {
17706 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17707 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17708 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17709 0
17710 },
17711};
17712
17713static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17714 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17715 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17716 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17717 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17718 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17719 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17720 { } /* end */
17721};
17722
17723static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17724 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17725 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17726 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17729 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17730 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17731 { } /* end */
17732};
17733
17734static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17735 .ops = &snd_hda_bind_vol,
17736 .values = {
17737 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17738 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17739 0
17740 },
17741};
17742
17743static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17744 .ops = &snd_hda_bind_sw,
17745 .values = {
17746 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17747 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17748 0
17749 },
17750};
17751
17752static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17753 HDA_BIND_VOL("Master Playback Volume",
17754 &alc663_asus_two_bind_master_vol),
17755 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17756 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17757 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17759 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17760 { } /* end */
17761};
17762
17763static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17764 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17765 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17766 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17767 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17768 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17769 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17770 { } /* end */
17771};
17772
17773static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17774 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17775 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17776 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17777 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17779
17780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17782 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17783 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17784 { } /* end */
17785};
17786
17787static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17788 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17789 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17790 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17791
17792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17793 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17794 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17795 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17796 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17797 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17798 { } /* end */
17799};
17800
ebb83eeb
KY
17801static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17802 .ops = &snd_hda_bind_sw,
17803 .values = {
17804 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17805 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17806 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17807 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17808 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17809 0
17810 },
17811};
17812
17813static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17814 .ops = &snd_hda_bind_sw,
17815 .values = {
17816 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17817 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17818 0
17819 },
17820};
17821
17822static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17823 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17824 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17825 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17826 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17827 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17828 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17829 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17831 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17832 { } /* end */
17833};
17834
17835static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17836 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17837 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17838 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17839 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17840 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17842 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17843 { } /* end */
17844};
17845
17846
bc9f98a9
KY
17847static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17848 {
17849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17850 .name = "Channel Mode",
17851 .info = alc_ch_mode_info,
17852 .get = alc_ch_mode_get,
17853 .put = alc_ch_mode_put,
17854 },
17855 { } /* end */
17856};
17857
17858static struct hda_verb alc662_init_verbs[] = {
17859 /* ADC: mute amp left and right */
17860 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17861 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17862
b60dd394
KY
17863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17865 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17866 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17867 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17868 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17869
17870 /* Front Pin: output 0 (0x0c) */
17871 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17873
17874 /* Rear Pin: output 1 (0x0d) */
17875 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17876 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17877
17878 /* CLFE Pin: output 2 (0x0e) */
17879 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17880 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17881
17882 /* Mic (rear) pin: input vref at 80% */
17883 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17884 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17885 /* Front Mic pin: input vref at 80% */
17886 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17887 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17888 /* Line In pin: input */
17889 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17890 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17891 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17892 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17893 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17894 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17895 /* CD pin widget for input */
17896 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17897
17898 /* FIXME: use matrix-type input source selection */
17899 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17900 /* Input mixer */
17901 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17902 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17903
17904 /* always trun on EAPD */
17905 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17906 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17907
bc9f98a9
KY
17908 { }
17909};
17910
cec27c89
KY
17911static struct hda_verb alc663_init_verbs[] = {
17912 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17913 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17914 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17915 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17916 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17917 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17918 { }
17919};
17920
17921static struct hda_verb alc272_init_verbs[] = {
17922 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17923 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17924 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17925 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17926 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17927 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17928 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17929 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17930 { }
17931};
17932
bc9f98a9
KY
17933static struct hda_verb alc662_sue_init_verbs[] = {
17934 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17935 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17936 {}
17937};
17938
17939static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17940 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17942 {}
bc9f98a9
KY
17943};
17944
8c427226
KY
17945/* Set Unsolicited Event*/
17946static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17947 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17948 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17949 {}
17950};
17951
6dda9f4a 17952static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17953 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17954 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17955 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17956 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17957 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17958 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17959 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17960 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17961 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17962 {}
17963};
17964
17965static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17966 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17967 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17968 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17970 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17971 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17972 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17973 {}
17974};
17975
17976static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17977 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17978 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17979 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17980 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17981 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17982 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17983 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17984 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17985 {}
17986};
6dda9f4a 17987
f1d4e28b
KY
17988static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17989 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17990 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17991 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17992 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17994 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17995 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17996 {}
17997};
6dda9f4a 17998
f1d4e28b
KY
17999static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18000 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18001 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18002 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18003 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18005 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18006 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18009 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18010 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18011 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18012 {}
18013};
18014
18015static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18016 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18017 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18018 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18019 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18020 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18021 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18022 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18023 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18024 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18025 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18026 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18027 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18028 {}
18029};
18030
18031static struct hda_verb alc663_g71v_init_verbs[] = {
18032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18033 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18034 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18035
18036 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18037 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18038 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18039
18040 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18041 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18042 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18043 {}
18044};
18045
18046static struct hda_verb alc663_g50v_init_verbs[] = {
18047 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18048 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18049 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18050
18051 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18052 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18053 {}
18054};
18055
f1d4e28b
KY
18056static struct hda_verb alc662_ecs_init_verbs[] = {
18057 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18059 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18060 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18061 {}
18062};
18063
622e84cd
KY
18064static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18065 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18066 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18067 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18068 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18069 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18070 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18071 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18074 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18075 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18076 {}
18077};
18078
18079static struct hda_verb alc272_dell_init_verbs[] = {
18080 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18081 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18082 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18083 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18084 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18085 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18086 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18087 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18088 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18089 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18090 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18091 {}
18092};
18093
ebb83eeb
KY
18094static struct hda_verb alc663_mode7_init_verbs[] = {
18095 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18096 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18097 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18098 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18099 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18100 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18101 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18102 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18103 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18104 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18105 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18106 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18107 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18108 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18109 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18110 {}
18111};
18112
18113static struct hda_verb alc663_mode8_init_verbs[] = {
18114 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18116 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18117 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18118 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18119 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18120 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18121 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18122 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18123 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18124 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18127 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18128 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18129 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18130 {}
18131};
18132
f1d4e28b
KY
18133static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18134 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18135 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18136 { } /* end */
18137};
18138
622e84cd
KY
18139static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18140 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18141 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18142 { } /* end */
18143};
18144
bc9f98a9
KY
18145static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18146{
18147 unsigned int present;
f12ab1e0 18148 unsigned char bits;
bc9f98a9 18149
864f92be 18150 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 18151 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18152
47fd830a
TI
18153 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18154 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18155}
18156
18157static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18158{
18159 unsigned int present;
f12ab1e0 18160 unsigned char bits;
bc9f98a9 18161
864f92be 18162 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 18163 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18164
47fd830a
TI
18165 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18166 HDA_AMP_MUTE, bits);
18167 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18168 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18169}
18170
18171static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18172 unsigned int res)
18173{
18174 if ((res >> 26) == ALC880_HP_EVENT)
18175 alc662_lenovo_101e_all_automute(codec);
18176 if ((res >> 26) == ALC880_FRONT_EVENT)
18177 alc662_lenovo_101e_ispeaker_automute(codec);
18178}
18179
291702f0
KY
18180/* unsolicited event for HP jack sensing */
18181static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18182 unsigned int res)
18183{
291702f0 18184 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18185 alc_mic_automute(codec);
42171c17
TI
18186 else
18187 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18188}
18189
4f5d1706
TI
18190static void alc662_eeepc_setup(struct hda_codec *codec)
18191{
18192 struct alc_spec *spec = codec->spec;
18193
18194 alc262_hippo1_setup(codec);
18195 spec->ext_mic.pin = 0x18;
18196 spec->ext_mic.mux_idx = 0;
18197 spec->int_mic.pin = 0x19;
18198 spec->int_mic.mux_idx = 1;
18199 spec->auto_mic = 1;
18200}
18201
291702f0
KY
18202static void alc662_eeepc_inithook(struct hda_codec *codec)
18203{
4f5d1706
TI
18204 alc262_hippo_automute(codec);
18205 alc_mic_automute(codec);
291702f0
KY
18206}
18207
4f5d1706 18208static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18209{
42171c17
TI
18210 struct alc_spec *spec = codec->spec;
18211
18212 spec->autocfg.hp_pins[0] = 0x14;
18213 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18214}
18215
4f5d1706
TI
18216#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18217
6dda9f4a
KY
18218static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18219{
18220 unsigned int present;
18221 unsigned char bits;
18222
864f92be 18223 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18224 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18225 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18226 HDA_AMP_MUTE, bits);
f1d4e28b 18227 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18228 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18229}
18230
18231static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18232{
18233 unsigned int present;
18234 unsigned char bits;
18235
864f92be 18236 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18237 bits = present ? HDA_AMP_MUTE : 0;
18238 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18239 HDA_AMP_MUTE, bits);
f1d4e28b 18240 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18241 HDA_AMP_MUTE, bits);
f1d4e28b 18242 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18243 HDA_AMP_MUTE, bits);
f1d4e28b 18244 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18245 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18246}
18247
18248static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18249{
18250 unsigned int present;
18251 unsigned char bits;
18252
864f92be 18253 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18254 bits = present ? HDA_AMP_MUTE : 0;
18255 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18256 HDA_AMP_MUTE, bits);
f1d4e28b 18257 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18258 HDA_AMP_MUTE, bits);
f1d4e28b 18259 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18260 HDA_AMP_MUTE, bits);
f1d4e28b 18261 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18262 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18263}
18264
18265static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18266{
18267 unsigned int present;
18268 unsigned char bits;
18269
864f92be 18270 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18271 bits = present ? 0 : PIN_OUT;
18272 snd_hda_codec_write(codec, 0x14, 0,
18273 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18274}
18275
18276static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18277{
18278 unsigned int present1, present2;
18279
864f92be
WF
18280 present1 = snd_hda_jack_detect(codec, 0x21);
18281 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18282
18283 if (present1 || present2) {
18284 snd_hda_codec_write_cache(codec, 0x14, 0,
18285 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18286 } else {
18287 snd_hda_codec_write_cache(codec, 0x14, 0,
18288 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18289 }
18290}
18291
18292static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18293{
18294 unsigned int present1, present2;
18295
864f92be
WF
18296 present1 = snd_hda_jack_detect(codec, 0x1b);
18297 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18298
18299 if (present1 || present2) {
18300 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18301 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18302 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18303 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18304 } else {
18305 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18306 HDA_AMP_MUTE, 0);
f1d4e28b 18307 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18308 HDA_AMP_MUTE, 0);
f1d4e28b 18309 }
6dda9f4a
KY
18310}
18311
ebb83eeb
KY
18312static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18313{
18314 unsigned int present1, present2;
18315
18316 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18317 AC_VERB_GET_PIN_SENSE, 0)
18318 & AC_PINSENSE_PRESENCE;
18319 present2 = snd_hda_codec_read(codec, 0x21, 0,
18320 AC_VERB_GET_PIN_SENSE, 0)
18321 & AC_PINSENSE_PRESENCE;
18322
18323 if (present1 || present2) {
18324 snd_hda_codec_write_cache(codec, 0x14, 0,
18325 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18326 snd_hda_codec_write_cache(codec, 0x17, 0,
18327 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18328 } else {
18329 snd_hda_codec_write_cache(codec, 0x14, 0,
18330 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18331 snd_hda_codec_write_cache(codec, 0x17, 0,
18332 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18333 }
18334}
18335
18336static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18337{
18338 unsigned int present1, present2;
18339
18340 present1 = snd_hda_codec_read(codec, 0x21, 0,
18341 AC_VERB_GET_PIN_SENSE, 0)
18342 & AC_PINSENSE_PRESENCE;
18343 present2 = snd_hda_codec_read(codec, 0x15, 0,
18344 AC_VERB_GET_PIN_SENSE, 0)
18345 & AC_PINSENSE_PRESENCE;
18346
18347 if (present1 || present2) {
18348 snd_hda_codec_write_cache(codec, 0x14, 0,
18349 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18350 snd_hda_codec_write_cache(codec, 0x17, 0,
18351 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18352 } else {
18353 snd_hda_codec_write_cache(codec, 0x14, 0,
18354 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18355 snd_hda_codec_write_cache(codec, 0x17, 0,
18356 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18357 }
18358}
18359
6dda9f4a
KY
18360static void alc663_m51va_unsol_event(struct hda_codec *codec,
18361 unsigned int res)
18362{
18363 switch (res >> 26) {
18364 case ALC880_HP_EVENT:
18365 alc663_m51va_speaker_automute(codec);
18366 break;
18367 case ALC880_MIC_EVENT:
4f5d1706 18368 alc_mic_automute(codec);
6dda9f4a
KY
18369 break;
18370 }
18371}
18372
4f5d1706
TI
18373static void alc663_m51va_setup(struct hda_codec *codec)
18374{
18375 struct alc_spec *spec = codec->spec;
18376 spec->ext_mic.pin = 0x18;
18377 spec->ext_mic.mux_idx = 0;
18378 spec->int_mic.pin = 0x12;
ebb83eeb 18379 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18380 spec->auto_mic = 1;
18381}
18382
6dda9f4a
KY
18383static void alc663_m51va_inithook(struct hda_codec *codec)
18384{
18385 alc663_m51va_speaker_automute(codec);
4f5d1706 18386 alc_mic_automute(codec);
6dda9f4a
KY
18387}
18388
f1d4e28b 18389/* ***************** Mode1 ******************************/
4f5d1706 18390#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18391
18392static void alc663_mode1_setup(struct hda_codec *codec)
18393{
18394 struct alc_spec *spec = codec->spec;
18395 spec->ext_mic.pin = 0x18;
18396 spec->ext_mic.mux_idx = 0;
18397 spec->int_mic.pin = 0x19;
18398 spec->int_mic.mux_idx = 1;
18399 spec->auto_mic = 1;
18400}
18401
4f5d1706 18402#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18403
f1d4e28b
KY
18404/* ***************** Mode2 ******************************/
18405static void alc662_mode2_unsol_event(struct hda_codec *codec,
18406 unsigned int res)
18407{
18408 switch (res >> 26) {
18409 case ALC880_HP_EVENT:
18410 alc662_f5z_speaker_automute(codec);
18411 break;
18412 case ALC880_MIC_EVENT:
4f5d1706 18413 alc_mic_automute(codec);
f1d4e28b
KY
18414 break;
18415 }
18416}
18417
ebb83eeb 18418#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18419
f1d4e28b
KY
18420static void alc662_mode2_inithook(struct hda_codec *codec)
18421{
18422 alc662_f5z_speaker_automute(codec);
4f5d1706 18423 alc_mic_automute(codec);
f1d4e28b
KY
18424}
18425/* ***************** Mode3 ******************************/
18426static void alc663_mode3_unsol_event(struct hda_codec *codec,
18427 unsigned int res)
18428{
18429 switch (res >> 26) {
18430 case ALC880_HP_EVENT:
18431 alc663_two_hp_m1_speaker_automute(codec);
18432 break;
18433 case ALC880_MIC_EVENT:
4f5d1706 18434 alc_mic_automute(codec);
f1d4e28b
KY
18435 break;
18436 }
18437}
18438
ebb83eeb 18439#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18440
f1d4e28b
KY
18441static void alc663_mode3_inithook(struct hda_codec *codec)
18442{
18443 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18444 alc_mic_automute(codec);
f1d4e28b
KY
18445}
18446/* ***************** Mode4 ******************************/
18447static void alc663_mode4_unsol_event(struct hda_codec *codec,
18448 unsigned int res)
18449{
18450 switch (res >> 26) {
18451 case ALC880_HP_EVENT:
18452 alc663_21jd_two_speaker_automute(codec);
18453 break;
18454 case ALC880_MIC_EVENT:
4f5d1706 18455 alc_mic_automute(codec);
f1d4e28b
KY
18456 break;
18457 }
18458}
18459
ebb83eeb 18460#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18461
f1d4e28b
KY
18462static void alc663_mode4_inithook(struct hda_codec *codec)
18463{
18464 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18465 alc_mic_automute(codec);
f1d4e28b
KY
18466}
18467/* ***************** Mode5 ******************************/
18468static void alc663_mode5_unsol_event(struct hda_codec *codec,
18469 unsigned int res)
18470{
18471 switch (res >> 26) {
18472 case ALC880_HP_EVENT:
18473 alc663_15jd_two_speaker_automute(codec);
18474 break;
18475 case ALC880_MIC_EVENT:
4f5d1706 18476 alc_mic_automute(codec);
f1d4e28b
KY
18477 break;
18478 }
18479}
18480
ebb83eeb 18481#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18482
f1d4e28b
KY
18483static void alc663_mode5_inithook(struct hda_codec *codec)
18484{
18485 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18486 alc_mic_automute(codec);
f1d4e28b
KY
18487}
18488/* ***************** Mode6 ******************************/
18489static void alc663_mode6_unsol_event(struct hda_codec *codec,
18490 unsigned int res)
18491{
18492 switch (res >> 26) {
18493 case ALC880_HP_EVENT:
18494 alc663_two_hp_m2_speaker_automute(codec);
18495 break;
18496 case ALC880_MIC_EVENT:
4f5d1706 18497 alc_mic_automute(codec);
f1d4e28b
KY
18498 break;
18499 }
18500}
18501
ebb83eeb 18502#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18503
f1d4e28b
KY
18504static void alc663_mode6_inithook(struct hda_codec *codec)
18505{
18506 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18507 alc_mic_automute(codec);
f1d4e28b
KY
18508}
18509
ebb83eeb
KY
18510/* ***************** Mode7 ******************************/
18511static void alc663_mode7_unsol_event(struct hda_codec *codec,
18512 unsigned int res)
18513{
18514 switch (res >> 26) {
18515 case ALC880_HP_EVENT:
18516 alc663_two_hp_m7_speaker_automute(codec);
18517 break;
18518 case ALC880_MIC_EVENT:
18519 alc_mic_automute(codec);
18520 break;
18521 }
18522}
18523
18524#define alc663_mode7_setup alc663_mode1_setup
18525
18526static void alc663_mode7_inithook(struct hda_codec *codec)
18527{
18528 alc663_two_hp_m7_speaker_automute(codec);
18529 alc_mic_automute(codec);
18530}
18531
18532/* ***************** Mode8 ******************************/
18533static void alc663_mode8_unsol_event(struct hda_codec *codec,
18534 unsigned int res)
18535{
18536 switch (res >> 26) {
18537 case ALC880_HP_EVENT:
18538 alc663_two_hp_m8_speaker_automute(codec);
18539 break;
18540 case ALC880_MIC_EVENT:
18541 alc_mic_automute(codec);
18542 break;
18543 }
18544}
18545
18546#define alc663_mode8_setup alc663_m51va_setup
18547
18548static void alc663_mode8_inithook(struct hda_codec *codec)
18549{
18550 alc663_two_hp_m8_speaker_automute(codec);
18551 alc_mic_automute(codec);
18552}
18553
6dda9f4a
KY
18554static void alc663_g71v_hp_automute(struct hda_codec *codec)
18555{
18556 unsigned int present;
18557 unsigned char bits;
18558
864f92be 18559 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18560 bits = present ? HDA_AMP_MUTE : 0;
18561 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18562 HDA_AMP_MUTE, bits);
18563 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18564 HDA_AMP_MUTE, bits);
18565}
18566
18567static void alc663_g71v_front_automute(struct hda_codec *codec)
18568{
18569 unsigned int present;
18570 unsigned char bits;
18571
864f92be 18572 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18573 bits = present ? HDA_AMP_MUTE : 0;
18574 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18575 HDA_AMP_MUTE, bits);
18576}
18577
18578static void alc663_g71v_unsol_event(struct hda_codec *codec,
18579 unsigned int res)
18580{
18581 switch (res >> 26) {
18582 case ALC880_HP_EVENT:
18583 alc663_g71v_hp_automute(codec);
18584 break;
18585 case ALC880_FRONT_EVENT:
18586 alc663_g71v_front_automute(codec);
18587 break;
18588 case ALC880_MIC_EVENT:
4f5d1706 18589 alc_mic_automute(codec);
6dda9f4a
KY
18590 break;
18591 }
18592}
18593
4f5d1706
TI
18594#define alc663_g71v_setup alc663_m51va_setup
18595
6dda9f4a
KY
18596static void alc663_g71v_inithook(struct hda_codec *codec)
18597{
18598 alc663_g71v_front_automute(codec);
18599 alc663_g71v_hp_automute(codec);
4f5d1706 18600 alc_mic_automute(codec);
6dda9f4a
KY
18601}
18602
18603static void alc663_g50v_unsol_event(struct hda_codec *codec,
18604 unsigned int res)
18605{
18606 switch (res >> 26) {
18607 case ALC880_HP_EVENT:
18608 alc663_m51va_speaker_automute(codec);
18609 break;
18610 case ALC880_MIC_EVENT:
4f5d1706 18611 alc_mic_automute(codec);
6dda9f4a
KY
18612 break;
18613 }
18614}
18615
4f5d1706
TI
18616#define alc663_g50v_setup alc663_m51va_setup
18617
6dda9f4a
KY
18618static void alc663_g50v_inithook(struct hda_codec *codec)
18619{
18620 alc663_m51va_speaker_automute(codec);
4f5d1706 18621 alc_mic_automute(codec);
6dda9f4a
KY
18622}
18623
f1d4e28b
KY
18624static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18625 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18626 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18627
5f99f86a 18628 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18629 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18630 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18631
5f99f86a 18632 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18633 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18634 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18635 { } /* end */
18636};
18637
9541ba1d
CP
18638static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18639 /* Master Playback automatically created from Speaker and Headphone */
18640 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18641 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18642 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18643 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18644
8607f7c4
DH
18645 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18646 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18647 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18648
28c4edb7
DH
18649 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18650 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18651 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18652 { } /* end */
18653};
18654
cb53c626
TI
18655#ifdef CONFIG_SND_HDA_POWER_SAVE
18656#define alc662_loopbacks alc880_loopbacks
18657#endif
18658
bc9f98a9 18659
def319f9 18660/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18661#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18662#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18663#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18664#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18665
18666/*
18667 * configuration and preset
18668 */
ea734963 18669static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18670 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18671 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18672 [ALC662_3ST_6ch] = "3stack-6ch",
18673 [ALC662_5ST_DIG] = "6stack-dig",
18674 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18675 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18676 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18677 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18678 [ALC663_ASUS_M51VA] = "m51va",
18679 [ALC663_ASUS_G71V] = "g71v",
18680 [ALC663_ASUS_H13] = "h13",
18681 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18682 [ALC663_ASUS_MODE1] = "asus-mode1",
18683 [ALC662_ASUS_MODE2] = "asus-mode2",
18684 [ALC663_ASUS_MODE3] = "asus-mode3",
18685 [ALC663_ASUS_MODE4] = "asus-mode4",
18686 [ALC663_ASUS_MODE5] = "asus-mode5",
18687 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18688 [ALC663_ASUS_MODE7] = "asus-mode7",
18689 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18690 [ALC272_DELL] = "dell",
18691 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18692 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18693 [ALC662_AUTO] = "auto",
18694};
18695
18696static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18697 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18698 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18699 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18700 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18701 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18702 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18703 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18704 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18705 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18706 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18707 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18708 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18709 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18710 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18711 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18712 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18713 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18714 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18715 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18716 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18717 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18718 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18719 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18720 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18721 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18722 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18723 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18724 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18725 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18726 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18727 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18728 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18729 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18730 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18731 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18732 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18733 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18734 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18735 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18736 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18737 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18738 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18739 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18740 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18741 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18742 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18743 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18744 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18745 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18746 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18747 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18748 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18749 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18750 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18751 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18752 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18753 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18754 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18755 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18756 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18757 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18758 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18759 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18760 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18761 ALC662_3ST_6ch_DIG),
4dee8baa 18762 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18763 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18764 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18765 ALC662_3ST_6ch_DIG),
6227cdce 18766 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18767 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18768 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18769 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18770 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18771 ALC662_3ST_6ch_DIG),
dea0a509
TI
18772 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18773 ALC663_ASUS_H13),
965b76d2 18774 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18775 {}
18776};
18777
18778static struct alc_config_preset alc662_presets[] = {
18779 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18780 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18781 .init_verbs = { alc662_init_verbs },
18782 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18783 .dac_nids = alc662_dac_nids,
18784 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18785 .dig_in_nid = ALC662_DIGIN_NID,
18786 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18787 .channel_mode = alc662_3ST_2ch_modes,
18788 .input_mux = &alc662_capture_source,
18789 },
18790 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18791 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18792 .init_verbs = { alc662_init_verbs },
18793 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18794 .dac_nids = alc662_dac_nids,
18795 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18796 .dig_in_nid = ALC662_DIGIN_NID,
18797 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18798 .channel_mode = alc662_3ST_6ch_modes,
18799 .need_dac_fix = 1,
18800 .input_mux = &alc662_capture_source,
f12ab1e0 18801 },
bc9f98a9 18802 [ALC662_3ST_6ch] = {
f9e336f6 18803 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18804 .init_verbs = { alc662_init_verbs },
18805 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18806 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18807 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18808 .channel_mode = alc662_3ST_6ch_modes,
18809 .need_dac_fix = 1,
18810 .input_mux = &alc662_capture_source,
f12ab1e0 18811 },
bc9f98a9 18812 [ALC662_5ST_DIG] = {
f9e336f6 18813 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18814 .init_verbs = { alc662_init_verbs },
18815 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18816 .dac_nids = alc662_dac_nids,
18817 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18818 .dig_in_nid = ALC662_DIGIN_NID,
18819 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18820 .channel_mode = alc662_5stack_modes,
18821 .input_mux = &alc662_capture_source,
18822 },
18823 [ALC662_LENOVO_101E] = {
f9e336f6 18824 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18825 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18826 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18827 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18828 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18829 .channel_mode = alc662_3ST_2ch_modes,
18830 .input_mux = &alc662_lenovo_101e_capture_source,
18831 .unsol_event = alc662_lenovo_101e_unsol_event,
18832 .init_hook = alc662_lenovo_101e_all_automute,
18833 },
291702f0 18834 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18835 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18836 .init_verbs = { alc662_init_verbs,
18837 alc662_eeepc_sue_init_verbs },
18838 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18839 .dac_nids = alc662_dac_nids,
291702f0
KY
18840 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18841 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18842 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18843 .setup = alc662_eeepc_setup,
291702f0
KY
18844 .init_hook = alc662_eeepc_inithook,
18845 },
8c427226 18846 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18847 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18848 alc662_chmode_mixer },
18849 .init_verbs = { alc662_init_verbs,
18850 alc662_eeepc_ep20_sue_init_verbs },
18851 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18852 .dac_nids = alc662_dac_nids,
8c427226
KY
18853 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18854 .channel_mode = alc662_3ST_6ch_modes,
18855 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18856 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18857 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18858 .init_hook = alc662_eeepc_ep20_inithook,
18859 },
f1d4e28b 18860 [ALC662_ECS] = {
f9e336f6 18861 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18862 .init_verbs = { alc662_init_verbs,
18863 alc662_ecs_init_verbs },
18864 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18865 .dac_nids = alc662_dac_nids,
18866 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18867 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18868 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18869 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18870 .init_hook = alc662_eeepc_inithook,
18871 },
6dda9f4a 18872 [ALC663_ASUS_M51VA] = {
f9e336f6 18873 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18874 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18875 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18876 .dac_nids = alc662_dac_nids,
18877 .dig_out_nid = ALC662_DIGOUT_NID,
18878 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18879 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18880 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18881 .setup = alc663_m51va_setup,
6dda9f4a
KY
18882 .init_hook = alc663_m51va_inithook,
18883 },
18884 [ALC663_ASUS_G71V] = {
f9e336f6 18885 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18886 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18887 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18888 .dac_nids = alc662_dac_nids,
18889 .dig_out_nid = ALC662_DIGOUT_NID,
18890 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18891 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18892 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18893 .setup = alc663_g71v_setup,
6dda9f4a
KY
18894 .init_hook = alc663_g71v_inithook,
18895 },
18896 [ALC663_ASUS_H13] = {
f9e336f6 18897 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18898 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18899 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18900 .dac_nids = alc662_dac_nids,
18901 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18902 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18903 .unsol_event = alc663_m51va_unsol_event,
18904 .init_hook = alc663_m51va_inithook,
18905 },
18906 [ALC663_ASUS_G50V] = {
f9e336f6 18907 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18908 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18909 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18910 .dac_nids = alc662_dac_nids,
18911 .dig_out_nid = ALC662_DIGOUT_NID,
18912 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18913 .channel_mode = alc662_3ST_6ch_modes,
18914 .input_mux = &alc663_capture_source,
18915 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18916 .setup = alc663_g50v_setup,
6dda9f4a
KY
18917 .init_hook = alc663_g50v_inithook,
18918 },
f1d4e28b 18919 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18920 .mixers = { alc663_m51va_mixer },
18921 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18922 .init_verbs = { alc662_init_verbs,
18923 alc663_21jd_amic_init_verbs },
18924 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18925 .hp_nid = 0x03,
18926 .dac_nids = alc662_dac_nids,
18927 .dig_out_nid = ALC662_DIGOUT_NID,
18928 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18929 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18930 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18931 .setup = alc663_mode1_setup,
f1d4e28b
KY
18932 .init_hook = alc663_mode1_inithook,
18933 },
18934 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18935 .mixers = { alc662_1bjd_mixer },
18936 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18937 .init_verbs = { alc662_init_verbs,
18938 alc662_1bjd_amic_init_verbs },
18939 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18940 .dac_nids = alc662_dac_nids,
18941 .dig_out_nid = ALC662_DIGOUT_NID,
18942 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18943 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18944 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18945 .setup = alc662_mode2_setup,
f1d4e28b
KY
18946 .init_hook = alc662_mode2_inithook,
18947 },
18948 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18949 .mixers = { alc663_two_hp_m1_mixer },
18950 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18951 .init_verbs = { alc662_init_verbs,
18952 alc663_two_hp_amic_m1_init_verbs },
18953 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18954 .hp_nid = 0x03,
18955 .dac_nids = alc662_dac_nids,
18956 .dig_out_nid = ALC662_DIGOUT_NID,
18957 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18958 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18959 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18960 .setup = alc663_mode3_setup,
f1d4e28b
KY
18961 .init_hook = alc663_mode3_inithook,
18962 },
18963 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18964 .mixers = { alc663_asus_21jd_clfe_mixer },
18965 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18966 .init_verbs = { alc662_init_verbs,
18967 alc663_21jd_amic_init_verbs},
18968 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18969 .hp_nid = 0x03,
18970 .dac_nids = alc662_dac_nids,
18971 .dig_out_nid = ALC662_DIGOUT_NID,
18972 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18973 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18974 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18975 .setup = alc663_mode4_setup,
f1d4e28b
KY
18976 .init_hook = alc663_mode4_inithook,
18977 },
18978 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18979 .mixers = { alc663_asus_15jd_clfe_mixer },
18980 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18981 .init_verbs = { alc662_init_verbs,
18982 alc663_15jd_amic_init_verbs },
18983 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18984 .hp_nid = 0x03,
18985 .dac_nids = alc662_dac_nids,
18986 .dig_out_nid = ALC662_DIGOUT_NID,
18987 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18988 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18989 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18990 .setup = alc663_mode5_setup,
f1d4e28b
KY
18991 .init_hook = alc663_mode5_inithook,
18992 },
18993 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18994 .mixers = { alc663_two_hp_m2_mixer },
18995 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18996 .init_verbs = { alc662_init_verbs,
18997 alc663_two_hp_amic_m2_init_verbs },
18998 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18999 .hp_nid = 0x03,
19000 .dac_nids = alc662_dac_nids,
19001 .dig_out_nid = ALC662_DIGOUT_NID,
19002 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19003 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 19004 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 19005 .setup = alc663_mode6_setup,
f1d4e28b
KY
19006 .init_hook = alc663_mode6_inithook,
19007 },
ebb83eeb
KY
19008 [ALC663_ASUS_MODE7] = {
19009 .mixers = { alc663_mode7_mixer },
19010 .cap_mixer = alc662_auto_capture_mixer,
19011 .init_verbs = { alc662_init_verbs,
19012 alc663_mode7_init_verbs },
19013 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19014 .hp_nid = 0x03,
19015 .dac_nids = alc662_dac_nids,
19016 .dig_out_nid = ALC662_DIGOUT_NID,
19017 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19018 .channel_mode = alc662_3ST_2ch_modes,
19019 .unsol_event = alc663_mode7_unsol_event,
19020 .setup = alc663_mode7_setup,
19021 .init_hook = alc663_mode7_inithook,
19022 },
19023 [ALC663_ASUS_MODE8] = {
19024 .mixers = { alc663_mode8_mixer },
19025 .cap_mixer = alc662_auto_capture_mixer,
19026 .init_verbs = { alc662_init_verbs,
19027 alc663_mode8_init_verbs },
19028 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19029 .hp_nid = 0x03,
19030 .dac_nids = alc662_dac_nids,
19031 .dig_out_nid = ALC662_DIGOUT_NID,
19032 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19033 .channel_mode = alc662_3ST_2ch_modes,
19034 .unsol_event = alc663_mode8_unsol_event,
19035 .setup = alc663_mode8_setup,
19036 .init_hook = alc663_mode8_inithook,
19037 },
622e84cd
KY
19038 [ALC272_DELL] = {
19039 .mixers = { alc663_m51va_mixer },
19040 .cap_mixer = alc272_auto_capture_mixer,
19041 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
19042 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19043 .dac_nids = alc662_dac_nids,
19044 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19045 .adc_nids = alc272_adc_nids,
19046 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19047 .capsrc_nids = alc272_capsrc_nids,
19048 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19049 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19050 .setup = alc663_m51va_setup,
622e84cd
KY
19051 .init_hook = alc663_m51va_inithook,
19052 },
19053 [ALC272_DELL_ZM1] = {
19054 .mixers = { alc663_m51va_mixer },
19055 .cap_mixer = alc662_auto_capture_mixer,
19056 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19057 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19058 .dac_nids = alc662_dac_nids,
19059 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19060 .adc_nids = alc662_adc_nids,
b59bdf3b 19061 .num_adc_nids = 1,
622e84cd
KY
19062 .capsrc_nids = alc662_capsrc_nids,
19063 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19064 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19065 .setup = alc663_m51va_setup,
622e84cd
KY
19066 .init_hook = alc663_m51va_inithook,
19067 },
9541ba1d
CP
19068 [ALC272_SAMSUNG_NC10] = {
19069 .mixers = { alc272_nc10_mixer },
19070 .init_verbs = { alc662_init_verbs,
19071 alc663_21jd_amic_init_verbs },
19072 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19073 .dac_nids = alc272_dac_nids,
19074 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19075 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 19076 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 19077 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19078 .setup = alc663_mode4_setup,
9541ba1d
CP
19079 .init_hook = alc663_mode4_inithook,
19080 },
bc9f98a9
KY
19081};
19082
19083
19084/*
19085 * BIOS auto configuration
19086 */
19087
7085ec12
TI
19088/* convert from MIX nid to DAC */
19089static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19090{
19091 if (nid == 0x0f)
19092 return 0x02;
19093 else if (nid >= 0x0c && nid <= 0x0e)
19094 return nid - 0x0c + 0x02;
cc1c452e
DH
19095 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19096 return 0x25;
7085ec12
TI
19097 else
19098 return 0;
19099}
19100
19101/* get MIX nid connected to the given pin targeted to DAC */
19102static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19103 hda_nid_t dac)
19104{
cc1c452e 19105 hda_nid_t mix[5];
7085ec12
TI
19106 int i, num;
19107
19108 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19109 for (i = 0; i < num; i++) {
19110 if (alc662_mix_to_dac(mix[i]) == dac)
19111 return mix[i];
19112 }
19113 return 0;
19114}
19115
19116/* look for an empty DAC slot */
19117static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19118{
19119 struct alc_spec *spec = codec->spec;
19120 hda_nid_t srcs[5];
19121 int i, j, num;
19122
19123 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19124 if (num < 0)
19125 return 0;
19126 for (i = 0; i < num; i++) {
19127 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19128 if (!nid)
19129 continue;
19130 for (j = 0; j < spec->multiout.num_dacs; j++)
19131 if (spec->multiout.dac_nids[j] == nid)
19132 break;
19133 if (j >= spec->multiout.num_dacs)
19134 return nid;
19135 }
19136 return 0;
19137}
19138
19139/* fill in the dac_nids table from the parsed pin configuration */
19140static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19141 const struct auto_pin_cfg *cfg)
19142{
19143 struct alc_spec *spec = codec->spec;
19144 int i;
19145 hda_nid_t dac;
19146
19147 spec->multiout.dac_nids = spec->private_dac_nids;
19148 for (i = 0; i < cfg->line_outs; i++) {
19149 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19150 if (!dac)
19151 continue;
19152 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19153 }
19154 return 0;
19155}
19156
bcb2f0f5
TI
19157static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19158 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19159{
bcb2f0f5 19160 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
19161 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19162}
19163
bcb2f0f5
TI
19164static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19165 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19166{
bcb2f0f5 19167 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19168 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19169}
19170
bcb2f0f5
TI
19171#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19172 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19173#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19174 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19175#define alc662_add_stereo_vol(spec, pfx, nid) \
19176 alc662_add_vol_ctl(spec, pfx, nid, 3)
19177#define alc662_add_stereo_sw(spec, pfx, nid) \
19178 alc662_add_sw_ctl(spec, pfx, nid, 3)
19179
bc9f98a9 19180/* add playback controls from the parsed DAC table */
7085ec12 19181static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19182 const struct auto_pin_cfg *cfg)
19183{
7085ec12 19184 struct alc_spec *spec = codec->spec;
ea734963 19185 static const char * const chname[4] = {
bc9f98a9
KY
19186 "Front", "Surround", NULL /*CLFE*/, "Side"
19187 };
bcb2f0f5 19188 const char *pfx = alc_get_line_out_pfx(cfg, true);
7085ec12 19189 hda_nid_t nid, mix;
bc9f98a9
KY
19190 int i, err;
19191
19192 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19193 nid = spec->multiout.dac_nids[i];
19194 if (!nid)
19195 continue;
19196 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19197 if (!mix)
bc9f98a9 19198 continue;
bcb2f0f5 19199 if (!pfx && i == 2) {
bc9f98a9 19200 /* Center/LFE */
7085ec12 19201 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19202 if (err < 0)
19203 return err;
7085ec12 19204 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19205 if (err < 0)
19206 return err;
7085ec12 19207 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19208 if (err < 0)
19209 return err;
7085ec12 19210 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19211 if (err < 0)
19212 return err;
19213 } else {
bcb2f0f5
TI
19214 const char *name = pfx;
19215 if (!name)
19216 name = chname[i];
19217 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
bc9f98a9
KY
19218 if (err < 0)
19219 return err;
bcb2f0f5 19220 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
bc9f98a9
KY
19221 if (err < 0)
19222 return err;
19223 }
19224 }
19225 return 0;
19226}
19227
19228/* add playback controls for speaker and HP outputs */
7085ec12
TI
19229/* return DAC nid if any new DAC is assigned */
19230static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19231 const char *pfx)
19232{
7085ec12
TI
19233 struct alc_spec *spec = codec->spec;
19234 hda_nid_t nid, mix;
bc9f98a9 19235 int err;
bc9f98a9
KY
19236
19237 if (!pin)
19238 return 0;
7085ec12
TI
19239 nid = alc662_look_for_dac(codec, pin);
19240 if (!nid) {
7085ec12
TI
19241 /* the corresponding DAC is already occupied */
19242 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19243 return 0; /* no way */
19244 /* create a switch only */
0afe5f89 19245 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19246 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19247 }
19248
7085ec12
TI
19249 mix = alc662_dac_to_mix(codec, pin, nid);
19250 if (!mix)
19251 return 0;
19252 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19253 if (err < 0)
19254 return err;
19255 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19256 if (err < 0)
19257 return err;
19258 return nid;
bc9f98a9
KY
19259}
19260
19261/* create playback/capture controls for input pins */
05f5f477 19262#define alc662_auto_create_input_ctls \
4b7348a1 19263 alc882_auto_create_input_ctls
bc9f98a9
KY
19264
19265static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19266 hda_nid_t nid, int pin_type,
7085ec12 19267 hda_nid_t dac)
bc9f98a9 19268{
7085ec12 19269 int i, num;
ce503f38 19270 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19271
f6c7e546 19272 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19273 /* need the manual connection? */
7085ec12
TI
19274 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19275 if (num <= 1)
19276 return;
19277 for (i = 0; i < num; i++) {
19278 if (alc662_mix_to_dac(srcs[i]) != dac)
19279 continue;
19280 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19281 return;
bc9f98a9
KY
19282 }
19283}
19284
19285static void alc662_auto_init_multi_out(struct hda_codec *codec)
19286{
19287 struct alc_spec *spec = codec->spec;
7085ec12 19288 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19289 int i;
19290
19291 for (i = 0; i <= HDA_SIDE; i++) {
19292 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19293 if (nid)
baba8ee9 19294 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19295 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19296 }
19297}
19298
19299static void alc662_auto_init_hp_out(struct hda_codec *codec)
19300{
19301 struct alc_spec *spec = codec->spec;
19302 hda_nid_t pin;
19303
19304 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19305 if (pin)
19306 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19307 spec->multiout.hp_nid);
f6c7e546
TI
19308 pin = spec->autocfg.speaker_pins[0];
19309 if (pin)
7085ec12
TI
19310 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19311 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19312}
19313
bc9f98a9
KY
19314#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19315
19316static void alc662_auto_init_analog_input(struct hda_codec *codec)
19317{
19318 struct alc_spec *spec = codec->spec;
66ceeb6b 19319 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19320 int i;
19321
66ceeb6b
TI
19322 for (i = 0; i < cfg->num_inputs; i++) {
19323 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19324 if (alc_is_input_pin(codec, nid)) {
30ea098f 19325 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19326 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19327 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19328 snd_hda_codec_write(codec, nid, 0,
19329 AC_VERB_SET_AMP_GAIN_MUTE,
19330 AMP_OUT_MUTE);
19331 }
19332 }
19333}
19334
f511b01c
TI
19335#define alc662_auto_init_input_src alc882_auto_init_input_src
19336
bc9f98a9
KY
19337static int alc662_parse_auto_config(struct hda_codec *codec)
19338{
19339 struct alc_spec *spec = codec->spec;
19340 int err;
19341 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19342
19343 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19344 alc662_ignore);
19345 if (err < 0)
19346 return err;
19347 if (!spec->autocfg.line_outs)
19348 return 0; /* can't find valid BIOS pin config */
19349
7085ec12 19350 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19351 if (err < 0)
19352 return err;
7085ec12 19353 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19354 if (err < 0)
19355 return err;
7085ec12 19356 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19357 spec->autocfg.speaker_pins[0],
19358 "Speaker");
19359 if (err < 0)
19360 return err;
7085ec12
TI
19361 if (err)
19362 spec->multiout.extra_out_nid[0] = err;
19363 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19364 "Headphone");
19365 if (err < 0)
19366 return err;
7085ec12
TI
19367 if (err)
19368 spec->multiout.hp_nid = err;
05f5f477 19369 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19370 if (err < 0)
bc9f98a9
KY
19371 return err;
19372
19373 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19374
757899ac 19375 alc_auto_parse_digital(codec);
bc9f98a9 19376
603c4019 19377 if (spec->kctls.list)
d88897ea 19378 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19379
19380 spec->num_mux_defs = 1;
61b9b9b1 19381 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19382
cec27c89
KY
19383 add_verb(spec, alc662_init_verbs);
19384 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19385 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19386 add_verb(spec, alc663_init_verbs);
19387
19388 if (codec->vendor_id == 0x10ec0272)
19389 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19390
19391 err = alc_auto_add_mic_boost(codec);
19392 if (err < 0)
19393 return err;
19394
6227cdce
KY
19395 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19396 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19397 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19398 else
19399 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19400
8c87286f 19401 return 1;
bc9f98a9
KY
19402}
19403
19404/* additional initialization for auto-configuration model */
19405static void alc662_auto_init(struct hda_codec *codec)
19406{
f6c7e546 19407 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19408 alc662_auto_init_multi_out(codec);
19409 alc662_auto_init_hp_out(codec);
19410 alc662_auto_init_analog_input(codec);
f511b01c 19411 alc662_auto_init_input_src(codec);
757899ac 19412 alc_auto_init_digital(codec);
f6c7e546 19413 if (spec->unsol_event)
7fb0d78f 19414 alc_inithook(codec);
bc9f98a9
KY
19415}
19416
6be7948f 19417static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19418 const struct alc_fixup *fix, int action)
6fc398cb 19419{
b5bfbc67 19420 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19421 return;
6be7948f
TB
19422 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19423 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19424 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19425 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19426 (0 << AC_AMPCAP_MUTE_SHIFT)))
19427 printk(KERN_WARNING
19428 "hda_codec: failed to override amp caps for NID 0x2\n");
19429}
19430
6cb3b707 19431enum {
2df03514 19432 ALC662_FIXUP_ASPIRE,
6cb3b707 19433 ALC662_FIXUP_IDEAPAD,
6be7948f 19434 ALC272_FIXUP_MARIO,
d2ebd479 19435 ALC662_FIXUP_CZC_P10T,
6cb3b707
DH
19436};
19437
19438static const struct alc_fixup alc662_fixups[] = {
2df03514 19439 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19440 .type = ALC_FIXUP_PINS,
19441 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19442 { 0x15, 0x99130112 }, /* subwoofer */
19443 { }
19444 }
19445 },
6cb3b707 19446 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19447 .type = ALC_FIXUP_PINS,
19448 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19449 { 0x17, 0x99130112 }, /* subwoofer */
19450 { }
19451 }
19452 },
6be7948f 19453 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19454 .type = ALC_FIXUP_FUNC,
19455 .v.func = alc272_fixup_mario,
d2ebd479
AA
19456 },
19457 [ALC662_FIXUP_CZC_P10T] = {
19458 .type = ALC_FIXUP_VERBS,
19459 .v.verbs = (const struct hda_verb[]) {
19460 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19461 {}
19462 }
19463 },
6cb3b707
DH
19464};
19465
19466static struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19467 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
2df03514 19468 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19469 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19470 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19471 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19472 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19473 {}
19474};
19475
6be7948f
TB
19476static const struct alc_model_fixup alc662_fixup_models[] = {
19477 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19478 {}
19479};
6cb3b707
DH
19480
19481
bc9f98a9
KY
19482static int patch_alc662(struct hda_codec *codec)
19483{
19484 struct alc_spec *spec;
19485 int err, board_config;
693194f3 19486 int coef;
bc9f98a9
KY
19487
19488 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19489 if (!spec)
19490 return -ENOMEM;
19491
19492 codec->spec = spec;
19493
da00c244
KY
19494 alc_auto_parse_customize_define(codec);
19495
2c3bf9ab
TI
19496 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19497
693194f3
KY
19498 coef = alc_read_coef_idx(codec, 0);
19499 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19500 alc_codec_rename(codec, "ALC661");
693194f3
KY
19501 else if (coef & (1 << 14) &&
19502 codec->bus->pci->subsystem_vendor == 0x1025 &&
19503 spec->cdefine.platform_type == 1)
c027ddcd 19504 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19505 else if (coef == 0x4011)
19506 alc_codec_rename(codec, "ALC656");
274693f3 19507
bc9f98a9
KY
19508 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19509 alc662_models,
19510 alc662_cfg_tbl);
19511 if (board_config < 0) {
9a11f1aa
TI
19512 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19513 codec->chip_name);
bc9f98a9
KY
19514 board_config = ALC662_AUTO;
19515 }
19516
19517 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19518 alc_pick_fixup(codec, alc662_fixup_models,
19519 alc662_fixup_tbl, alc662_fixups);
19520 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19521 /* automatic parse from the BIOS config */
19522 err = alc662_parse_auto_config(codec);
19523 if (err < 0) {
19524 alc_free(codec);
19525 return err;
8c87286f 19526 } else if (!err) {
bc9f98a9
KY
19527 printk(KERN_INFO
19528 "hda_codec: Cannot set up configuration "
19529 "from BIOS. Using base mode...\n");
19530 board_config = ALC662_3ST_2ch_DIG;
19531 }
19532 }
19533
dc1eae25 19534 if (has_cdefine_beep(codec)) {
8af2591d
TI
19535 err = snd_hda_attach_beep_device(codec, 0x1);
19536 if (err < 0) {
19537 alc_free(codec);
19538 return err;
19539 }
680cd536
KK
19540 }
19541
bc9f98a9 19542 if (board_config != ALC662_AUTO)
e9c364c0 19543 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19544
bc9f98a9
KY
19545 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19546 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19547
bc9f98a9
KY
19548 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19549 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19550
dd704698
TI
19551 if (!spec->adc_nids) {
19552 spec->adc_nids = alc662_adc_nids;
19553 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19554 }
19555 if (!spec->capsrc_nids)
19556 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19557
f9e336f6 19558 if (!spec->cap_mixer)
b59bdf3b 19559 set_capture_mixer(codec);
cec27c89 19560
dc1eae25 19561 if (has_cdefine_beep(codec)) {
da00c244
KY
19562 switch (codec->vendor_id) {
19563 case 0x10ec0662:
19564 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19565 break;
19566 case 0x10ec0272:
19567 case 0x10ec0663:
19568 case 0x10ec0665:
19569 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19570 break;
19571 case 0x10ec0273:
19572 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19573 break;
19574 }
cec27c89 19575 }
2134ea4f
TI
19576 spec->vmaster_nid = 0x02;
19577
b5bfbc67
TI
19578 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19579
bc9f98a9 19580 codec->patch_ops = alc_patch_ops;
b5bfbc67 19581 if (board_config == ALC662_AUTO)
bc9f98a9 19582 spec->init_hook = alc662_auto_init;
6cb3b707 19583
bf1b0225
KY
19584 alc_init_jacks(codec);
19585
cb53c626
TI
19586#ifdef CONFIG_SND_HDA_POWER_SAVE
19587 if (!spec->loopback.amplist)
19588 spec->loopback.amplist = alc662_loopbacks;
19589#endif
bc9f98a9
KY
19590
19591 return 0;
19592}
19593
274693f3
KY
19594static int patch_alc888(struct hda_codec *codec)
19595{
19596 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19597 kfree(codec->chip_name);
01e0f137
KY
19598 if (codec->vendor_id == 0x10ec0887)
19599 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19600 else
19601 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19602 if (!codec->chip_name) {
19603 alc_free(codec);
274693f3 19604 return -ENOMEM;
ac2c92e0
TI
19605 }
19606 return patch_alc662(codec);
274693f3 19607 }
ac2c92e0 19608 return patch_alc882(codec);
274693f3
KY
19609}
19610
d1eb57f4
KY
19611/*
19612 * ALC680 support
19613 */
c69aefab 19614#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19615#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19616#define alc680_modes alc260_modes
19617
19618static hda_nid_t alc680_dac_nids[3] = {
19619 /* Lout1, Lout2, hp */
19620 0x02, 0x03, 0x04
19621};
19622
19623static hda_nid_t alc680_adc_nids[3] = {
19624 /* ADC0-2 */
19625 /* DMIC, MIC, Line-in*/
19626 0x07, 0x08, 0x09
19627};
19628
c69aefab
KY
19629/*
19630 * Analog capture ADC cgange
19631 */
66ceeb6b
TI
19632static void alc680_rec_autoswitch(struct hda_codec *codec)
19633{
19634 struct alc_spec *spec = codec->spec;
19635 struct auto_pin_cfg *cfg = &spec->autocfg;
19636 int pin_found = 0;
19637 int type_found = AUTO_PIN_LAST;
19638 hda_nid_t nid;
19639 int i;
19640
19641 for (i = 0; i < cfg->num_inputs; i++) {
19642 nid = cfg->inputs[i].pin;
19643 if (!(snd_hda_query_pin_caps(codec, nid) &
19644 AC_PINCAP_PRES_DETECT))
19645 continue;
19646 if (snd_hda_jack_detect(codec, nid)) {
19647 if (cfg->inputs[i].type < type_found) {
19648 type_found = cfg->inputs[i].type;
19649 pin_found = nid;
19650 }
19651 }
19652 }
19653
19654 nid = 0x07;
19655 if (pin_found)
19656 snd_hda_get_connections(codec, pin_found, &nid, 1);
19657
19658 if (nid != spec->cur_adc)
19659 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19660 spec->cur_adc = nid;
19661 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19662 spec->cur_adc_format);
19663}
19664
c69aefab
KY
19665static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19666 struct hda_codec *codec,
19667 unsigned int stream_tag,
19668 unsigned int format,
19669 struct snd_pcm_substream *substream)
19670{
19671 struct alc_spec *spec = codec->spec;
c69aefab 19672
66ceeb6b 19673 spec->cur_adc = 0x07;
c69aefab
KY
19674 spec->cur_adc_stream_tag = stream_tag;
19675 spec->cur_adc_format = format;
19676
66ceeb6b 19677 alc680_rec_autoswitch(codec);
c69aefab
KY
19678 return 0;
19679}
19680
19681static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19682 struct hda_codec *codec,
19683 struct snd_pcm_substream *substream)
19684{
19685 snd_hda_codec_cleanup_stream(codec, 0x07);
19686 snd_hda_codec_cleanup_stream(codec, 0x08);
19687 snd_hda_codec_cleanup_stream(codec, 0x09);
19688 return 0;
19689}
19690
19691static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19692 .substreams = 1, /* can be overridden */
19693 .channels_min = 2,
19694 .channels_max = 2,
19695 /* NID is set in alc_build_pcms */
19696 .ops = {
19697 .prepare = alc680_capture_pcm_prepare,
19698 .cleanup = alc680_capture_pcm_cleanup
19699 },
19700};
19701
d1eb57f4
KY
19702static struct snd_kcontrol_new alc680_base_mixer[] = {
19703 /* output mixer control */
19704 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19705 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19706 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19707 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19708 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19709 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19710 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19711 { }
19712};
19713
c69aefab
KY
19714static struct hda_bind_ctls alc680_bind_cap_vol = {
19715 .ops = &snd_hda_bind_vol,
19716 .values = {
19717 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19718 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19719 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19720 0
19721 },
19722};
19723
19724static struct hda_bind_ctls alc680_bind_cap_switch = {
19725 .ops = &snd_hda_bind_sw,
19726 .values = {
19727 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19728 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19729 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19730 0
19731 },
19732};
19733
19734static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19735 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19736 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19737 { } /* end */
19738};
19739
19740/*
19741 * generic initialization of ADC, input mixers and output mixers
19742 */
19743static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19744 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19745 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19746 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19747
c69aefab
KY
19748 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19749 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19750 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19751 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19752 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19753 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19754
19755 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19757 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19758 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19759 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19760
19761 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19762 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19763 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19764
d1eb57f4
KY
19765 { }
19766};
19767
c69aefab
KY
19768/* toggle speaker-output according to the hp-jack state */
19769static void alc680_base_setup(struct hda_codec *codec)
19770{
19771 struct alc_spec *spec = codec->spec;
19772
19773 spec->autocfg.hp_pins[0] = 0x16;
19774 spec->autocfg.speaker_pins[0] = 0x14;
19775 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19776 spec->autocfg.num_inputs = 2;
19777 spec->autocfg.inputs[0].pin = 0x18;
19778 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19779 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19780 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19781}
19782
19783static void alc680_unsol_event(struct hda_codec *codec,
19784 unsigned int res)
19785{
19786 if ((res >> 26) == ALC880_HP_EVENT)
19787 alc_automute_amp(codec);
19788 if ((res >> 26) == ALC880_MIC_EVENT)
19789 alc680_rec_autoswitch(codec);
19790}
19791
19792static void alc680_inithook(struct hda_codec *codec)
19793{
19794 alc_automute_amp(codec);
19795 alc680_rec_autoswitch(codec);
19796}
19797
d1eb57f4
KY
19798/* create input playback/capture controls for the given pin */
19799static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19800 const char *ctlname, int idx)
19801{
19802 hda_nid_t dac;
19803 int err;
19804
19805 switch (nid) {
19806 case 0x14:
19807 dac = 0x02;
19808 break;
19809 case 0x15:
19810 dac = 0x03;
19811 break;
19812 case 0x16:
19813 dac = 0x04;
19814 break;
19815 default:
19816 return 0;
19817 }
19818 if (spec->multiout.dac_nids[0] != dac &&
19819 spec->multiout.dac_nids[1] != dac) {
19820 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19821 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19822 HDA_OUTPUT));
19823 if (err < 0)
19824 return err;
19825
19826 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19827 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19828
19829 if (err < 0)
19830 return err;
19831 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19832 }
19833
19834 return 0;
19835}
19836
19837/* add playback controls from the parsed DAC table */
19838static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19839 const struct auto_pin_cfg *cfg)
19840{
19841 hda_nid_t nid;
19842 int err;
19843
19844 spec->multiout.dac_nids = spec->private_dac_nids;
19845
19846 nid = cfg->line_out_pins[0];
19847 if (nid) {
19848 const char *name;
19849 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19850 name = "Speaker";
19851 else
19852 name = "Front";
19853 err = alc680_new_analog_output(spec, nid, name, 0);
19854 if (err < 0)
19855 return err;
19856 }
19857
19858 nid = cfg->speaker_pins[0];
19859 if (nid) {
19860 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19861 if (err < 0)
19862 return err;
19863 }
19864 nid = cfg->hp_pins[0];
19865 if (nid) {
19866 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19867 if (err < 0)
19868 return err;
19869 }
19870
19871 return 0;
19872}
19873
19874static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19875 hda_nid_t nid, int pin_type)
19876{
19877 alc_set_pin_output(codec, nid, pin_type);
19878}
19879
19880static void alc680_auto_init_multi_out(struct hda_codec *codec)
19881{
19882 struct alc_spec *spec = codec->spec;
19883 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19884 if (nid) {
19885 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19886 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19887 }
19888}
19889
19890static void alc680_auto_init_hp_out(struct hda_codec *codec)
19891{
19892 struct alc_spec *spec = codec->spec;
19893 hda_nid_t pin;
19894
19895 pin = spec->autocfg.hp_pins[0];
19896 if (pin)
19897 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19898 pin = spec->autocfg.speaker_pins[0];
19899 if (pin)
19900 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19901}
19902
19903/* pcm configuration: identical with ALC880 */
19904#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19905#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19906#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19907#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19908#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19909
19910/*
19911 * BIOS auto configuration
19912 */
19913static int alc680_parse_auto_config(struct hda_codec *codec)
19914{
19915 struct alc_spec *spec = codec->spec;
19916 int err;
19917 static hda_nid_t alc680_ignore[] = { 0 };
19918
19919 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19920 alc680_ignore);
19921 if (err < 0)
19922 return err;
c69aefab 19923
d1eb57f4
KY
19924 if (!spec->autocfg.line_outs) {
19925 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19926 spec->multiout.max_channels = 2;
19927 spec->no_analog = 1;
19928 goto dig_only;
19929 }
19930 return 0; /* can't find valid BIOS pin config */
19931 }
19932 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19933 if (err < 0)
19934 return err;
19935
19936 spec->multiout.max_channels = 2;
19937
19938 dig_only:
19939 /* digital only support output */
757899ac 19940 alc_auto_parse_digital(codec);
d1eb57f4
KY
19941 if (spec->kctls.list)
19942 add_mixer(spec, spec->kctls.list);
19943
19944 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19945
19946 err = alc_auto_add_mic_boost(codec);
19947 if (err < 0)
19948 return err;
19949
19950 return 1;
19951}
19952
19953#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19954
19955/* init callback for auto-configuration model -- overriding the default init */
19956static void alc680_auto_init(struct hda_codec *codec)
19957{
19958 struct alc_spec *spec = codec->spec;
19959 alc680_auto_init_multi_out(codec);
19960 alc680_auto_init_hp_out(codec);
19961 alc680_auto_init_analog_input(codec);
757899ac 19962 alc_auto_init_digital(codec);
d1eb57f4
KY
19963 if (spec->unsol_event)
19964 alc_inithook(codec);
19965}
19966
19967/*
19968 * configuration and preset
19969 */
ea734963 19970static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19971 [ALC680_BASE] = "base",
19972 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19973};
19974
19975static struct snd_pci_quirk alc680_cfg_tbl[] = {
19976 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19977 {}
19978};
19979
19980static struct alc_config_preset alc680_presets[] = {
19981 [ALC680_BASE] = {
19982 .mixers = { alc680_base_mixer },
c69aefab 19983 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19984 .init_verbs = { alc680_init_verbs },
19985 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19986 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19987 .dig_out_nid = ALC680_DIGOUT_NID,
19988 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19989 .channel_mode = alc680_modes,
c69aefab
KY
19990 .unsol_event = alc680_unsol_event,
19991 .setup = alc680_base_setup,
19992 .init_hook = alc680_inithook,
19993
d1eb57f4
KY
19994 },
19995};
19996
19997static int patch_alc680(struct hda_codec *codec)
19998{
19999 struct alc_spec *spec;
20000 int board_config;
20001 int err;
20002
20003 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20004 if (spec == NULL)
20005 return -ENOMEM;
20006
20007 codec->spec = spec;
20008
20009 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20010 alc680_models,
20011 alc680_cfg_tbl);
20012
20013 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20014 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20015 codec->chip_name);
20016 board_config = ALC680_AUTO;
20017 }
20018
20019 if (board_config == ALC680_AUTO) {
20020 /* automatic parse from the BIOS config */
20021 err = alc680_parse_auto_config(codec);
20022 if (err < 0) {
20023 alc_free(codec);
20024 return err;
20025 } else if (!err) {
20026 printk(KERN_INFO
20027 "hda_codec: Cannot set up configuration "
20028 "from BIOS. Using base mode...\n");
20029 board_config = ALC680_BASE;
20030 }
20031 }
20032
20033 if (board_config != ALC680_AUTO)
20034 setup_preset(codec, &alc680_presets[board_config]);
20035
20036 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 20037 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 20038 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 20039 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
20040
20041 if (!spec->adc_nids) {
20042 spec->adc_nids = alc680_adc_nids;
20043 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20044 }
20045
20046 if (!spec->cap_mixer)
20047 set_capture_mixer(codec);
20048
20049 spec->vmaster_nid = 0x02;
20050
20051 codec->patch_ops = alc_patch_ops;
20052 if (board_config == ALC680_AUTO)
20053 spec->init_hook = alc680_auto_init;
20054
20055 return 0;
20056}
20057
1da177e4
LT
20058/*
20059 * patch entries
20060 */
1289e9e8 20061static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 20062 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20063 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20064 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20065 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20066 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20067 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20068 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20069 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20070 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20071 .patch = patch_alc861 },
f32610ed
JS
20072 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20073 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20074 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20075 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20076 .patch = patch_alc882 },
bc9f98a9
KY
20077 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20078 .patch = patch_alc662 },
6dda9f4a 20079 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20080 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20081 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20082 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20083 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20084 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20085 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20086 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20087 .patch = patch_alc882 },
cb308f97 20088 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20089 .patch = patch_alc882 },
df694daa 20090 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20091 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20092 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20093 .patch = patch_alc882 },
274693f3 20094 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20095 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20096 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20097 {} /* terminator */
20098};
1289e9e8
TI
20099
20100MODULE_ALIAS("snd-hda-codec-id:10ec*");
20101
20102MODULE_LICENSE("GPL");
20103MODULE_DESCRIPTION("Realtek HD-audio codec");
20104
20105static struct hda_codec_preset_list realtek_list = {
20106 .preset = snd_hda_preset_realtek,
20107 .owner = THIS_MODULE,
20108};
20109
20110static int __init patch_realtek_init(void)
20111{
20112 return snd_hda_add_codec_preset(&realtek_list);
20113}
20114
20115static void __exit patch_realtek_exit(void)
20116{
20117 snd_hda_delete_codec_preset(&realtek_list);
20118}
20119
20120module_init(patch_realtek_init)
20121module_exit(patch_realtek_exit)