]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Make common input-jack helper functions
[mirror_ubuntu-bionic-kernel.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
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:
5083 return "Speaker";
5084 case AUTO_PIN_HP_OUT:
5085 return "Headphone";
5086 default:
5087 if (cfg->line_outs == 1)
5088 return "PCM";
5089 break;
5090 }
5091 return NULL;
5092}
5093
e9edcee0 5094/* add playback controls from the parsed DAC table */
df694daa
KY
5095static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5096 const struct auto_pin_cfg *cfg)
e9edcee0 5097{
ea734963 5098 static const char * const chname[4] = {
f12ab1e0
TI
5099 "Front", "Surround", NULL /*CLFE*/, "Side"
5100 };
bcb2f0f5 5101 const char *pfx = alc_get_line_out_pfx(cfg, false);
e9edcee0
TI
5102 hda_nid_t nid;
5103 int i, err;
5104
5105 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 5106 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5107 continue;
5108 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5109 if (!pfx && i == 2) {
e9edcee0 5110 /* Center/LFE */
0afe5f89
TI
5111 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5112 "Center",
f12ab1e0
TI
5113 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5114 HDA_OUTPUT));
5115 if (err < 0)
e9edcee0 5116 return err;
0afe5f89
TI
5117 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5118 "LFE",
f12ab1e0
TI
5119 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5120 HDA_OUTPUT));
5121 if (err < 0)
e9edcee0 5122 return err;
0afe5f89
TI
5123 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5124 "Center",
f12ab1e0
TI
5125 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5126 HDA_INPUT));
5127 if (err < 0)
e9edcee0 5128 return err;
0afe5f89
TI
5129 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5130 "LFE",
f12ab1e0
TI
5131 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5132 HDA_INPUT));
5133 if (err < 0)
e9edcee0
TI
5134 return err;
5135 } else {
bcb2f0f5
TI
5136 const char *name = pfx;
5137 if (!name)
5138 name = chname[i];
5139 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5140 name, i,
f12ab1e0
TI
5141 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5142 HDA_OUTPUT));
5143 if (err < 0)
e9edcee0 5144 return err;
bcb2f0f5
TI
5145 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5146 name, i,
f12ab1e0
TI
5147 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5148 HDA_INPUT));
5149 if (err < 0)
e9edcee0
TI
5150 return err;
5151 }
5152 }
e9edcee0
TI
5153 return 0;
5154}
5155
8d88bc3d
TI
5156/* add playback controls for speaker and HP outputs */
5157static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5158 const char *pfx)
e9edcee0
TI
5159{
5160 hda_nid_t nid;
5161 int err;
5162
f12ab1e0 5163 if (!pin)
e9edcee0
TI
5164 return 0;
5165
5166 if (alc880_is_fixed_pin(pin)) {
5167 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5168 /* specify the DAC as the extra output */
f12ab1e0 5169 if (!spec->multiout.hp_nid)
e9edcee0 5170 spec->multiout.hp_nid = nid;
82bc955f
TI
5171 else
5172 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5173 /* control HP volume/switch on the output mixer amp */
5174 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5175 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5176 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5177 if (err < 0)
e9edcee0 5178 return err;
0afe5f89 5179 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5180 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5181 if (err < 0)
e9edcee0
TI
5182 return err;
5183 } else if (alc880_is_multi_pin(pin)) {
5184 /* set manual connection */
e9edcee0 5185 /* we have only a switch on HP-out PIN */
0afe5f89 5186 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5187 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5188 if (err < 0)
e9edcee0
TI
5189 return err;
5190 }
5191 return 0;
5192}
5193
5194/* create input playback/capture controls for the given pin */
f12ab1e0 5195static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5196 const char *ctlname, int ctlidx,
df694daa 5197 int idx, hda_nid_t mix_nid)
e9edcee0 5198{
df694daa 5199 int err;
e9edcee0 5200
66ceeb6b 5201 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5202 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5203 if (err < 0)
e9edcee0 5204 return err;
66ceeb6b 5205 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5206 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5207 if (err < 0)
e9edcee0
TI
5208 return err;
5209 return 0;
5210}
5211
05f5f477
TI
5212static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5213{
5214 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5215 return (pincap & AC_PINCAP_IN) != 0;
5216}
5217
e9edcee0 5218/* create playback/capture controls for input pins */
05f5f477
TI
5219static int alc_auto_create_input_ctls(struct hda_codec *codec,
5220 const struct auto_pin_cfg *cfg,
5221 hda_nid_t mixer,
5222 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5223{
05f5f477 5224 struct alc_spec *spec = codec->spec;
61b9b9b1 5225 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5226 int i, err, idx, type_idx = 0;
5227 const char *prev_label = NULL;
e9edcee0 5228
66ceeb6b 5229 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5230 hda_nid_t pin;
10a20af7 5231 const char *label;
05f5f477 5232
66ceeb6b 5233 pin = cfg->inputs[i].pin;
05f5f477
TI
5234 if (!alc_is_input_pin(codec, pin))
5235 continue;
5236
5322bf27
DH
5237 label = hda_get_autocfg_input_label(codec, cfg, i);
5238 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5239 type_idx++;
5240 else
5241 type_idx = 0;
5322bf27
DH
5242 prev_label = label;
5243
05f5f477
TI
5244 if (mixer) {
5245 idx = get_connection_index(codec, mixer, pin);
5246 if (idx >= 0) {
5247 err = new_analog_input(spec, pin,
10a20af7
TI
5248 label, type_idx,
5249 idx, mixer);
05f5f477
TI
5250 if (err < 0)
5251 return err;
5252 }
5253 }
5254
5255 if (!cap1)
5256 continue;
5257 idx = get_connection_index(codec, cap1, pin);
5258 if (idx < 0 && cap2)
5259 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5260 if (idx >= 0)
5261 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5262 }
5263 return 0;
5264}
5265
05f5f477
TI
5266static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5267 const struct auto_pin_cfg *cfg)
5268{
5269 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5270}
5271
f6c7e546
TI
5272static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5273 unsigned int pin_type)
5274{
5275 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5276 pin_type);
5277 /* unmute pin */
d260cdf6
TI
5278 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5279 AMP_OUT_UNMUTE);
f6c7e546
TI
5280}
5281
df694daa
KY
5282static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5283 hda_nid_t nid, int pin_type,
e9edcee0
TI
5284 int dac_idx)
5285{
f6c7e546 5286 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5287 /* need the manual connection? */
5288 if (alc880_is_multi_pin(nid)) {
5289 struct alc_spec *spec = codec->spec;
5290 int idx = alc880_multi_pin_idx(nid);
5291 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5292 AC_VERB_SET_CONNECT_SEL,
5293 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5294 }
5295}
5296
baba8ee9
TI
5297static int get_pin_type(int line_out_type)
5298{
5299 if (line_out_type == AUTO_PIN_HP_OUT)
5300 return PIN_HP;
5301 else
5302 return PIN_OUT;
5303}
5304
e9edcee0
TI
5305static void alc880_auto_init_multi_out(struct hda_codec *codec)
5306{
5307 struct alc_spec *spec = codec->spec;
5308 int i;
ea1fb29a 5309
e9edcee0
TI
5310 for (i = 0; i < spec->autocfg.line_outs; i++) {
5311 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5312 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5313 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5314 }
5315}
5316
8d88bc3d 5317static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5318{
5319 struct alc_spec *spec = codec->spec;
5320 hda_nid_t pin;
5321
82bc955f 5322 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5323 if (pin) /* connect to front */
5324 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5325 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5326 if (pin) /* connect to front */
5327 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5328}
5329
5330static void alc880_auto_init_analog_input(struct hda_codec *codec)
5331{
5332 struct alc_spec *spec = codec->spec;
66ceeb6b 5333 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5334 int i;
5335
66ceeb6b
TI
5336 for (i = 0; i < cfg->num_inputs; i++) {
5337 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5338 if (alc_is_input_pin(codec, nid)) {
30ea098f 5339 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5340 if (nid != ALC880_PIN_CD_NID &&
5341 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5342 snd_hda_codec_write(codec, nid, 0,
5343 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5344 AMP_OUT_MUTE);
5345 }
5346 }
5347}
5348
7f311a46
TI
5349static void alc880_auto_init_input_src(struct hda_codec *codec)
5350{
5351 struct alc_spec *spec = codec->spec;
5352 int c;
5353
5354 for (c = 0; c < spec->num_adc_nids; c++) {
5355 unsigned int mux_idx;
5356 const struct hda_input_mux *imux;
5357 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5358 imux = &spec->input_mux[mux_idx];
5359 if (!imux->num_items && mux_idx > 0)
5360 imux = &spec->input_mux[0];
5361 if (imux)
5362 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5363 AC_VERB_SET_CONNECT_SEL,
5364 imux->items[0].index);
5365 }
5366}
5367
e9edcee0 5368/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5369/* return 1 if successful, 0 if the proper config is not found,
5370 * or a negative error code
5371 */
e9edcee0
TI
5372static int alc880_parse_auto_config(struct hda_codec *codec)
5373{
5374 struct alc_spec *spec = codec->spec;
757899ac 5375 int err;
df694daa 5376 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5377
f12ab1e0
TI
5378 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5379 alc880_ignore);
5380 if (err < 0)
e9edcee0 5381 return err;
f12ab1e0 5382 if (!spec->autocfg.line_outs)
e9edcee0 5383 return 0; /* can't find valid BIOS pin config */
df694daa 5384
f12ab1e0
TI
5385 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5386 if (err < 0)
5387 return err;
5388 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5389 if (err < 0)
5390 return err;
5391 err = alc880_auto_create_extra_out(spec,
5392 spec->autocfg.speaker_pins[0],
5393 "Speaker");
5394 if (err < 0)
5395 return err;
5396 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5397 "Headphone");
5398 if (err < 0)
5399 return err;
05f5f477 5400 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5401 if (err < 0)
e9edcee0
TI
5402 return err;
5403
5404 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5405
757899ac 5406 alc_auto_parse_digital(codec);
e9edcee0 5407
603c4019 5408 if (spec->kctls.list)
d88897ea 5409 add_mixer(spec, spec->kctls.list);
e9edcee0 5410
d88897ea 5411 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5412
a1e8d2da 5413 spec->num_mux_defs = 1;
61b9b9b1 5414 spec->input_mux = &spec->private_imux[0];
e9edcee0 5415
6227cdce 5416 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5417
e9edcee0
TI
5418 return 1;
5419}
5420
ae6b813a
TI
5421/* additional initialization for auto-configuration model */
5422static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5423{
f6c7e546 5424 struct alc_spec *spec = codec->spec;
e9edcee0 5425 alc880_auto_init_multi_out(codec);
8d88bc3d 5426 alc880_auto_init_extra_out(codec);
e9edcee0 5427 alc880_auto_init_analog_input(codec);
7f311a46 5428 alc880_auto_init_input_src(codec);
757899ac 5429 alc_auto_init_digital(codec);
f6c7e546 5430 if (spec->unsol_event)
7fb0d78f 5431 alc_inithook(codec);
e9edcee0
TI
5432}
5433
b59bdf3b
TI
5434/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5435 * one of two digital mic pins, e.g. on ALC272
5436 */
5437static void fixup_automic_adc(struct hda_codec *codec)
5438{
5439 struct alc_spec *spec = codec->spec;
5440 int i;
5441
5442 for (i = 0; i < spec->num_adc_nids; i++) {
5443 hda_nid_t cap = spec->capsrc_nids ?
5444 spec->capsrc_nids[i] : spec->adc_nids[i];
5445 int iidx, eidx;
5446
5447 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5448 if (iidx < 0)
5449 continue;
5450 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5451 if (eidx < 0)
5452 continue;
5453 spec->int_mic.mux_idx = iidx;
5454 spec->ext_mic.mux_idx = eidx;
5455 if (spec->capsrc_nids)
5456 spec->capsrc_nids += i;
5457 spec->adc_nids += i;
5458 spec->num_adc_nids = 1;
5459 return;
5460 }
5461 snd_printd(KERN_INFO "hda_codec: %s: "
5462 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5463 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5464 spec->auto_mic = 0; /* disable auto-mic to be sure */
5465}
5466
748cce43
TI
5467/* select or unmute the given capsrc route */
5468static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5469 int idx)
5470{
5471 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5472 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5473 HDA_AMP_MUTE, 0);
5474 } else {
5475 snd_hda_codec_write_cache(codec, cap, 0,
5476 AC_VERB_SET_CONNECT_SEL, idx);
5477 }
5478}
5479
840b64c0
TI
5480/* set the default connection to that pin */
5481static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5482{
5483 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5484 int i;
5485
eaa9b3a7
TI
5486 for (i = 0; i < spec->num_adc_nids; i++) {
5487 hda_nid_t cap = spec->capsrc_nids ?
5488 spec->capsrc_nids[i] : spec->adc_nids[i];
5489 int idx;
5490
5491 idx = get_connection_index(codec, cap, pin);
5492 if (idx < 0)
5493 continue;
748cce43 5494 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5495 return i; /* return the found index */
5496 }
5497 return -1; /* not found */
5498}
5499
5500/* choose the ADC/MUX containing the input pin and initialize the setup */
5501static void fixup_single_adc(struct hda_codec *codec)
5502{
5503 struct alc_spec *spec = codec->spec;
66ceeb6b 5504 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5505 int i;
5506
5507 /* search for the input pin; there must be only one */
66ceeb6b 5508 if (cfg->num_inputs != 1)
eaa9b3a7 5509 return;
66ceeb6b 5510 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5511 if (i >= 0) {
5512 /* use only this ADC */
5513 if (spec->capsrc_nids)
5514 spec->capsrc_nids += i;
5515 spec->adc_nids += i;
5516 spec->num_adc_nids = 1;
eaa9b3a7
TI
5517 }
5518}
5519
840b64c0
TI
5520/* initialize dual adcs */
5521static void fixup_dual_adc_switch(struct hda_codec *codec)
5522{
5523 struct alc_spec *spec = codec->spec;
5524 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5525 init_capsrc_for_pin(codec, spec->int_mic.pin);
5526}
5527
b59bdf3b 5528static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5529{
b59bdf3b 5530 struct alc_spec *spec = codec->spec;
a23b688f
TI
5531 static struct snd_kcontrol_new *caps[2][3] = {
5532 { alc_capture_mixer_nosrc1,
5533 alc_capture_mixer_nosrc2,
5534 alc_capture_mixer_nosrc3 },
5535 { alc_capture_mixer1,
5536 alc_capture_mixer2,
5537 alc_capture_mixer3 },
f9e336f6 5538 };
a23b688f 5539 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5540 int mux = 0;
840b64c0
TI
5541 int num_adcs = spec->num_adc_nids;
5542 if (spec->dual_adc_switch)
5543 fixup_dual_adc_switch(codec);
5544 else if (spec->auto_mic)
b59bdf3b 5545 fixup_automic_adc(codec);
eaa9b3a7
TI
5546 else if (spec->input_mux) {
5547 if (spec->input_mux->num_items > 1)
5548 mux = 1;
5549 else if (spec->input_mux->num_items == 1)
5550 fixup_single_adc(codec);
5551 }
840b64c0
TI
5552 if (spec->dual_adc_switch)
5553 num_adcs = 1;
5554 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5555 }
f9e336f6
TI
5556}
5557
6694635d
TI
5558/* fill adc_nids (and capsrc_nids) containing all active input pins */
5559static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5560 int num_nids)
5561{
5562 struct alc_spec *spec = codec->spec;
66ceeb6b 5563 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5564 int n;
5565 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5566
5567 for (n = 0; n < num_nids; n++) {
5568 hda_nid_t adc, cap;
5569 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5570 int nconns, i, j;
5571
5572 adc = nids[n];
5573 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5574 continue;
5575 cap = adc;
5576 nconns = snd_hda_get_connections(codec, cap, conn,
5577 ARRAY_SIZE(conn));
5578 if (nconns == 1) {
5579 cap = conn[0];
5580 nconns = snd_hda_get_connections(codec, cap, conn,
5581 ARRAY_SIZE(conn));
5582 }
5583 if (nconns <= 0)
5584 continue;
5585 if (!fallback_adc) {
5586 fallback_adc = adc;
5587 fallback_cap = cap;
5588 }
66ceeb6b
TI
5589 for (i = 0; i < cfg->num_inputs; i++) {
5590 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5591 for (j = 0; j < nconns; j++) {
5592 if (conn[j] == nid)
5593 break;
5594 }
5595 if (j >= nconns)
5596 break;
5597 }
66ceeb6b 5598 if (i >= cfg->num_inputs) {
6694635d
TI
5599 int num_adcs = spec->num_adc_nids;
5600 spec->private_adc_nids[num_adcs] = adc;
5601 spec->private_capsrc_nids[num_adcs] = cap;
5602 spec->num_adc_nids++;
5603 spec->adc_nids = spec->private_adc_nids;
5604 if (adc != cap)
5605 spec->capsrc_nids = spec->private_capsrc_nids;
5606 }
5607 }
5608 if (!spec->num_adc_nids) {
5609 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5610 " using fallback 0x%x\n",
5611 codec->chip_name, fallback_adc);
6694635d
TI
5612 spec->private_adc_nids[0] = fallback_adc;
5613 spec->adc_nids = spec->private_adc_nids;
5614 if (fallback_adc != fallback_cap) {
5615 spec->private_capsrc_nids[0] = fallback_cap;
5616 spec->capsrc_nids = spec->private_adc_nids;
5617 }
5618 }
5619}
5620
67d634c0 5621#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5622#define set_beep_amp(spec, nid, idx, dir) \
5623 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5624
5625static struct snd_pci_quirk beep_white_list[] = {
5626 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5627 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5628 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5629 {}
5630};
5631
5632static inline int has_cdefine_beep(struct hda_codec *codec)
5633{
5634 struct alc_spec *spec = codec->spec;
5635 const struct snd_pci_quirk *q;
5636 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5637 if (q)
5638 return q->value;
5639 return spec->cdefine.enable_pcbeep;
5640}
67d634c0
TI
5641#else
5642#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5643#define has_cdefine_beep(codec) 0
67d634c0 5644#endif
45bdd1c1
TI
5645
5646/*
5647 * OK, here we have finally the patch for ALC880
5648 */
5649
1da177e4
LT
5650static int patch_alc880(struct hda_codec *codec)
5651{
5652 struct alc_spec *spec;
5653 int board_config;
df694daa 5654 int err;
1da177e4 5655
e560d8d8 5656 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5657 if (spec == NULL)
5658 return -ENOMEM;
5659
5660 codec->spec = spec;
5661
f5fcc13c
TI
5662 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5663 alc880_models,
5664 alc880_cfg_tbl);
5665 if (board_config < 0) {
9a11f1aa
TI
5666 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5667 codec->chip_name);
e9edcee0 5668 board_config = ALC880_AUTO;
1da177e4 5669 }
1da177e4 5670
e9edcee0
TI
5671 if (board_config == ALC880_AUTO) {
5672 /* automatic parse from the BIOS config */
5673 err = alc880_parse_auto_config(codec);
5674 if (err < 0) {
5675 alc_free(codec);
5676 return err;
f12ab1e0 5677 } else if (!err) {
9c7f852e
TI
5678 printk(KERN_INFO
5679 "hda_codec: Cannot set up configuration "
5680 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5681 board_config = ALC880_3ST;
5682 }
1da177e4
LT
5683 }
5684
680cd536
KK
5685 err = snd_hda_attach_beep_device(codec, 0x1);
5686 if (err < 0) {
5687 alc_free(codec);
5688 return err;
5689 }
5690
df694daa 5691 if (board_config != ALC880_AUTO)
e9c364c0 5692 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5693
1da177e4
LT
5694 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5695 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5696 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5697
1da177e4
LT
5698 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5699 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5700
f12ab1e0 5701 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5702 /* check whether NID 0x07 is valid */
54d17403 5703 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5704 /* get type */
a22d543a 5705 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5706 if (wcap != AC_WID_AUD_IN) {
5707 spec->adc_nids = alc880_adc_nids_alt;
5708 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5709 } else {
5710 spec->adc_nids = alc880_adc_nids;
5711 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5712 }
5713 }
b59bdf3b 5714 set_capture_mixer(codec);
45bdd1c1 5715 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5716
2134ea4f
TI
5717 spec->vmaster_nid = 0x0c;
5718
1da177e4 5719 codec->patch_ops = alc_patch_ops;
e9edcee0 5720 if (board_config == ALC880_AUTO)
ae6b813a 5721 spec->init_hook = alc880_auto_init;
cb53c626
TI
5722#ifdef CONFIG_SND_HDA_POWER_SAVE
5723 if (!spec->loopback.amplist)
5724 spec->loopback.amplist = alc880_loopbacks;
5725#endif
1da177e4
LT
5726
5727 return 0;
5728}
5729
e9edcee0 5730
1da177e4
LT
5731/*
5732 * ALC260 support
5733 */
5734
e9edcee0
TI
5735static hda_nid_t alc260_dac_nids[1] = {
5736 /* front */
5737 0x02,
5738};
5739
5740static hda_nid_t alc260_adc_nids[1] = {
5741 /* ADC0 */
5742 0x04,
5743};
5744
df694daa 5745static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5746 /* ADC1 */
5747 0x05,
5748};
5749
d57fdac0
JW
5750/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5751 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5752 */
5753static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5754 /* ADC0, ADC1 */
5755 0x04, 0x05
5756};
5757
e9edcee0
TI
5758#define ALC260_DIGOUT_NID 0x03
5759#define ALC260_DIGIN_NID 0x06
5760
5761static struct hda_input_mux alc260_capture_source = {
5762 .num_items = 4,
5763 .items = {
5764 { "Mic", 0x0 },
5765 { "Front Mic", 0x1 },
5766 { "Line", 0x2 },
5767 { "CD", 0x4 },
5768 },
5769};
5770
17e7aec6 5771/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5772 * headphone jack and the internal CD lines since these are the only pins at
5773 * which audio can appear. For flexibility, also allow the option of
5774 * recording the mixer output on the second ADC (ADC0 doesn't have a
5775 * connection to the mixer output).
a9430dd8 5776 */
a1e8d2da
JW
5777static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5778 {
5779 .num_items = 3,
5780 .items = {
5781 { "Mic/Line", 0x0 },
5782 { "CD", 0x4 },
5783 { "Headphone", 0x2 },
5784 },
a9430dd8 5785 },
a1e8d2da
JW
5786 {
5787 .num_items = 4,
5788 .items = {
5789 { "Mic/Line", 0x0 },
5790 { "CD", 0x4 },
5791 { "Headphone", 0x2 },
5792 { "Mixer", 0x5 },
5793 },
5794 },
5795
a9430dd8
JW
5796};
5797
a1e8d2da
JW
5798/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5799 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5800 */
a1e8d2da
JW
5801static struct hda_input_mux alc260_acer_capture_sources[2] = {
5802 {
5803 .num_items = 4,
5804 .items = {
5805 { "Mic", 0x0 },
5806 { "Line", 0x2 },
5807 { "CD", 0x4 },
5808 { "Headphone", 0x5 },
5809 },
5810 },
5811 {
5812 .num_items = 5,
5813 .items = {
5814 { "Mic", 0x0 },
5815 { "Line", 0x2 },
5816 { "CD", 0x4 },
5817 { "Headphone", 0x6 },
5818 { "Mixer", 0x5 },
5819 },
0bfc90e9
JW
5820 },
5821};
cc959489
MS
5822
5823/* Maxdata Favorit 100XS */
5824static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5825 {
5826 .num_items = 2,
5827 .items = {
5828 { "Line/Mic", 0x0 },
5829 { "CD", 0x4 },
5830 },
5831 },
5832 {
5833 .num_items = 3,
5834 .items = {
5835 { "Line/Mic", 0x0 },
5836 { "CD", 0x4 },
5837 { "Mixer", 0x5 },
5838 },
5839 },
5840};
5841
1da177e4
LT
5842/*
5843 * This is just place-holder, so there's something for alc_build_pcms to look
5844 * at when it calculates the maximum number of channels. ALC260 has no mixer
5845 * element which allows changing the channel mode, so the verb list is
5846 * never used.
5847 */
d2a6d7dc 5848static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5849 { 2, NULL },
5850};
5851
df694daa
KY
5852
5853/* Mixer combinations
5854 *
5855 * basic: base_output + input + pc_beep + capture
5856 * HP: base_output + input + capture_alt
5857 * HP_3013: hp_3013 + input + capture
5858 * fujitsu: fujitsu + capture
0bfc90e9 5859 * acer: acer + capture
df694daa
KY
5860 */
5861
5862static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5863 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5864 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5865 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5866 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5867 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5868 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5869 { } /* end */
f12ab1e0 5870};
1da177e4 5871
df694daa 5872static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5873 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5874 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5875 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5876 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5877 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5878 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5879 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5880 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5881 { } /* end */
5882};
5883
bec15c3a
TI
5884/* update HP, line and mono out pins according to the master switch */
5885static void alc260_hp_master_update(struct hda_codec *codec,
5886 hda_nid_t hp, hda_nid_t line,
5887 hda_nid_t mono)
5888{
5889 struct alc_spec *spec = codec->spec;
5890 unsigned int val = spec->master_sw ? PIN_HP : 0;
5891 /* change HP and line-out pins */
30cde0aa 5892 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5893 val);
30cde0aa 5894 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5895 val);
5896 /* mono (speaker) depending on the HP jack sense */
5897 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5898 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5899 val);
5900}
5901
5902static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5903 struct snd_ctl_elem_value *ucontrol)
5904{
5905 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5906 struct alc_spec *spec = codec->spec;
5907 *ucontrol->value.integer.value = spec->master_sw;
5908 return 0;
5909}
5910
5911static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5912 struct snd_ctl_elem_value *ucontrol)
5913{
5914 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5915 struct alc_spec *spec = codec->spec;
5916 int val = !!*ucontrol->value.integer.value;
5917 hda_nid_t hp, line, mono;
5918
5919 if (val == spec->master_sw)
5920 return 0;
5921 spec->master_sw = val;
5922 hp = (kcontrol->private_value >> 16) & 0xff;
5923 line = (kcontrol->private_value >> 8) & 0xff;
5924 mono = kcontrol->private_value & 0xff;
5925 alc260_hp_master_update(codec, hp, line, mono);
5926 return 1;
5927}
5928
5929static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5930 {
5931 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5932 .name = "Master Playback Switch",
5b0cb1d8 5933 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5934 .info = snd_ctl_boolean_mono_info,
5935 .get = alc260_hp_master_sw_get,
5936 .put = alc260_hp_master_sw_put,
5937 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5938 },
5939 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5940 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5941 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5942 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5943 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5944 HDA_OUTPUT),
5945 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5946 { } /* end */
5947};
5948
5949static struct hda_verb alc260_hp_unsol_verbs[] = {
5950 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5951 {},
5952};
5953
5954static void alc260_hp_automute(struct hda_codec *codec)
5955{
5956 struct alc_spec *spec = codec->spec;
bec15c3a 5957
864f92be 5958 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5959 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5960}
5961
5962static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5963{
5964 if ((res >> 26) == ALC880_HP_EVENT)
5965 alc260_hp_automute(codec);
5966}
5967
df694daa 5968static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5969 {
5970 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5971 .name = "Master Playback Switch",
5b0cb1d8 5972 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5973 .info = snd_ctl_boolean_mono_info,
5974 .get = alc260_hp_master_sw_get,
5975 .put = alc260_hp_master_sw_put,
30cde0aa 5976 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5977 },
df694daa
KY
5978 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5979 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5980 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5981 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5982 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5983 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5984 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5985 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5986 { } /* end */
5987};
5988
3f878308
KY
5989static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5990 .ops = &snd_hda_bind_vol,
5991 .values = {
5992 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5993 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5994 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5995 0
5996 },
5997};
5998
5999static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6000 .ops = &snd_hda_bind_sw,
6001 .values = {
6002 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6003 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6004 0
6005 },
6006};
6007
6008static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6009 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6010 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6011 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6012 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6013 { } /* end */
6014};
6015
bec15c3a
TI
6016static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6017 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6018 {},
6019};
6020
6021static void alc260_hp_3013_automute(struct hda_codec *codec)
6022{
6023 struct alc_spec *spec = codec->spec;
bec15c3a 6024
864f92be 6025 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 6026 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
6027}
6028
6029static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6030 unsigned int res)
6031{
6032 if ((res >> 26) == ALC880_HP_EVENT)
6033 alc260_hp_3013_automute(codec);
6034}
6035
3f878308
KY
6036static void alc260_hp_3012_automute(struct hda_codec *codec)
6037{
864f92be 6038 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 6039
3f878308
KY
6040 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6041 bits);
6042 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6043 bits);
6044 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6045 bits);
6046}
6047
6048static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6049 unsigned int res)
6050{
6051 if ((res >> 26) == ALC880_HP_EVENT)
6052 alc260_hp_3012_automute(codec);
6053}
6054
6055/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6056 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6057 */
c8b6bf9b 6058static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6059 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6060 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6061 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6062 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6063 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6064 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6065 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6066 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6067 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6068 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6069 { } /* end */
6070};
6071
a1e8d2da
JW
6072/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6073 * versions of the ALC260 don't act on requests to enable mic bias from NID
6074 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6075 * datasheet doesn't mention this restriction. At this stage it's not clear
6076 * whether this behaviour is intentional or is a hardware bug in chip
6077 * revisions available in early 2006. Therefore for now allow the
6078 * "Headphone Jack Mode" control to span all choices, but if it turns out
6079 * that the lack of mic bias for this NID is intentional we could change the
6080 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6081 *
6082 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6083 * don't appear to make the mic bias available from the "line" jack, even
6084 * though the NID used for this jack (0x14) can supply it. The theory is
6085 * that perhaps Acer have included blocking capacitors between the ALC260
6086 * and the output jack. If this turns out to be the case for all such
6087 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6088 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6089 *
6090 * The C20x Tablet series have a mono internal speaker which is controlled
6091 * via the chip's Mono sum widget and pin complex, so include the necessary
6092 * controls for such models. On models without a "mono speaker" the control
6093 * won't do anything.
a1e8d2da 6094 */
0bfc90e9
JW
6095static struct snd_kcontrol_new alc260_acer_mixer[] = {
6096 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6097 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6098 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6099 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6100 HDA_OUTPUT),
31bffaa9 6101 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6102 HDA_INPUT),
0bfc90e9
JW
6103 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6104 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6106 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6107 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6108 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6109 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6110 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6111 { } /* end */
6112};
6113
cc959489
MS
6114/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6115 */
6116static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6117 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6118 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6119 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6120 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6121 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6122 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6123 { } /* end */
6124};
6125
bc9f98a9
KY
6126/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6127 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6128 */
6129static struct snd_kcontrol_new alc260_will_mixer[] = {
6130 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6131 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6132 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6133 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6134 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6135 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6136 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6137 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6138 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6139 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6140 { } /* end */
6141};
6142
6143/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6144 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6145 */
6146static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6147 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6148 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6150 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6151 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6152 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6153 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6154 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6155 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6156 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6157 { } /* end */
6158};
6159
df694daa
KY
6160/*
6161 * initialization verbs
6162 */
1da177e4
LT
6163static struct hda_verb alc260_init_verbs[] = {
6164 /* Line In pin widget for input */
05acb863 6165 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6166 /* CD pin widget for input */
05acb863 6167 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6168 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6169 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6170 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6171 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6172 /* LINE-2 is used for line-out in rear */
05acb863 6173 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6174 /* select line-out */
fd56f2db 6175 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6176 /* LINE-OUT pin */
05acb863 6177 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6178 /* enable HP */
05acb863 6179 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6180 /* enable Mono */
05acb863
TI
6181 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6182 /* mute capture amp left and right */
16ded525 6183 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6184 /* set connection select to line in (default select for this ADC) */
6185 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6186 /* mute capture amp left and right */
6187 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6188 /* set connection select to line in (default select for this ADC) */
6189 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6190 /* set vol=0 Line-Out mixer amp left and right */
6191 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6192 /* unmute pin widget amp left and right (no gain on this amp) */
6193 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6194 /* set vol=0 HP mixer amp left and right */
6195 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6196 /* unmute pin widget amp left and right (no gain on this amp) */
6197 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6198 /* set vol=0 Mono mixer amp left and right */
6199 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6200 /* unmute pin widget amp left and right (no gain on this amp) */
6201 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6202 /* unmute LINE-2 out pin */
6203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6204 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6205 * Line In 2 = 0x03
6206 */
cb53c626
TI
6207 /* mute analog inputs */
6208 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6209 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6210 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6211 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6212 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6213 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6214 /* mute Front out path */
6215 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6216 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6217 /* mute Headphone out path */
6218 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6219 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6220 /* mute Mono out path */
6221 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6222 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6223 { }
6224};
6225
474167d6 6226#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6227static struct hda_verb alc260_hp_init_verbs[] = {
6228 /* Headphone and output */
6229 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6230 /* mono output */
6231 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6232 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6233 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6234 /* Mic2 (front panel) pin widget for input and vref at 80% */
6235 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6236 /* Line In pin widget for input */
6237 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6238 /* Line-2 pin widget for output */
6239 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6240 /* CD pin widget for input */
6241 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6242 /* unmute amp left and right */
6243 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6244 /* set connection select to line in (default select for this ADC) */
6245 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6246 /* unmute Line-Out mixer amp left and right (volume = 0) */
6247 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6248 /* mute pin widget amp left and right (no gain on this amp) */
6249 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6250 /* unmute HP mixer amp left and right (volume = 0) */
6251 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6252 /* mute pin widget amp left and right (no gain on this amp) */
6253 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6254 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6255 * Line In 2 = 0x03
6256 */
cb53c626
TI
6257 /* mute analog inputs */
6258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6259 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6260 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6261 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6262 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6263 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6264 /* Unmute Front out path */
6265 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6266 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6267 /* Unmute Headphone out path */
6268 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6269 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6270 /* Unmute Mono out path */
6271 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6272 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6273 { }
6274};
474167d6 6275#endif
df694daa
KY
6276
6277static struct hda_verb alc260_hp_3013_init_verbs[] = {
6278 /* Line out and output */
6279 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6280 /* mono output */
6281 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6282 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6283 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6284 /* Mic2 (front panel) pin widget for input and vref at 80% */
6285 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6286 /* Line In pin widget for input */
6287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6288 /* Headphone pin widget for output */
6289 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6290 /* CD pin widget for input */
6291 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6292 /* unmute amp left and right */
6293 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6294 /* set connection select to line in (default select for this ADC) */
6295 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6296 /* unmute Line-Out mixer amp left and right (volume = 0) */
6297 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6298 /* mute pin widget amp left and right (no gain on this amp) */
6299 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6300 /* unmute HP mixer amp left and right (volume = 0) */
6301 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6302 /* mute pin widget amp left and right (no gain on this amp) */
6303 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6304 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6305 * Line In 2 = 0x03
6306 */
cb53c626
TI
6307 /* mute analog inputs */
6308 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6309 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6310 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6311 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6312 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6313 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6314 /* Unmute Front out path */
6315 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6316 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6317 /* Unmute Headphone out path */
6318 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6319 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6320 /* Unmute Mono out path */
6321 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6322 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6323 { }
6324};
6325
a9430dd8 6326/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6327 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6328 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6329 */
6330static struct hda_verb alc260_fujitsu_init_verbs[] = {
6331 /* Disable all GPIOs */
6332 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6333 /* Internal speaker is connected to headphone pin */
6334 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6335 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6336 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6337 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6338 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6339 /* Ensure all other unused pins are disabled and muted. */
6340 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6341 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6342 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6343 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6344 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6345 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6346 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6347 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6348
6349 /* Disable digital (SPDIF) pins */
6350 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6351 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6352
ea1fb29a 6353 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6354 * when acting as an output.
6355 */
6356 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6357
f7ace40d 6358 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6359 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6360 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6361 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6362 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6363 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6364 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6365 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6366 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6367 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6368
f7ace40d
JW
6369 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6370 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6371 /* Unmute Line1 pin widget output buffer since it starts as an output.
6372 * If the pin mode is changed by the user the pin mode control will
6373 * take care of enabling the pin's input/output buffers as needed.
6374 * Therefore there's no need to enable the input buffer at this
6375 * stage.
cdcd9268 6376 */
f7ace40d 6377 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6378 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6379 * mixer ctrl)
6380 */
f7ace40d
JW
6381 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6382
6383 /* Mute capture amp left and right */
6384 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6385 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6386 * in (on mic1 pin)
6387 */
6388 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6389
6390 /* Do the same for the second ADC: mute capture input amp and
6391 * set ADC connection to line in (on mic1 pin)
6392 */
6393 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6394 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6395
6396 /* Mute all inputs to mixer widget (even unconnected ones) */
6397 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6398 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6400 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6401 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6402 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6403 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6404 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6405
6406 { }
a9430dd8
JW
6407};
6408
0bfc90e9
JW
6409/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6410 * similar laptops (adapted from Fujitsu init verbs).
6411 */
6412static struct hda_verb alc260_acer_init_verbs[] = {
6413 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6414 * the headphone jack. Turn this on and rely on the standard mute
6415 * methods whenever the user wants to turn these outputs off.
6416 */
6417 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6418 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6419 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6420 /* Internal speaker/Headphone jack is connected to Line-out pin */
6421 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6422 /* Internal microphone/Mic jack is connected to Mic1 pin */
6423 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6424 /* Line In jack is connected to Line1 pin */
6425 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6426 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6427 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6428 /* Ensure all other unused pins are disabled and muted. */
6429 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6430 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6431 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6432 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6433 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6434 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6435 /* Disable digital (SPDIF) pins */
6436 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6437 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6438
ea1fb29a 6439 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6440 * bus when acting as outputs.
6441 */
6442 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6443 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6444
6445 /* Start with output sum widgets muted and their output gains at min */
6446 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6447 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6448 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6449 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6450 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6451 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6452 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6453 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6454 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6455
f12ab1e0
TI
6456 /* Unmute Line-out pin widget amp left and right
6457 * (no equiv mixer ctrl)
6458 */
0bfc90e9 6459 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6460 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6461 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6462 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6463 * inputs. If the pin mode is changed by the user the pin mode control
6464 * will take care of enabling the pin's input/output buffers as needed.
6465 * Therefore there's no need to enable the input buffer at this
6466 * stage.
6467 */
6468 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6469 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6470
6471 /* Mute capture amp left and right */
6472 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6473 /* Set ADC connection select to match default mixer setting - mic
6474 * (on mic1 pin)
6475 */
6476 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6477
6478 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6479 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6480 */
6481 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6482 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6483
6484 /* Mute all inputs to mixer widget (even unconnected ones) */
6485 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6487 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6489 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6491 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6492 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6493
6494 { }
6495};
6496
cc959489
MS
6497/* Initialisation sequence for Maxdata Favorit 100XS
6498 * (adapted from Acer init verbs).
6499 */
6500static struct hda_verb alc260_favorit100_init_verbs[] = {
6501 /* GPIO 0 enables the output jack.
6502 * Turn this on and rely on the standard mute
6503 * methods whenever the user wants to turn these outputs off.
6504 */
6505 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6506 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6507 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6508 /* Line/Mic input jack is connected to Mic1 pin */
6509 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6510 /* Ensure all other unused pins are disabled and muted. */
6511 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6512 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6513 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6514 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6515 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6516 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6517 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6518 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6519 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6520 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6521 /* Disable digital (SPDIF) pins */
6522 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6523 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6524
6525 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6526 * bus when acting as outputs.
6527 */
6528 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6529 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6530
6531 /* Start with output sum widgets muted and their output gains at min */
6532 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6533 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6534 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6536 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6537 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6538 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6539 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6540 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6541
6542 /* Unmute Line-out pin widget amp left and right
6543 * (no equiv mixer ctrl)
6544 */
6545 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6546 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6547 * inputs. If the pin mode is changed by the user the pin mode control
6548 * will take care of enabling the pin's input/output buffers as needed.
6549 * Therefore there's no need to enable the input buffer at this
6550 * stage.
6551 */
6552 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6553
6554 /* Mute capture amp left and right */
6555 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6556 /* Set ADC connection select to match default mixer setting - mic
6557 * (on mic1 pin)
6558 */
6559 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6560
6561 /* Do similar with the second ADC: mute capture input amp and
6562 * set ADC connection to mic to match ALSA's default state.
6563 */
6564 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6565 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6566
6567 /* Mute all inputs to mixer widget (even unconnected ones) */
6568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6570 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6571 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6576
6577 { }
6578};
6579
bc9f98a9
KY
6580static struct hda_verb alc260_will_verbs[] = {
6581 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6582 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6583 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6584 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6585 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6586 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6587 {}
6588};
6589
6590static struct hda_verb alc260_replacer_672v_verbs[] = {
6591 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6592 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6593 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6594
6595 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6596 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6597 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6598
6599 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6600 {}
6601};
6602
6603/* toggle speaker-output according to the hp-jack state */
6604static void alc260_replacer_672v_automute(struct hda_codec *codec)
6605{
6606 unsigned int present;
6607
6608 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6609 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6610 if (present) {
82beb8fd
TI
6611 snd_hda_codec_write_cache(codec, 0x01, 0,
6612 AC_VERB_SET_GPIO_DATA, 1);
6613 snd_hda_codec_write_cache(codec, 0x0f, 0,
6614 AC_VERB_SET_PIN_WIDGET_CONTROL,
6615 PIN_HP);
bc9f98a9 6616 } else {
82beb8fd
TI
6617 snd_hda_codec_write_cache(codec, 0x01, 0,
6618 AC_VERB_SET_GPIO_DATA, 0);
6619 snd_hda_codec_write_cache(codec, 0x0f, 0,
6620 AC_VERB_SET_PIN_WIDGET_CONTROL,
6621 PIN_OUT);
bc9f98a9
KY
6622 }
6623}
6624
6625static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6626 unsigned int res)
6627{
6628 if ((res >> 26) == ALC880_HP_EVENT)
6629 alc260_replacer_672v_automute(codec);
6630}
6631
3f878308
KY
6632static struct hda_verb alc260_hp_dc7600_verbs[] = {
6633 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6635 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6636 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6637 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6638 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6639 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6640 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6641 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6642 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6643 {}
6644};
6645
7cf51e48
JW
6646/* Test configuration for debugging, modelled after the ALC880 test
6647 * configuration.
6648 */
6649#ifdef CONFIG_SND_DEBUG
6650static hda_nid_t alc260_test_dac_nids[1] = {
6651 0x02,
6652};
6653static hda_nid_t alc260_test_adc_nids[2] = {
6654 0x04, 0x05,
6655};
a1e8d2da 6656/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6657 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6658 * is NID 0x04.
17e7aec6 6659 */
a1e8d2da
JW
6660static struct hda_input_mux alc260_test_capture_sources[2] = {
6661 {
6662 .num_items = 7,
6663 .items = {
6664 { "MIC1 pin", 0x0 },
6665 { "MIC2 pin", 0x1 },
6666 { "LINE1 pin", 0x2 },
6667 { "LINE2 pin", 0x3 },
6668 { "CD pin", 0x4 },
6669 { "LINE-OUT pin", 0x5 },
6670 { "HP-OUT pin", 0x6 },
6671 },
6672 },
6673 {
6674 .num_items = 8,
6675 .items = {
6676 { "MIC1 pin", 0x0 },
6677 { "MIC2 pin", 0x1 },
6678 { "LINE1 pin", 0x2 },
6679 { "LINE2 pin", 0x3 },
6680 { "CD pin", 0x4 },
6681 { "Mixer", 0x5 },
6682 { "LINE-OUT pin", 0x6 },
6683 { "HP-OUT pin", 0x7 },
6684 },
7cf51e48
JW
6685 },
6686};
6687static struct snd_kcontrol_new alc260_test_mixer[] = {
6688 /* Output driver widgets */
6689 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6690 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6691 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6692 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6693 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6694 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6695
a1e8d2da
JW
6696 /* Modes for retasking pin widgets
6697 * Note: the ALC260 doesn't seem to act on requests to enable mic
6698 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6699 * mention this restriction. At this stage it's not clear whether
6700 * this behaviour is intentional or is a hardware bug in chip
6701 * revisions available at least up until early 2006. Therefore for
6702 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6703 * choices, but if it turns out that the lack of mic bias for these
6704 * NIDs is intentional we could change their modes from
6705 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6706 */
7cf51e48
JW
6707 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6708 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6709 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6710 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6711 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6712 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6713
6714 /* Loopback mixer controls */
6715 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6716 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6717 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6718 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6719 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6720 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6721 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6722 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6723 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6724 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6725 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6726 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6727 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6728 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6729
6730 /* Controls for GPIO pins, assuming they are configured as outputs */
6731 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6732 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6733 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6734 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6735
92621f13
JW
6736 /* Switches to allow the digital IO pins to be enabled. The datasheet
6737 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6738 * make this output available should provide clarification.
92621f13
JW
6739 */
6740 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6741 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6742
f8225f6d
JW
6743 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6744 * this output to turn on an external amplifier.
6745 */
6746 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6747 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6748
7cf51e48
JW
6749 { } /* end */
6750};
6751static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6752 /* Enable all GPIOs as outputs with an initial value of 0 */
6753 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6754 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6755 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6756
7cf51e48
JW
6757 /* Enable retasking pins as output, initially without power amp */
6758 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6759 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6760 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6761 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6762 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6763 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6764
92621f13
JW
6765 /* Disable digital (SPDIF) pins initially, but users can enable
6766 * them via a mixer switch. In the case of SPDIF-out, this initverb
6767 * payload also sets the generation to 0, output to be in "consumer"
6768 * PCM format, copyright asserted, no pre-emphasis and no validity
6769 * control.
6770 */
7cf51e48
JW
6771 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6772 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6773
ea1fb29a 6774 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6775 * OUT1 sum bus when acting as an output.
6776 */
6777 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6778 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6779 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6780 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6781
6782 /* Start with output sum widgets muted and their output gains at min */
6783 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6784 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6785 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6786 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6787 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6789 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6790 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6791 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6792
cdcd9268
JW
6793 /* Unmute retasking pin widget output buffers since the default
6794 * state appears to be output. As the pin mode is changed by the
6795 * user the pin mode control will take care of enabling the pin's
6796 * input/output buffers as needed.
6797 */
7cf51e48
JW
6798 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6799 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6800 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6801 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6802 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6803 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6804 /* Also unmute the mono-out pin widget */
6805 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6806
7cf51e48
JW
6807 /* Mute capture amp left and right */
6808 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6809 /* Set ADC connection select to match default mixer setting (mic1
6810 * pin)
7cf51e48
JW
6811 */
6812 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6813
6814 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6815 * set ADC connection to mic1 pin
7cf51e48
JW
6816 */
6817 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6818 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6819
6820 /* Mute all inputs to mixer widget (even unconnected ones) */
6821 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6822 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6823 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6824 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6829
6830 { }
6831};
6832#endif
6833
6330079f
TI
6834#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6835#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6836
a3bcba38
TI
6837#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6838#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6839
df694daa
KY
6840/*
6841 * for BIOS auto-configuration
6842 */
16ded525 6843
df694daa 6844static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6845 const char *pfx, int *vol_bits)
df694daa
KY
6846{
6847 hda_nid_t nid_vol;
6848 unsigned long vol_val, sw_val;
df694daa
KY
6849 int err;
6850
6851 if (nid >= 0x0f && nid < 0x11) {
6852 nid_vol = nid - 0x7;
6853 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6854 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6855 } else if (nid == 0x11) {
6856 nid_vol = nid - 0x7;
6857 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6858 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6859 } else if (nid >= 0x12 && nid <= 0x15) {
6860 nid_vol = 0x08;
6861 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6862 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6863 } else
6864 return 0; /* N/A */
ea1fb29a 6865
863b4518
TI
6866 if (!(*vol_bits & (1 << nid_vol))) {
6867 /* first control for the volume widget */
0afe5f89 6868 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6869 if (err < 0)
6870 return err;
6871 *vol_bits |= (1 << nid_vol);
6872 }
0afe5f89 6873 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6874 if (err < 0)
df694daa
KY
6875 return err;
6876 return 1;
6877}
6878
6879/* add playback controls from the parsed DAC table */
6880static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6881 const struct auto_pin_cfg *cfg)
6882{
6883 hda_nid_t nid;
6884 int err;
863b4518 6885 int vols = 0;
df694daa
KY
6886
6887 spec->multiout.num_dacs = 1;
6888 spec->multiout.dac_nids = spec->private_dac_nids;
6889 spec->multiout.dac_nids[0] = 0x02;
6890
6891 nid = cfg->line_out_pins[0];
6892 if (nid) {
23112d6d
TI
6893 const char *pfx;
6894 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6895 pfx = "Master";
6896 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6897 pfx = "Speaker";
6898 else
6899 pfx = "Front";
6900 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6901 if (err < 0)
6902 return err;
6903 }
6904
82bc955f 6905 nid = cfg->speaker_pins[0];
df694daa 6906 if (nid) {
863b4518 6907 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6908 if (err < 0)
6909 return err;
6910 }
6911
eb06ed8f 6912 nid = cfg->hp_pins[0];
df694daa 6913 if (nid) {
863b4518
TI
6914 err = alc260_add_playback_controls(spec, nid, "Headphone",
6915 &vols);
df694daa
KY
6916 if (err < 0)
6917 return err;
6918 }
f12ab1e0 6919 return 0;
df694daa
KY
6920}
6921
6922/* create playback/capture controls for input pins */
05f5f477 6923static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6924 const struct auto_pin_cfg *cfg)
6925{
05f5f477 6926 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6927}
6928
6929static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6930 hda_nid_t nid, int pin_type,
6931 int sel_idx)
6932{
f6c7e546 6933 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6934 /* need the manual connection? */
6935 if (nid >= 0x12) {
6936 int idx = nid - 0x12;
6937 snd_hda_codec_write(codec, idx + 0x0b, 0,
6938 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6939 }
6940}
6941
6942static void alc260_auto_init_multi_out(struct hda_codec *codec)
6943{
6944 struct alc_spec *spec = codec->spec;
6945 hda_nid_t nid;
6946
f12ab1e0 6947 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6948 if (nid) {
6949 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6950 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6951 }
ea1fb29a 6952
82bc955f 6953 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6954 if (nid)
6955 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6956
eb06ed8f 6957 nid = spec->autocfg.hp_pins[0];
df694daa 6958 if (nid)
baba8ee9 6959 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6960}
df694daa
KY
6961
6962#define ALC260_PIN_CD_NID 0x16
6963static void alc260_auto_init_analog_input(struct hda_codec *codec)
6964{
6965 struct alc_spec *spec = codec->spec;
66ceeb6b 6966 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6967 int i;
6968
66ceeb6b
TI
6969 for (i = 0; i < cfg->num_inputs; i++) {
6970 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6971 if (nid >= 0x12) {
30ea098f 6972 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6973 if (nid != ALC260_PIN_CD_NID &&
6974 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6975 snd_hda_codec_write(codec, nid, 0,
6976 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6977 AMP_OUT_MUTE);
6978 }
6979 }
6980}
6981
7f311a46
TI
6982#define alc260_auto_init_input_src alc880_auto_init_input_src
6983
df694daa
KY
6984/*
6985 * generic initialization of ADC, input mixers and output mixers
6986 */
6987static struct hda_verb alc260_volume_init_verbs[] = {
6988 /*
6989 * Unmute ADC0-1 and set the default input to mic-in
6990 */
6991 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6992 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6993 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6994 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6995
df694daa
KY
6996 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6997 * mixer widget
f12ab1e0
TI
6998 * Note: PASD motherboards uses the Line In 2 as the input for
6999 * front panel mic (mic 2)
df694daa
KY
7000 */
7001 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7002 /* mute analog inputs */
7003 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7004 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7006 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7007 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7008
7009 /*
7010 * Set up output mixers (0x08 - 0x0a)
7011 */
7012 /* set vol=0 to output mixers */
7013 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7014 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7015 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7016 /* set up input amps for analog loopback */
7017 /* Amp Indices: DAC = 0, mixer = 1 */
7018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7021 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7022 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7024
df694daa
KY
7025 { }
7026};
7027
7028static int alc260_parse_auto_config(struct hda_codec *codec)
7029{
7030 struct alc_spec *spec = codec->spec;
df694daa
KY
7031 int err;
7032 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7033
f12ab1e0
TI
7034 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7035 alc260_ignore);
7036 if (err < 0)
df694daa 7037 return err;
f12ab1e0
TI
7038 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7039 if (err < 0)
4a471b7d 7040 return err;
603c4019 7041 if (!spec->kctls.list)
df694daa 7042 return 0; /* can't find valid BIOS pin config */
05f5f477 7043 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7044 if (err < 0)
df694daa
KY
7045 return err;
7046
7047 spec->multiout.max_channels = 2;
7048
0852d7a6 7049 if (spec->autocfg.dig_outs)
df694daa 7050 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7051 if (spec->kctls.list)
d88897ea 7052 add_mixer(spec, spec->kctls.list);
df694daa 7053
d88897ea 7054 add_verb(spec, alc260_volume_init_verbs);
df694daa 7055
a1e8d2da 7056 spec->num_mux_defs = 1;
61b9b9b1 7057 spec->input_mux = &spec->private_imux[0];
df694daa 7058
6227cdce 7059 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7060
df694daa
KY
7061 return 1;
7062}
7063
ae6b813a
TI
7064/* additional initialization for auto-configuration model */
7065static void alc260_auto_init(struct hda_codec *codec)
df694daa 7066{
f6c7e546 7067 struct alc_spec *spec = codec->spec;
df694daa
KY
7068 alc260_auto_init_multi_out(codec);
7069 alc260_auto_init_analog_input(codec);
7f311a46 7070 alc260_auto_init_input_src(codec);
757899ac 7071 alc_auto_init_digital(codec);
f6c7e546 7072 if (spec->unsol_event)
7fb0d78f 7073 alc_inithook(codec);
df694daa
KY
7074}
7075
cb53c626
TI
7076#ifdef CONFIG_SND_HDA_POWER_SAVE
7077static struct hda_amp_list alc260_loopbacks[] = {
7078 { 0x07, HDA_INPUT, 0 },
7079 { 0x07, HDA_INPUT, 1 },
7080 { 0x07, HDA_INPUT, 2 },
7081 { 0x07, HDA_INPUT, 3 },
7082 { 0x07, HDA_INPUT, 4 },
7083 { } /* end */
7084};
7085#endif
7086
fc091769
TI
7087/*
7088 * Pin config fixes
7089 */
7090enum {
7091 PINFIX_HP_DC5750,
7092};
7093
fc091769
TI
7094static const struct alc_fixup alc260_fixups[] = {
7095 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7096 .type = ALC_FIXUP_PINS,
7097 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7098 { 0x11, 0x90130110 }, /* speaker */
7099 { }
7100 }
fc091769
TI
7101 },
7102};
7103
7104static struct snd_pci_quirk alc260_fixup_tbl[] = {
7105 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7106 {}
7107};
7108
df694daa
KY
7109/*
7110 * ALC260 configurations
7111 */
ea734963 7112static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7113 [ALC260_BASIC] = "basic",
7114 [ALC260_HP] = "hp",
7115 [ALC260_HP_3013] = "hp-3013",
2922c9af 7116 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7117 [ALC260_FUJITSU_S702X] = "fujitsu",
7118 [ALC260_ACER] = "acer",
bc9f98a9
KY
7119 [ALC260_WILL] = "will",
7120 [ALC260_REPLACER_672V] = "replacer",
cc959489 7121 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7122#ifdef CONFIG_SND_DEBUG
f5fcc13c 7123 [ALC260_TEST] = "test",
7cf51e48 7124#endif
f5fcc13c
TI
7125 [ALC260_AUTO] = "auto",
7126};
7127
7128static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7129 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7130 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7131 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7132 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7133 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7134 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7135 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7136 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7137 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7138 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7139 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7140 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7141 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7142 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7143 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7144 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7145 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7146 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7147 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7148 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7149 {}
7150};
7151
7152static struct alc_config_preset alc260_presets[] = {
7153 [ALC260_BASIC] = {
7154 .mixers = { alc260_base_output_mixer,
45bdd1c1 7155 alc260_input_mixer },
df694daa
KY
7156 .init_verbs = { alc260_init_verbs },
7157 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7158 .dac_nids = alc260_dac_nids,
f9e336f6 7159 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7160 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7161 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7162 .channel_mode = alc260_modes,
7163 .input_mux = &alc260_capture_source,
7164 },
7165 [ALC260_HP] = {
bec15c3a 7166 .mixers = { alc260_hp_output_mixer,
f9e336f6 7167 alc260_input_mixer },
bec15c3a
TI
7168 .init_verbs = { alc260_init_verbs,
7169 alc260_hp_unsol_verbs },
df694daa
KY
7170 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7171 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7172 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7173 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7174 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7175 .channel_mode = alc260_modes,
7176 .input_mux = &alc260_capture_source,
bec15c3a
TI
7177 .unsol_event = alc260_hp_unsol_event,
7178 .init_hook = alc260_hp_automute,
df694daa 7179 },
3f878308
KY
7180 [ALC260_HP_DC7600] = {
7181 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7182 alc260_input_mixer },
3f878308
KY
7183 .init_verbs = { alc260_init_verbs,
7184 alc260_hp_dc7600_verbs },
7185 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7186 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7187 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7188 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7189 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7190 .channel_mode = alc260_modes,
7191 .input_mux = &alc260_capture_source,
7192 .unsol_event = alc260_hp_3012_unsol_event,
7193 .init_hook = alc260_hp_3012_automute,
7194 },
df694daa
KY
7195 [ALC260_HP_3013] = {
7196 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7197 alc260_input_mixer },
bec15c3a
TI
7198 .init_verbs = { alc260_hp_3013_init_verbs,
7199 alc260_hp_3013_unsol_verbs },
df694daa
KY
7200 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7201 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7202 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7203 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7204 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7205 .channel_mode = alc260_modes,
7206 .input_mux = &alc260_capture_source,
bec15c3a
TI
7207 .unsol_event = alc260_hp_3013_unsol_event,
7208 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7209 },
7210 [ALC260_FUJITSU_S702X] = {
f9e336f6 7211 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7212 .init_verbs = { alc260_fujitsu_init_verbs },
7213 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7214 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7215 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7216 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7217 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7218 .channel_mode = alc260_modes,
a1e8d2da
JW
7219 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7220 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7221 },
0bfc90e9 7222 [ALC260_ACER] = {
f9e336f6 7223 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7224 .init_verbs = { alc260_acer_init_verbs },
7225 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7226 .dac_nids = alc260_dac_nids,
7227 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7228 .adc_nids = alc260_dual_adc_nids,
7229 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7230 .channel_mode = alc260_modes,
a1e8d2da
JW
7231 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7232 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7233 },
cc959489
MS
7234 [ALC260_FAVORIT100] = {
7235 .mixers = { alc260_favorit100_mixer },
7236 .init_verbs = { alc260_favorit100_init_verbs },
7237 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7238 .dac_nids = alc260_dac_nids,
7239 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7240 .adc_nids = alc260_dual_adc_nids,
7241 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7242 .channel_mode = alc260_modes,
7243 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7244 .input_mux = alc260_favorit100_capture_sources,
7245 },
bc9f98a9 7246 [ALC260_WILL] = {
f9e336f6 7247 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7248 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7249 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7250 .dac_nids = alc260_dac_nids,
7251 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7252 .adc_nids = alc260_adc_nids,
7253 .dig_out_nid = ALC260_DIGOUT_NID,
7254 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7255 .channel_mode = alc260_modes,
7256 .input_mux = &alc260_capture_source,
7257 },
7258 [ALC260_REPLACER_672V] = {
f9e336f6 7259 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7260 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7261 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7262 .dac_nids = alc260_dac_nids,
7263 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7264 .adc_nids = alc260_adc_nids,
7265 .dig_out_nid = ALC260_DIGOUT_NID,
7266 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7267 .channel_mode = alc260_modes,
7268 .input_mux = &alc260_capture_source,
7269 .unsol_event = alc260_replacer_672v_unsol_event,
7270 .init_hook = alc260_replacer_672v_automute,
7271 },
7cf51e48
JW
7272#ifdef CONFIG_SND_DEBUG
7273 [ALC260_TEST] = {
f9e336f6 7274 .mixers = { alc260_test_mixer },
7cf51e48
JW
7275 .init_verbs = { alc260_test_init_verbs },
7276 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7277 .dac_nids = alc260_test_dac_nids,
7278 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7279 .adc_nids = alc260_test_adc_nids,
7280 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7281 .channel_mode = alc260_modes,
a1e8d2da
JW
7282 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7283 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7284 },
7285#endif
df694daa
KY
7286};
7287
7288static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7289{
7290 struct alc_spec *spec;
df694daa 7291 int err, board_config;
1da177e4 7292
e560d8d8 7293 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7294 if (spec == NULL)
7295 return -ENOMEM;
7296
7297 codec->spec = spec;
7298
f5fcc13c
TI
7299 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7300 alc260_models,
7301 alc260_cfg_tbl);
7302 if (board_config < 0) {
9a11f1aa 7303 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7304 codec->chip_name);
df694daa 7305 board_config = ALC260_AUTO;
16ded525 7306 }
1da177e4 7307
b5bfbc67
TI
7308 if (board_config == ALC260_AUTO) {
7309 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7310 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7311 }
fc091769 7312
df694daa
KY
7313 if (board_config == ALC260_AUTO) {
7314 /* automatic parse from the BIOS config */
7315 err = alc260_parse_auto_config(codec);
7316 if (err < 0) {
7317 alc_free(codec);
7318 return err;
f12ab1e0 7319 } else if (!err) {
9c7f852e
TI
7320 printk(KERN_INFO
7321 "hda_codec: Cannot set up configuration "
7322 "from BIOS. Using base mode...\n");
df694daa
KY
7323 board_config = ALC260_BASIC;
7324 }
a9430dd8 7325 }
e9edcee0 7326
680cd536
KK
7327 err = snd_hda_attach_beep_device(codec, 0x1);
7328 if (err < 0) {
7329 alc_free(codec);
7330 return err;
7331 }
7332
df694daa 7333 if (board_config != ALC260_AUTO)
e9c364c0 7334 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7335
1da177e4
LT
7336 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7337 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7338 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7339
a3bcba38
TI
7340 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7341 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7342
4ef0ef19
TI
7343 if (!spec->adc_nids && spec->input_mux) {
7344 /* check whether NID 0x04 is valid */
7345 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7346 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7347 /* get type */
7348 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7349 spec->adc_nids = alc260_adc_nids_alt;
7350 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7351 } else {
7352 spec->adc_nids = alc260_adc_nids;
7353 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7354 }
7355 }
b59bdf3b 7356 set_capture_mixer(codec);
45bdd1c1 7357 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7358
b5bfbc67 7359 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7360
2134ea4f
TI
7361 spec->vmaster_nid = 0x08;
7362
1da177e4 7363 codec->patch_ops = alc_patch_ops;
df694daa 7364 if (board_config == ALC260_AUTO)
ae6b813a 7365 spec->init_hook = alc260_auto_init;
cb53c626
TI
7366#ifdef CONFIG_SND_HDA_POWER_SAVE
7367 if (!spec->loopback.amplist)
7368 spec->loopback.amplist = alc260_loopbacks;
7369#endif
1da177e4
LT
7370
7371 return 0;
7372}
7373
e9edcee0 7374
1da177e4 7375/*
4953550a 7376 * ALC882/883/885/888/889 support
1da177e4
LT
7377 *
7378 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7379 * configuration. Each pin widget can choose any input DACs and a mixer.
7380 * Each ADC is connected from a mixer of all inputs. This makes possible
7381 * 6-channel independent captures.
7382 *
7383 * In addition, an independent DAC for the multi-playback (not used in this
7384 * driver yet).
7385 */
df694daa
KY
7386#define ALC882_DIGOUT_NID 0x06
7387#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7388#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7389#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7390#define ALC1200_DIGOUT_NID 0x10
7391
1da177e4 7392
d2a6d7dc 7393static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7394 { 8, NULL }
7395};
7396
4953550a 7397/* DACs */
1da177e4
LT
7398static hda_nid_t alc882_dac_nids[4] = {
7399 /* front, rear, clfe, rear_surr */
7400 0x02, 0x03, 0x04, 0x05
7401};
4953550a 7402#define alc883_dac_nids alc882_dac_nids
1da177e4 7403
4953550a 7404/* ADCs */
df694daa
KY
7405#define alc882_adc_nids alc880_adc_nids
7406#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7407#define alc883_adc_nids alc882_adc_nids_alt
7408static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7409static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7410#define alc889_adc_nids alc880_adc_nids
1da177e4 7411
e1406348
TI
7412static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7413static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7414#define alc883_capsrc_nids alc882_capsrc_nids_alt
7415static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7416#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7417
1da177e4
LT
7418/* input MUX */
7419/* FIXME: should be a matrix-type input source selection */
7420
7421static struct hda_input_mux alc882_capture_source = {
7422 .num_items = 4,
7423 .items = {
7424 { "Mic", 0x0 },
7425 { "Front Mic", 0x1 },
7426 { "Line", 0x2 },
7427 { "CD", 0x4 },
7428 },
7429};
41d5545d 7430
4953550a
TI
7431#define alc883_capture_source alc882_capture_source
7432
87a8c370
JK
7433static struct hda_input_mux alc889_capture_source = {
7434 .num_items = 3,
7435 .items = {
7436 { "Front Mic", 0x0 },
7437 { "Mic", 0x3 },
7438 { "Line", 0x2 },
7439 },
7440};
7441
41d5545d
KS
7442static struct hda_input_mux mb5_capture_source = {
7443 .num_items = 3,
7444 .items = {
7445 { "Mic", 0x1 },
b8f171e7 7446 { "Line", 0x7 },
41d5545d
KS
7447 { "CD", 0x4 },
7448 },
7449};
7450
e458b1fa
LY
7451static struct hda_input_mux macmini3_capture_source = {
7452 .num_items = 2,
7453 .items = {
7454 { "Line", 0x2 },
7455 { "CD", 0x4 },
7456 },
7457};
7458
4953550a
TI
7459static struct hda_input_mux alc883_3stack_6ch_intel = {
7460 .num_items = 4,
7461 .items = {
7462 { "Mic", 0x1 },
7463 { "Front Mic", 0x0 },
7464 { "Line", 0x2 },
7465 { "CD", 0x4 },
7466 },
7467};
7468
7469static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7470 .num_items = 2,
7471 .items = {
7472 { "Mic", 0x1 },
7473 { "Line", 0x2 },
7474 },
7475};
7476
7477static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7478 .num_items = 4,
7479 .items = {
7480 { "Mic", 0x0 },
28c4edb7 7481 { "Internal Mic", 0x1 },
4953550a
TI
7482 { "Line", 0x2 },
7483 { "CD", 0x4 },
7484 },
7485};
7486
7487static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7488 .num_items = 2,
7489 .items = {
7490 { "Mic", 0x0 },
28c4edb7 7491 { "Internal Mic", 0x1 },
4953550a
TI
7492 },
7493};
7494
7495static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7496 .num_items = 3,
7497 .items = {
7498 { "Mic", 0x0 },
7499 { "Front Mic", 0x1 },
7500 { "Line", 0x4 },
7501 },
7502};
7503
7504static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7505 .num_items = 2,
7506 .items = {
7507 { "Mic", 0x0 },
7508 { "Line", 0x2 },
7509 },
7510};
7511
7512static struct hda_input_mux alc889A_mb31_capture_source = {
7513 .num_items = 2,
7514 .items = {
7515 { "Mic", 0x0 },
7516 /* Front Mic (0x01) unused */
7517 { "Line", 0x2 },
7518 /* Line 2 (0x03) unused */
af901ca1 7519 /* CD (0x04) unused? */
4953550a
TI
7520 },
7521};
7522
b7cccc52
JM
7523static struct hda_input_mux alc889A_imac91_capture_source = {
7524 .num_items = 2,
7525 .items = {
7526 { "Mic", 0x01 },
7527 { "Line", 0x2 }, /* Not sure! */
7528 },
7529};
7530
4953550a
TI
7531/*
7532 * 2ch mode
7533 */
7534static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7535 { 2, NULL }
7536};
7537
272a527c
KY
7538/*
7539 * 2ch mode
7540 */
7541static struct hda_verb alc882_3ST_ch2_init[] = {
7542 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7543 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7544 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7545 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7546 { } /* end */
7547};
7548
4953550a
TI
7549/*
7550 * 4ch mode
7551 */
7552static struct hda_verb alc882_3ST_ch4_init[] = {
7553 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7554 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7555 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7556 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7557 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7558 { } /* end */
7559};
7560
272a527c
KY
7561/*
7562 * 6ch mode
7563 */
7564static struct hda_verb alc882_3ST_ch6_init[] = {
7565 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7566 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7567 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7568 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7569 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7570 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7571 { } /* end */
7572};
7573
4953550a 7574static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7575 { 2, alc882_3ST_ch2_init },
4953550a 7576 { 4, alc882_3ST_ch4_init },
272a527c
KY
7577 { 6, alc882_3ST_ch6_init },
7578};
7579
4953550a
TI
7580#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7581
a65cc60f 7582/*
7583 * 2ch mode
7584 */
7585static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7586 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7587 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7588 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7589 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7590 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7591 { } /* end */
7592};
7593
7594/*
7595 * 4ch mode
7596 */
7597static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7598 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7599 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7600 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7601 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7602 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7603 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7604 { } /* end */
7605};
7606
7607/*
7608 * 6ch mode
7609 */
7610static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7611 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7612 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7613 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7614 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7615 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7616 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7617 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7618 { } /* end */
7619};
7620
7621static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7622 { 2, alc883_3ST_ch2_clevo_init },
7623 { 4, alc883_3ST_ch4_clevo_init },
7624 { 6, alc883_3ST_ch6_clevo_init },
7625};
7626
7627
df694daa
KY
7628/*
7629 * 6ch mode
7630 */
7631static struct hda_verb alc882_sixstack_ch6_init[] = {
7632 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7633 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7634 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7635 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7636 { } /* end */
7637};
7638
7639/*
7640 * 8ch mode
7641 */
7642static struct hda_verb alc882_sixstack_ch8_init[] = {
7643 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7644 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7645 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7646 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7647 { } /* end */
7648};
7649
7650static struct hda_channel_mode alc882_sixstack_modes[2] = {
7651 { 6, alc882_sixstack_ch6_init },
7652 { 8, alc882_sixstack_ch8_init },
7653};
7654
76e6f5a9
RH
7655
7656/* Macbook Air 2,1 */
7657
7658static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7659 { 2, NULL },
7660};
7661
87350ad0 7662/*
def319f9 7663 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7664 */
7665
7666/*
7667 * 2ch mode
7668 */
7669static struct hda_verb alc885_mbp_ch2_init[] = {
7670 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7671 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7672 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7673 { } /* end */
7674};
7675
7676/*
a3f730af 7677 * 4ch mode
87350ad0 7678 */
a3f730af 7679static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7680 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7681 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7682 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7683 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7684 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7685 { } /* end */
7686};
7687
a3f730af 7688static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7689 { 2, alc885_mbp_ch2_init },
a3f730af 7690 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7691};
7692
92b9de83
KS
7693/*
7694 * 2ch
7695 * Speakers/Woofer/HP = Front
7696 * LineIn = Input
7697 */
7698static struct hda_verb alc885_mb5_ch2_init[] = {
7699 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7700 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7701 { } /* end */
7702};
7703
7704/*
7705 * 6ch mode
7706 * Speakers/HP = Front
7707 * Woofer = LFE
7708 * LineIn = Surround
7709 */
7710static struct hda_verb alc885_mb5_ch6_init[] = {
7711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7713 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7714 { } /* end */
7715};
7716
7717static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7718 { 2, alc885_mb5_ch2_init },
7719 { 6, alc885_mb5_ch6_init },
7720};
87350ad0 7721
d01aecdf 7722#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7723
7724/*
7725 * 2ch mode
7726 */
7727static struct hda_verb alc883_4ST_ch2_init[] = {
7728 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7729 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7730 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7731 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7732 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7733 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7734 { } /* end */
7735};
7736
7737/*
7738 * 4ch mode
7739 */
7740static struct hda_verb alc883_4ST_ch4_init[] = {
7741 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7742 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7743 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7744 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7745 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7746 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7747 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7748 { } /* end */
7749};
7750
7751/*
7752 * 6ch mode
7753 */
7754static struct hda_verb alc883_4ST_ch6_init[] = {
7755 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7756 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7757 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7758 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7759 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7760 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7761 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7762 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7763 { } /* end */
7764};
7765
7766/*
7767 * 8ch mode
7768 */
7769static struct hda_verb alc883_4ST_ch8_init[] = {
7770 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7771 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7772 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7773 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7774 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7775 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7776 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7777 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7778 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7779 { } /* end */
7780};
7781
7782static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7783 { 2, alc883_4ST_ch2_init },
7784 { 4, alc883_4ST_ch4_init },
7785 { 6, alc883_4ST_ch6_init },
7786 { 8, alc883_4ST_ch8_init },
7787};
7788
7789
7790/*
7791 * 2ch mode
7792 */
7793static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7794 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7795 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7796 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7797 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7798 { } /* end */
7799};
7800
7801/*
7802 * 4ch mode
7803 */
7804static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7805 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7806 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7807 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7808 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7809 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7810 { } /* end */
7811};
7812
7813/*
7814 * 6ch mode
7815 */
7816static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7817 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7818 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7819 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7820 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7821 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7822 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7823 { } /* end */
7824};
7825
7826static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7827 { 2, alc883_3ST_ch2_intel_init },
7828 { 4, alc883_3ST_ch4_intel_init },
7829 { 6, alc883_3ST_ch6_intel_init },
7830};
7831
dd7714c9
WF
7832/*
7833 * 2ch mode
7834 */
7835static struct hda_verb alc889_ch2_intel_init[] = {
7836 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7837 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7838 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7839 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7840 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7841 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7842 { } /* end */
7843};
7844
87a8c370
JK
7845/*
7846 * 6ch mode
7847 */
7848static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7849 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7850 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7851 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7852 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7853 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7854 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7855 { } /* end */
7856};
7857
7858/*
7859 * 8ch mode
7860 */
7861static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7862 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7863 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7864 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7865 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7866 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7867 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7868 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7869 { } /* end */
7870};
7871
dd7714c9
WF
7872static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7873 { 2, alc889_ch2_intel_init },
87a8c370
JK
7874 { 6, alc889_ch6_intel_init },
7875 { 8, alc889_ch8_intel_init },
7876};
7877
4953550a
TI
7878/*
7879 * 6ch mode
7880 */
7881static struct hda_verb alc883_sixstack_ch6_init[] = {
7882 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7883 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7884 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7885 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7886 { } /* end */
7887};
7888
7889/*
7890 * 8ch mode
7891 */
7892static struct hda_verb alc883_sixstack_ch8_init[] = {
7893 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7894 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7895 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7896 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7897 { } /* end */
7898};
7899
7900static struct hda_channel_mode alc883_sixstack_modes[2] = {
7901 { 6, alc883_sixstack_ch6_init },
7902 { 8, alc883_sixstack_ch8_init },
7903};
7904
7905
1da177e4
LT
7906/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7907 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7908 */
c8b6bf9b 7909static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7910 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7911 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7912 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7913 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7914 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7915 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7916 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7917 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7918 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7919 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7920 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7921 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7922 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7923 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7924 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7925 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 7926 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
7927 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7928 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 7929 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 7930 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7931 { } /* end */
7932};
7933
76e6f5a9
RH
7934/* Macbook Air 2,1 same control for HP and internal Speaker */
7935
7936static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7937 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7938 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7939 { }
7940};
7941
7942
87350ad0 7943static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7944 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7945 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7946 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7947 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7948 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7949 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7950 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7951 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7952 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
7953 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
7955 { } /* end */
7956};
41d5545d
KS
7957
7958static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7959 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7960 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7961 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7962 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7963 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7964 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7965 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7966 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7967 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7968 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7969 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7970 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
7971 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7972 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
7973 { } /* end */
7974};
92b9de83 7975
e458b1fa
LY
7976static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7977 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7978 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7979 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7980 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7981 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7982 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7983 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7984 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7985 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7986 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 7987 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
7988 { } /* end */
7989};
7990
4b7e1803 7991static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7992 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7993 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7994 { } /* end */
7995};
7996
7997
bdd148a3
KY
7998static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7999 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8000 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8005 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8006 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8008 { } /* end */
8009};
8010
272a527c
KY
8011static struct snd_kcontrol_new alc882_targa_mixer[] = {
8012 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8013 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8014 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8015 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8016 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8017 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8018 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8021 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8022 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8023 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8024 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8025 { } /* end */
8026};
8027
8028/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8029 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8030 */
8031static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8032 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8033 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8034 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8035 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8036 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8037 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8038 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8039 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8040 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8041 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8042 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8043 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8044 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8045 { } /* end */
8046};
8047
914759b7
TI
8048static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8049 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8050 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8051 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8052 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8053 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8054 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8055 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8056 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8057 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8058 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8059 { } /* end */
8060};
8061
df694daa
KY
8062static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8063 {
8064 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8065 .name = "Channel Mode",
8066 .info = alc_ch_mode_info,
8067 .get = alc_ch_mode_get,
8068 .put = alc_ch_mode_put,
8069 },
8070 { } /* end */
8071};
8072
4953550a 8073static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8074 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8077 /* Rear mixer */
05acb863
TI
8078 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8079 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8080 /* CLFE mixer */
05acb863
TI
8081 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8082 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8083 /* Side mixer */
05acb863
TI
8084 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8085 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8086
e9edcee0 8087 /* Front Pin: output 0 (0x0c) */
05acb863 8088 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8089 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8090 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8091 /* Rear Pin: output 1 (0x0d) */
05acb863 8092 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8093 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8094 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8095 /* CLFE Pin: output 2 (0x0e) */
05acb863 8096 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8097 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8098 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8099 /* Side Pin: output 3 (0x0f) */
05acb863 8100 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8101 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8102 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8103 /* Mic (rear) pin: input vref at 80% */
16ded525 8104 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8105 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8106 /* Front Mic pin: input vref at 80% */
16ded525 8107 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8108 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8109 /* Line In pin: input */
05acb863 8110 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8111 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8112 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8113 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8114 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8115 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8116 /* CD pin widget for input */
05acb863 8117 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8118
8119 /* FIXME: use matrix-type input source selection */
8120 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8121 /* Input mixer2 */
05acb863 8122 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8123 /* Input mixer3 */
05acb863 8124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8125 /* ADC2: mute amp left and right */
8126 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8127 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8128 /* ADC3: mute amp left and right */
8129 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8130 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8131
8132 { }
8133};
8134
4953550a
TI
8135static struct hda_verb alc882_adc1_init_verbs[] = {
8136 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8138 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8139 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8140 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8141 /* ADC1: mute amp left and right */
8142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8143 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8144 { }
8145};
8146
4b146cb0
TI
8147static struct hda_verb alc882_eapd_verbs[] = {
8148 /* change to EAPD mode */
8149 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8150 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8151 { }
4b146cb0
TI
8152};
8153
87a8c370
JK
8154static struct hda_verb alc889_eapd_verbs[] = {
8155 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8156 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8157 { }
8158};
8159
6732bd0d
WF
8160static struct hda_verb alc_hp15_unsol_verbs[] = {
8161 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8162 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8163 {}
8164};
87a8c370
JK
8165
8166static struct hda_verb alc885_init_verbs[] = {
8167 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8169 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8170 /* Rear mixer */
88102f3f
KY
8171 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8172 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8173 /* CLFE mixer */
88102f3f
KY
8174 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8175 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8176 /* Side mixer */
88102f3f
KY
8177 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8178 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8179
8180 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8181 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8182 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8183 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8184 /* Front Pin: output 0 (0x0c) */
8185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8186 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8187 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8188 /* Rear Pin: output 1 (0x0d) */
8189 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8190 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8191 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8192 /* CLFE Pin: output 2 (0x0e) */
8193 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8194 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8195 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8196 /* Side Pin: output 3 (0x0f) */
8197 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8198 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8199 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8200 /* Mic (rear) pin: input vref at 80% */
8201 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8202 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8203 /* Front Mic pin: input vref at 80% */
8204 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8205 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8206 /* Line In pin: input */
8207 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8208 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8209
8210 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8211 /* Input mixer1 */
88102f3f 8212 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8213 /* Input mixer2 */
8214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8215 /* Input mixer3 */
88102f3f 8216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8217 /* ADC2: mute amp left and right */
8218 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8219 /* ADC3: mute amp left and right */
8220 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8221
8222 { }
8223};
8224
8225static struct hda_verb alc885_init_input_verbs[] = {
8226 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8227 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8228 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8229 { }
8230};
8231
8232
8233/* Unmute Selector 24h and set the default input to front mic */
8234static struct hda_verb alc889_init_input_verbs[] = {
8235 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8236 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8237 { }
8238};
8239
8240
4953550a
TI
8241#define alc883_init_verbs alc882_base_init_verbs
8242
9102cd1c
TD
8243/* Mac Pro test */
8244static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8245 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8246 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8247 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8248 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8249 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8250 /* FIXME: this looks suspicious...
d355c82a
JK
8251 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8252 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8253 */
9102cd1c
TD
8254 { } /* end */
8255};
8256
8257static struct hda_verb alc882_macpro_init_verbs[] = {
8258 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8259 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8260 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8261 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8262 /* Front Pin: output 0 (0x0c) */
8263 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8264 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8265 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8266 /* Front Mic pin: input vref at 80% */
8267 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8269 /* Speaker: output */
8270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8271 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8272 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8273 /* Headphone output (output 0 - 0x0c) */
8274 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8275 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8276 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8277
8278 /* FIXME: use matrix-type input source selection */
8279 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8280 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8281 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8284 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8285 /* Input mixer2 */
8286 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8288 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8289 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8290 /* Input mixer3 */
8291 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8292 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8293 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8294 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8295 /* ADC1: mute amp left and right */
8296 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8297 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8298 /* ADC2: mute amp left and right */
8299 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8300 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8301 /* ADC3: mute amp left and right */
8302 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8303 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8304
8305 { }
8306};
f12ab1e0 8307
41d5545d
KS
8308/* Macbook 5,1 */
8309static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8310 /* DACs */
8311 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8312 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8313 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8314 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8315 /* Front mixer */
41d5545d
KS
8316 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8317 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8318 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8319 /* Surround mixer */
8320 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8321 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8322 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8323 /* LFE mixer */
8324 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8325 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8326 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8327 /* HP mixer */
8328 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8329 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8330 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8331 /* Front Pin (0x0c) */
41d5545d
KS
8332 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8333 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8334 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8335 /* LFE Pin (0x0e) */
8336 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8337 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8338 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8339 /* HP Pin (0x0f) */
41d5545d
KS
8340 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8342 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8343 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8344 /* Front Mic pin: input vref at 80% */
8345 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8346 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8347 /* Line In pin */
8348 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8349 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8350
b8f171e7
AM
8351 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8354 { }
8355};
8356
e458b1fa
LY
8357/* Macmini 3,1 */
8358static struct hda_verb alc885_macmini3_init_verbs[] = {
8359 /* DACs */
8360 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8361 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8362 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8363 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8364 /* Front mixer */
8365 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8368 /* Surround mixer */
8369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8371 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8372 /* LFE mixer */
8373 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8374 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8375 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8376 /* HP mixer */
8377 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8378 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8380 /* Front Pin (0x0c) */
8381 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8382 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8383 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8384 /* LFE Pin (0x0e) */
8385 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8386 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8387 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8388 /* HP Pin (0x0f) */
8389 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8390 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8391 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8392 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8393 /* Line In pin */
8394 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8395 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8396
8397 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8398 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8399 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8400 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8401 { }
8402};
8403
76e6f5a9
RH
8404
8405static struct hda_verb alc885_mba21_init_verbs[] = {
8406 /*Internal and HP Speaker Mixer*/
8407 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8410 /*Internal Speaker Pin (0x0c)*/
8411 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8412 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8413 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8414 /* HP Pin: output 0 (0x0e) */
8415 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8416 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8417 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8418 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8419 /* Line in (is hp when jack connected)*/
8420 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8421 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8422
8423 { }
8424 };
8425
8426
87350ad0
TI
8427/* Macbook Pro rev3 */
8428static struct hda_verb alc885_mbp3_init_verbs[] = {
8429 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8430 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8431 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8433 /* Rear mixer */
8434 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8435 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8436 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8437 /* HP mixer */
8438 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8439 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8440 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8441 /* Front Pin: output 0 (0x0c) */
8442 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8443 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8444 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8445 /* HP Pin: output 0 (0x0e) */
87350ad0 8446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8448 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8449 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8450 /* Mic (rear) pin: input vref at 80% */
8451 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8453 /* Front Mic pin: input vref at 80% */
8454 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8455 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8456 /* Line In pin: use output 1 when in LineOut mode */
8457 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8458 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8459 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8460
8461 /* FIXME: use matrix-type input source selection */
8462 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8463 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8464 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8465 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8466 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8467 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8468 /* Input mixer2 */
8469 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8471 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8472 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8473 /* Input mixer3 */
8474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8477 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8478 /* ADC1: mute amp left and right */
8479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8480 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8481 /* ADC2: mute amp left and right */
8482 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8483 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8484 /* ADC3: mute amp left and right */
8485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8486 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8487
8488 { }
8489};
8490
4b7e1803
JM
8491/* iMac 9,1 */
8492static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8493 /* Internal Speaker Pin (0x0c) */
8494 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8495 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8496 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8497 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8498 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8499 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8500 /* HP Pin: Rear */
4b7e1803
JM
8501 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8503 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8504 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8505 /* Line in Rear */
8506 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8507 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8508 /* Front Mic pin: input vref at 80% */
8509 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8511 /* Rear mixer */
8512 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8515 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8519 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8524 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8525 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8529 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8534 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8536 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8537 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8538 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8539 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8540 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8542 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8543 { }
8544};
8545
c54728d8
NF
8546/* iMac 24 mixer. */
8547static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8548 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8549 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8550 { } /* end */
8551};
8552
8553/* iMac 24 init verbs. */
8554static struct hda_verb alc885_imac24_init_verbs[] = {
8555 /* Internal speakers: output 0 (0x0c) */
8556 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8557 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8558 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8559 /* Internal speakers: output 0 (0x0c) */
8560 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8561 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8562 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8563 /* Headphone: output 0 (0x0c) */
8564 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8565 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8566 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8567 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8568 /* Front Mic: input vref at 80% */
8569 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8570 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8571 { }
8572};
8573
8574/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8575static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8576{
a9fd4f3f 8577 struct alc_spec *spec = codec->spec;
c54728d8 8578
a9fd4f3f
TI
8579 spec->autocfg.hp_pins[0] = 0x14;
8580 spec->autocfg.speaker_pins[0] = 0x18;
8581 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8582}
8583
9d54f08b
TI
8584#define alc885_mb5_setup alc885_imac24_setup
8585#define alc885_macmini3_setup alc885_imac24_setup
8586
76e6f5a9
RH
8587/* Macbook Air 2,1 */
8588static void alc885_mba21_setup(struct hda_codec *codec)
8589{
8590 struct alc_spec *spec = codec->spec;
8591
8592 spec->autocfg.hp_pins[0] = 0x14;
8593 spec->autocfg.speaker_pins[0] = 0x18;
8594}
8595
8596
8597
4f5d1706 8598static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8599{
a9fd4f3f 8600 struct alc_spec *spec = codec->spec;
87350ad0 8601
a9fd4f3f
TI
8602 spec->autocfg.hp_pins[0] = 0x15;
8603 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8604}
8605
9d54f08b 8606static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8607{
9d54f08b 8608 struct alc_spec *spec = codec->spec;
4b7e1803 8609
9d54f08b 8610 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8611 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8612 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8613}
87350ad0 8614
272a527c
KY
8615static struct hda_verb alc882_targa_verbs[] = {
8616 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8617 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8618
8619 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8620 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8621
272a527c
KY
8622 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8623 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8624 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8625
8626 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8627 { } /* end */
8628};
8629
8630/* toggle speaker-output according to the hp-jack state */
8631static void alc882_targa_automute(struct hda_codec *codec)
8632{
a9fd4f3f
TI
8633 struct alc_spec *spec = codec->spec;
8634 alc_automute_amp(codec);
82beb8fd 8635 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8636 spec->jack_present ? 1 : 3);
8637}
8638
4f5d1706 8639static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8640{
8641 struct alc_spec *spec = codec->spec;
8642
8643 spec->autocfg.hp_pins[0] = 0x14;
8644 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8645}
8646
8647static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8648{
a9fd4f3f 8649 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8650 alc882_targa_automute(codec);
272a527c
KY
8651}
8652
8653static struct hda_verb alc882_asus_a7j_verbs[] = {
8654 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8655 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8656
8657 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8658 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8659 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8660
272a527c
KY
8661 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8662 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8663 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8664
8665 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8666 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8667 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8668 { } /* end */
8669};
8670
914759b7
TI
8671static struct hda_verb alc882_asus_a7m_verbs[] = {
8672 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8673 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8674
8675 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8677 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8678
914759b7
TI
8679 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8680 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8681 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8682
8683 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8684 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8685 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8686 { } /* end */
8687};
8688
9102cd1c
TD
8689static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8690{
8691 unsigned int gpiostate, gpiomask, gpiodir;
8692
8693 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8694 AC_VERB_GET_GPIO_DATA, 0);
8695
8696 if (!muted)
8697 gpiostate |= (1 << pin);
8698 else
8699 gpiostate &= ~(1 << pin);
8700
8701 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8702 AC_VERB_GET_GPIO_MASK, 0);
8703 gpiomask |= (1 << pin);
8704
8705 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8706 AC_VERB_GET_GPIO_DIRECTION, 0);
8707 gpiodir |= (1 << pin);
8708
8709
8710 snd_hda_codec_write(codec, codec->afg, 0,
8711 AC_VERB_SET_GPIO_MASK, gpiomask);
8712 snd_hda_codec_write(codec, codec->afg, 0,
8713 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8714
8715 msleep(1);
8716
8717 snd_hda_codec_write(codec, codec->afg, 0,
8718 AC_VERB_SET_GPIO_DATA, gpiostate);
8719}
8720
7debbe51
TI
8721/* set up GPIO at initialization */
8722static void alc885_macpro_init_hook(struct hda_codec *codec)
8723{
8724 alc882_gpio_mute(codec, 0, 0);
8725 alc882_gpio_mute(codec, 1, 0);
8726}
8727
8728/* set up GPIO and update auto-muting at initialization */
8729static void alc885_imac24_init_hook(struct hda_codec *codec)
8730{
8731 alc885_macpro_init_hook(codec);
4f5d1706 8732 alc_automute_amp(codec);
7debbe51
TI
8733}
8734
df694daa
KY
8735/*
8736 * generic initialization of ADC, input mixers and output mixers
8737 */
4953550a 8738static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8739 /*
8740 * Unmute ADC0-2 and set the default input to mic-in
8741 */
4953550a
TI
8742 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8743 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8744 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8745 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8746
4953550a
TI
8747 /*
8748 * Set up output mixers (0x0c - 0x0f)
8749 */
8750 /* set vol=0 to output mixers */
8751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8752 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8753 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8754 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8755 /* set up input amps for analog loopback */
8756 /* Amp Indices: DAC = 0, mixer = 1 */
8757 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8758 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8759 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8760 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8761 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8762 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8763 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8764 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8765 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8766 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8767
4953550a
TI
8768 /* FIXME: use matrix-type input source selection */
8769 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8770 /* Input mixer2 */
88102f3f 8771 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8772 /* Input mixer3 */
88102f3f 8773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8774 { }
9c7f852e
TI
8775};
8776
eb4c41d3
TS
8777/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8778static struct hda_verb alc889A_mb31_ch2_init[] = {
8779 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8780 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8781 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8782 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8783 { } /* end */
8784};
8785
8786/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8787static struct hda_verb alc889A_mb31_ch4_init[] = {
8788 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8789 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8790 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8791 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8792 { } /* end */
8793};
8794
8795/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8796static struct hda_verb alc889A_mb31_ch5_init[] = {
8797 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8798 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8799 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8800 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8801 { } /* end */
8802};
8803
8804/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8805static struct hda_verb alc889A_mb31_ch6_init[] = {
8806 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8807 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8808 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8809 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8810 { } /* end */
8811};
8812
8813static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8814 { 2, alc889A_mb31_ch2_init },
8815 { 4, alc889A_mb31_ch4_init },
8816 { 5, alc889A_mb31_ch5_init },
8817 { 6, alc889A_mb31_ch6_init },
8818};
8819
b373bdeb
AN
8820static struct hda_verb alc883_medion_eapd_verbs[] = {
8821 /* eanable EAPD on medion laptop */
8822 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8823 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8824 { }
8825};
8826
4953550a 8827#define alc883_base_mixer alc882_base_mixer
834be88d 8828
a8848bd6
AS
8829static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8830 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8831 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8832 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8833 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8834 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8835 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8836 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8838 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8839 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8840 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8841 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8842 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8843 { } /* end */
8844};
8845
0c4cc443 8846static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8847 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8848 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8849 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8850 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8852 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8854 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8855 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8856 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8857 { } /* end */
8858};
8859
fb97dc67
J
8860static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8861 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8862 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8863 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8864 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8865 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8866 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8867 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8868 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8869 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8870 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8871 { } /* end */
8872};
8873
9c7f852e
TI
8874static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8875 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8876 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8877 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8878 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8879 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8880 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8881 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8882 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8883 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8884 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8886 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8887 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8888 { } /* end */
8889};
df694daa 8890
9c7f852e
TI
8891static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8892 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8893 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8894 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8895 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8896 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8897 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8898 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8899 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8900 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8901 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8902 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8903 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8904 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8905 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8906 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8907 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8908 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8909 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8910 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8911 { } /* end */
8912};
8913
17bba1b7
J
8914static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8917 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8918 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8919 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8920 HDA_OUTPUT),
8921 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8922 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8923 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8924 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8925 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8926 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8927 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8928 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8929 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8930 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
8931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8932 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8933 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 8934 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8935 { } /* end */
8936};
8937
87a8c370
JK
8938static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8939 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8940 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8941 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8942 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8943 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8944 HDA_OUTPUT),
8945 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8946 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8947 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8948 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8949 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8950 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8951 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8952 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8953 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 8954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
8955 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8956 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8957 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
8958 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8959 { } /* end */
8960};
8961
d1d985f0 8962static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8963 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8964 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8965 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8966 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8967 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8968 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8969 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8970 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8971 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8972 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8973 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
8978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8980 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 8981 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8982 { } /* end */
8983};
8984
c259249f 8985static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8989 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8990 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8991 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8992 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8993 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8994 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8995 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8996 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8997 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9001 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9003 { } /* end */
f12ab1e0 9004};
ccc656ce 9005
c259249f 9006static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9007 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9010 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9011 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9012 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9013 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9014 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9015 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9016 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9017 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9018 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9019 { } /* end */
f12ab1e0 9020};
ccc656ce 9021
b99dba34
TI
9022static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9023 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9024 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9025 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9026 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9027 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9028 { } /* end */
9029};
9030
bc9f98a9
KY
9031static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9032 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9033 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9034 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9035 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9036 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9038 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9039 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9040 { } /* end */
f12ab1e0 9041};
bc9f98a9 9042
272a527c
KY
9043static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9044 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9045 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9046 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9047 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9048 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9049 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9050 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9051 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9052 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9053 { } /* end */
ea1fb29a 9054};
272a527c 9055
7ad7b218
MC
9056static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9057 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9058 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9059 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9060 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9061 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9062 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9063 { } /* end */
9064};
9065
9066static struct hda_verb alc883_medion_wim2160_verbs[] = {
9067 /* Unmute front mixer */
9068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9070
9071 /* Set speaker pin to front mixer */
9072 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9073
9074 /* Init headphone pin */
9075 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9076 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9077 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9078 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9079
9080 { } /* end */
9081};
9082
9083/* toggle speaker-output according to the hp-jack state */
9084static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9085{
9086 struct alc_spec *spec = codec->spec;
9087
9088 spec->autocfg.hp_pins[0] = 0x1a;
9089 spec->autocfg.speaker_pins[0] = 0x15;
9090}
9091
2880a867 9092static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9093 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9094 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9095 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9096 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9097 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9098 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9099 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9100 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9101 { } /* end */
d1a991a6 9102};
2880a867 9103
d2fd4b09
TV
9104static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9105 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9106 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9107 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9108 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9109 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9110 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9112 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9114 { } /* end */
9115};
9116
e2757d5e
KY
9117static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9118 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9119 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9120 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9121 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9122 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9123 0x0d, 1, 0x0, HDA_OUTPUT),
9124 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9125 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9126 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9127 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9128 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9129 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9130 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9131 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9132 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9133 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9134 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9135 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9136 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9137 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9138 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9139 { } /* end */
9140};
9141
eb4c41d3
TS
9142static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9143 /* Output mixers */
9144 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9145 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9146 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9147 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9148 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9149 HDA_OUTPUT),
9150 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9151 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9152 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9153 /* Output switches */
9154 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9155 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9156 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9157 /* Boost mixers */
5f99f86a
DH
9158 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9159 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9160 /* Input mixers */
9161 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9162 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9163 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9164 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9165 { } /* end */
9166};
9167
3e1647c5
GG
9168static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9169 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9170 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9173 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9174 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9175 { } /* end */
9176};
9177
e2757d5e
KY
9178static struct hda_bind_ctls alc883_bind_cap_vol = {
9179 .ops = &snd_hda_bind_vol,
9180 .values = {
9181 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9182 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9183 0
9184 },
9185};
9186
9187static struct hda_bind_ctls alc883_bind_cap_switch = {
9188 .ops = &snd_hda_bind_sw,
9189 .values = {
9190 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9191 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9192 0
9193 },
9194};
9195
9196static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9197 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9198 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9199 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9200 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9201 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9202 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9203 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9204 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9205 { } /* end */
9206};
df694daa 9207
4953550a
TI
9208static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9209 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9210 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9211 {
9212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9213 /* .name = "Capture Source", */
9214 .name = "Input Source",
9215 .count = 1,
9216 .info = alc_mux_enum_info,
9217 .get = alc_mux_enum_get,
9218 .put = alc_mux_enum_put,
9219 },
9220 { } /* end */
9221};
9c7f852e 9222
4953550a
TI
9223static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9224 {
9225 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9226 .name = "Channel Mode",
9227 .info = alc_ch_mode_info,
9228 .get = alc_ch_mode_get,
9229 .put = alc_ch_mode_put,
9230 },
9231 { } /* end */
9c7f852e
TI
9232};
9233
a8848bd6 9234/* toggle speaker-output according to the hp-jack state */
4f5d1706 9235static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9236{
a9fd4f3f 9237 struct alc_spec *spec = codec->spec;
a8848bd6 9238
a9fd4f3f
TI
9239 spec->autocfg.hp_pins[0] = 0x15;
9240 spec->autocfg.speaker_pins[0] = 0x14;
9241 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9242}
9243
a8848bd6
AS
9244static struct hda_verb alc883_mitac_verbs[] = {
9245 /* HP */
9246 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9247 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9248 /* Subwoofer */
9249 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9250 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9251
9252 /* enable unsolicited event */
9253 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9254 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9255
9256 { } /* end */
9257};
9258
a65cc60f 9259static struct hda_verb alc883_clevo_m540r_verbs[] = {
9260 /* HP */
9261 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9262 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9263 /* Int speaker */
9264 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9265
9266 /* enable unsolicited event */
9267 /*
9268 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9269 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9270 */
9271
9272 { } /* end */
9273};
9274
0c4cc443 9275static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9276 /* HP */
9277 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9278 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9279 /* Int speaker */
9280 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9281 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9282
9283 /* enable unsolicited event */
9284 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9285 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9286
9287 { } /* end */
9288};
9289
fb97dc67
J
9290static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9291 /* HP */
9292 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9293 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9294 /* Subwoofer */
9295 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9296 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9297
9298 /* enable unsolicited event */
9299 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9300
9301 { } /* end */
9302};
9303
c259249f 9304static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9305 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9307
9308 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9309 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9310
64a8be74
DH
9311/* Connect Line-Out side jack (SPDIF) to Side */
9312 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9313 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9314 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9315/* Connect Mic jack to CLFE */
9316 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9317 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9318 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9319/* Connect Line-in jack to Surround */
9320 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9321 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9322 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9323/* Connect HP out jack to Front */
9324 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9325 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9326 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9327
9328 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9329
9330 { } /* end */
9331};
9332
bc9f98a9
KY
9333static struct hda_verb alc883_lenovo_101e_verbs[] = {
9334 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9335 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9336 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9337 { } /* end */
9338};
9339
272a527c
KY
9340static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9341 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9343 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9344 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9345 { } /* end */
9346};
9347
9348static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9349 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9351 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9352 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9353 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9354 { } /* end */
9355};
9356
189609ae
KY
9357static struct hda_verb alc883_haier_w66_verbs[] = {
9358 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9360
9361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9362
9363 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9364 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9365 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9366 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9367 { } /* end */
9368};
9369
e2757d5e
KY
9370static struct hda_verb alc888_lenovo_sky_verbs[] = {
9371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9374 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9375 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9376 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9377 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9378 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9379 { } /* end */
9380};
9381
8718b700
HRK
9382static struct hda_verb alc888_6st_dell_verbs[] = {
9383 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9384 { }
9385};
9386
3e1647c5
GG
9387static struct hda_verb alc883_vaiott_verbs[] = {
9388 /* HP */
9389 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9390 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9391
9392 /* enable unsolicited event */
9393 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9394
9395 { } /* end */
9396};
9397
4f5d1706 9398static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9399{
a9fd4f3f 9400 struct alc_spec *spec = codec->spec;
8718b700 9401
a9fd4f3f
TI
9402 spec->autocfg.hp_pins[0] = 0x1b;
9403 spec->autocfg.speaker_pins[0] = 0x14;
9404 spec->autocfg.speaker_pins[1] = 0x16;
9405 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9406}
9407
4723c022 9408static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9409 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9410 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9411 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9412 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9413 { } /* end */
5795b9e6
CM
9414};
9415
3ea0d7cf
HRK
9416/*
9417 * 2ch mode
9418 */
4723c022 9419static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9420 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9421 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9422 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9423 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9424 { } /* end */
8341de60
CM
9425};
9426
3ea0d7cf
HRK
9427/*
9428 * 4ch mode
9429 */
9430static struct hda_verb alc888_3st_hp_4ch_init[] = {
9431 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9432 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9433 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9434 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9435 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9436 { } /* end */
9437};
9438
9439/*
9440 * 6ch mode
9441 */
4723c022 9442static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9443 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9444 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9445 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9446 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9447 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9448 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9449 { } /* end */
8341de60
CM
9450};
9451
3ea0d7cf 9452static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9453 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9454 { 4, alc888_3st_hp_4ch_init },
4723c022 9455 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9456};
9457
272a527c
KY
9458/* toggle front-jack and RCA according to the hp-jack state */
9459static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9460{
864f92be 9461 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9462
47fd830a
TI
9463 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9464 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9465 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9466 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9467}
9468
9469/* toggle RCA according to the front-jack state */
9470static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9471{
864f92be 9472 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9473
47fd830a
TI
9474 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9475 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9476}
47fd830a 9477
272a527c
KY
9478static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9479 unsigned int res)
9480{
9481 if ((res >> 26) == ALC880_HP_EVENT)
9482 alc888_lenovo_ms7195_front_automute(codec);
9483 if ((res >> 26) == ALC880_FRONT_EVENT)
9484 alc888_lenovo_ms7195_rca_automute(codec);
9485}
9486
272a527c 9487/* toggle speaker-output according to the hp-jack state */
dc427170 9488static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9489{
a9fd4f3f 9490 struct alc_spec *spec = codec->spec;
272a527c 9491
a9fd4f3f
TI
9492 spec->autocfg.hp_pins[0] = 0x14;
9493 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9494}
9495
ccc656ce 9496/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9497#define alc883_targa_init_hook alc882_targa_init_hook
9498#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9499
4f5d1706 9500static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9501{
a9fd4f3f
TI
9502 struct alc_spec *spec = codec->spec;
9503
9504 spec->autocfg.hp_pins[0] = 0x15;
9505 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9506}
9507
9508static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9509{
a9fd4f3f 9510 alc_automute_amp(codec);
eeb43387 9511 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9512}
9513
9514static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9515 unsigned int res)
9516{
0c4cc443 9517 switch (res >> 26) {
0c4cc443 9518 case ALC880_MIC_EVENT:
eeb43387 9519 alc88x_simple_mic_automute(codec);
0c4cc443 9520 break;
a9fd4f3f
TI
9521 default:
9522 alc_automute_amp_unsol_event(codec, res);
9523 break;
0c4cc443 9524 }
368c7a95
J
9525}
9526
fb97dc67 9527/* toggle speaker-output according to the hp-jack state */
4f5d1706 9528static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9529{
a9fd4f3f 9530 struct alc_spec *spec = codec->spec;
fb97dc67 9531
a9fd4f3f
TI
9532 spec->autocfg.hp_pins[0] = 0x14;
9533 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9534}
9535
4f5d1706 9536static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9537{
a9fd4f3f 9538 struct alc_spec *spec = codec->spec;
189609ae 9539
a9fd4f3f
TI
9540 spec->autocfg.hp_pins[0] = 0x1b;
9541 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9542}
9543
bc9f98a9
KY
9544static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9545{
864f92be 9546 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9547
47fd830a
TI
9548 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9549 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9550}
9551
9552static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9553{
864f92be 9554 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9555
47fd830a
TI
9556 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9557 HDA_AMP_MUTE, bits);
9558 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9559 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9560}
9561
9562static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9563 unsigned int res)
9564{
9565 if ((res >> 26) == ALC880_HP_EVENT)
9566 alc883_lenovo_101e_all_automute(codec);
9567 if ((res >> 26) == ALC880_FRONT_EVENT)
9568 alc883_lenovo_101e_ispeaker_automute(codec);
9569}
9570
676a9b53 9571/* toggle speaker-output according to the hp-jack state */
4f5d1706 9572static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9573{
a9fd4f3f 9574 struct alc_spec *spec = codec->spec;
676a9b53 9575
a9fd4f3f
TI
9576 spec->autocfg.hp_pins[0] = 0x14;
9577 spec->autocfg.speaker_pins[0] = 0x15;
9578 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9579}
9580
d1a991a6
KY
9581static struct hda_verb alc883_acer_eapd_verbs[] = {
9582 /* HP Pin: output 0 (0x0c) */
9583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9584 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9585 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9586 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9587 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9588 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9589 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9590 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9591 /* eanable EAPD on medion laptop */
9592 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9593 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9594 /* enable unsolicited event */
9595 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9596 { }
9597};
9598
4f5d1706 9599static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9600{
a9fd4f3f 9601 struct alc_spec *spec = codec->spec;
5795b9e6 9602
a9fd4f3f
TI
9603 spec->autocfg.hp_pins[0] = 0x1b;
9604 spec->autocfg.speaker_pins[0] = 0x14;
9605 spec->autocfg.speaker_pins[1] = 0x15;
9606 spec->autocfg.speaker_pins[2] = 0x16;
9607 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9608}
9609
4f5d1706 9610static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9611{
a9fd4f3f 9612 struct alc_spec *spec = codec->spec;
e2757d5e 9613
a9fd4f3f
TI
9614 spec->autocfg.hp_pins[0] = 0x1b;
9615 spec->autocfg.speaker_pins[0] = 0x14;
9616 spec->autocfg.speaker_pins[1] = 0x15;
9617 spec->autocfg.speaker_pins[2] = 0x16;
9618 spec->autocfg.speaker_pins[3] = 0x17;
9619 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9620}
9621
4f5d1706 9622static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9623{
9624 struct alc_spec *spec = codec->spec;
9625
9626 spec->autocfg.hp_pins[0] = 0x15;
9627 spec->autocfg.speaker_pins[0] = 0x14;
9628 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9629}
9630
e2757d5e
KY
9631static struct hda_verb alc888_asus_m90v_verbs[] = {
9632 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9633 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9634 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9635 /* enable unsolicited event */
9636 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9637 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9638 { } /* end */
9639};
9640
4f5d1706 9641static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9642{
a9fd4f3f 9643 struct alc_spec *spec = codec->spec;
e2757d5e 9644
a9fd4f3f
TI
9645 spec->autocfg.hp_pins[0] = 0x1b;
9646 spec->autocfg.speaker_pins[0] = 0x14;
9647 spec->autocfg.speaker_pins[1] = 0x15;
9648 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9649 spec->ext_mic.pin = 0x18;
9650 spec->int_mic.pin = 0x19;
9651 spec->ext_mic.mux_idx = 0;
9652 spec->int_mic.mux_idx = 1;
9653 spec->auto_mic = 1;
e2757d5e
KY
9654}
9655
9656static struct hda_verb alc888_asus_eee1601_verbs[] = {
9657 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9658 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9659 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9661 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9662 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9663 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9664 /* enable unsolicited event */
9665 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9666 { } /* end */
9667};
9668
e2757d5e
KY
9669static void alc883_eee1601_inithook(struct hda_codec *codec)
9670{
a9fd4f3f
TI
9671 struct alc_spec *spec = codec->spec;
9672
9673 spec->autocfg.hp_pins[0] = 0x14;
9674 spec->autocfg.speaker_pins[0] = 0x1b;
9675 alc_automute_pin(codec);
e2757d5e
KY
9676}
9677
eb4c41d3
TS
9678static struct hda_verb alc889A_mb31_verbs[] = {
9679 /* Init rear pin (used as headphone output) */
9680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9681 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9682 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9683 /* Init line pin (used as output in 4ch and 6ch mode) */
9684 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9685 /* Init line 2 pin (used as headphone out by default) */
9686 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9687 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9688 { } /* end */
9689};
9690
9691/* Mute speakers according to the headphone jack state */
9692static void alc889A_mb31_automute(struct hda_codec *codec)
9693{
9694 unsigned int present;
9695
9696 /* Mute only in 2ch or 4ch mode */
9697 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9698 == 0x00) {
864f92be 9699 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9700 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9701 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9702 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9703 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9704 }
9705}
9706
9707static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9708{
9709 if ((res >> 26) == ALC880_HP_EVENT)
9710 alc889A_mb31_automute(codec);
9711}
9712
4953550a 9713
cb53c626 9714#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9715#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9716#endif
9717
def319f9 9718/* pcm configuration: identical with ALC880 */
4953550a
TI
9719#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9720#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9721#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9722#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9723
9724static hda_nid_t alc883_slave_dig_outs[] = {
9725 ALC1200_DIGOUT_NID, 0,
9726};
9727
9728static hda_nid_t alc1200_slave_dig_outs[] = {
9729 ALC883_DIGOUT_NID, 0,
9730};
9c7f852e
TI
9731
9732/*
9733 * configuration and preset
9734 */
ea734963 9735static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9736 [ALC882_3ST_DIG] = "3stack-dig",
9737 [ALC882_6ST_DIG] = "6stack-dig",
9738 [ALC882_ARIMA] = "arima",
9739 [ALC882_W2JC] = "w2jc",
9740 [ALC882_TARGA] = "targa",
9741 [ALC882_ASUS_A7J] = "asus-a7j",
9742 [ALC882_ASUS_A7M] = "asus-a7m",
9743 [ALC885_MACPRO] = "macpro",
9744 [ALC885_MB5] = "mb5",
e458b1fa 9745 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9746 [ALC885_MBA21] = "mba21",
4953550a
TI
9747 [ALC885_MBP3] = "mbp3",
9748 [ALC885_IMAC24] = "imac24",
4b7e1803 9749 [ALC885_IMAC91] = "imac91",
4953550a 9750 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9751 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9752 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9753 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9754 [ALC883_TARGA_DIG] = "targa-dig",
9755 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9756 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9757 [ALC883_ACER] = "acer",
2880a867 9758 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9759 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9760 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9761 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9762 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9763 [ALC883_MEDION] = "medion",
7ad7b218 9764 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9765 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9766 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9767 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9768 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9769 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9770 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9771 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9772 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9773 [ALC883_MITAC] = "mitac",
a65cc60f 9774 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9775 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9776 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9777 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9778 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9779 [ALC889A_INTEL] = "intel-alc889a",
9780 [ALC889_INTEL] = "intel-x58",
3ab90935 9781 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9782 [ALC889A_MB31] = "mb31",
3e1647c5 9783 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9784 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9785};
9786
4953550a
TI
9787static struct snd_pci_quirk alc882_cfg_tbl[] = {
9788 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9789
ac3e3741 9790 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9791 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9792 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9793 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9794 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9795 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9796 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9797 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9798 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9799 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9800 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9801 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9802 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9803 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9804 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9805 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9806 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9807 ALC888_ACER_ASPIRE_6530G),
cc374c47 9808 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9809 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9810 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9811 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9812 /* default Acer -- disabled as it causes more problems.
9813 * model=auto should work fine now
9814 */
9815 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9816
5795b9e6 9817 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9818
febe3375 9819 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9820 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9821 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9822 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9823 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9824 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9825
9826 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9827 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9828 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9829 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9830 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9831 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9832 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9833 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9834 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9835 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9836 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9837
9838 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9839 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9840 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9841 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9842 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9843 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9844 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9845 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9846 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9847
6f3bf657 9848 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9849 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9850 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9851 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9852 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9853 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9854 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9855 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9856 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9857 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9858 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9859 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9860 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9861 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9862 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9863 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9864 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9865 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9866 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9867 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9868 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9869 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9870 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9871 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9872 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9873 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9874 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9875 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9876 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9877 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9878 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9879
ac3e3741 9880 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9881 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9882 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9883 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9884 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9885 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9886 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9887 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9888 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9889 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9890 ALC883_FUJITSU_PI2515),
bfb53037 9891 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9892 ALC888_FUJITSU_XA3530),
272a527c 9893 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9894 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9895 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9896 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9897 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9898 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9899 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9900 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9901
17bba1b7
J
9902 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9903 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9904 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9905 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9906 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9907 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9908 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9909
4953550a 9910 {}
f3cd3f5d
WF
9911};
9912
4953550a
TI
9913/* codec SSID table for Intel Mac */
9914static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9915 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9916 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9917 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9918 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9919 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9920 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9921 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9922 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9923 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9924 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9925 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9926 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9927 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9928 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9929 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9930 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9931 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9932 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9933 * so apparently no perfect solution yet
4953550a
TI
9934 */
9935 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9936 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9937 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9938 {} /* terminator */
b25c9da1
WF
9939};
9940
4953550a
TI
9941static struct alc_config_preset alc882_presets[] = {
9942 [ALC882_3ST_DIG] = {
9943 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9944 .init_verbs = { alc882_base_init_verbs,
9945 alc882_adc1_init_verbs },
4953550a
TI
9946 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9947 .dac_nids = alc882_dac_nids,
9948 .dig_out_nid = ALC882_DIGOUT_NID,
9949 .dig_in_nid = ALC882_DIGIN_NID,
9950 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9951 .channel_mode = alc882_ch_modes,
9952 .need_dac_fix = 1,
9953 .input_mux = &alc882_capture_source,
9954 },
9955 [ALC882_6ST_DIG] = {
9956 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9957 .init_verbs = { alc882_base_init_verbs,
9958 alc882_adc1_init_verbs },
4953550a
TI
9959 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9960 .dac_nids = alc882_dac_nids,
9961 .dig_out_nid = ALC882_DIGOUT_NID,
9962 .dig_in_nid = ALC882_DIGIN_NID,
9963 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9964 .channel_mode = alc882_sixstack_modes,
9965 .input_mux = &alc882_capture_source,
9966 },
9967 [ALC882_ARIMA] = {
9968 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9969 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9970 alc882_eapd_verbs },
4953550a
TI
9971 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9972 .dac_nids = alc882_dac_nids,
9973 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9974 .channel_mode = alc882_sixstack_modes,
9975 .input_mux = &alc882_capture_source,
9976 },
9977 [ALC882_W2JC] = {
9978 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9979 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9980 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9981 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9982 .dac_nids = alc882_dac_nids,
9983 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9984 .channel_mode = alc880_threestack_modes,
9985 .need_dac_fix = 1,
9986 .input_mux = &alc882_capture_source,
9987 .dig_out_nid = ALC882_DIGOUT_NID,
9988 },
76e6f5a9
RH
9989 [ALC885_MBA21] = {
9990 .mixers = { alc885_mba21_mixer },
9991 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9992 .num_dacs = 2,
9993 .dac_nids = alc882_dac_nids,
9994 .channel_mode = alc885_mba21_ch_modes,
9995 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9996 .input_mux = &alc882_capture_source,
9997 .unsol_event = alc_automute_amp_unsol_event,
9998 .setup = alc885_mba21_setup,
9999 .init_hook = alc_automute_amp,
10000 },
4953550a
TI
10001 [ALC885_MBP3] = {
10002 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10003 .init_verbs = { alc885_mbp3_init_verbs,
10004 alc880_gpio1_init_verbs },
be0ae923 10005 .num_dacs = 2,
4953550a 10006 .dac_nids = alc882_dac_nids,
be0ae923
TI
10007 .hp_nid = 0x04,
10008 .channel_mode = alc885_mbp_4ch_modes,
10009 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10010 .input_mux = &alc882_capture_source,
10011 .dig_out_nid = ALC882_DIGOUT_NID,
10012 .dig_in_nid = ALC882_DIGIN_NID,
10013 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10014 .setup = alc885_mbp3_setup,
10015 .init_hook = alc_automute_amp,
4953550a
TI
10016 },
10017 [ALC885_MB5] = {
10018 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10019 .init_verbs = { alc885_mb5_init_verbs,
10020 alc880_gpio1_init_verbs },
10021 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10022 .dac_nids = alc882_dac_nids,
10023 .channel_mode = alc885_mb5_6ch_modes,
10024 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10025 .input_mux = &mb5_capture_source,
10026 .dig_out_nid = ALC882_DIGOUT_NID,
10027 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10028 .unsol_event = alc_automute_amp_unsol_event,
10029 .setup = alc885_mb5_setup,
10030 .init_hook = alc_automute_amp,
4953550a 10031 },
e458b1fa
LY
10032 [ALC885_MACMINI3] = {
10033 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10034 .init_verbs = { alc885_macmini3_init_verbs,
10035 alc880_gpio1_init_verbs },
10036 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10037 .dac_nids = alc882_dac_nids,
10038 .channel_mode = alc885_macmini3_6ch_modes,
10039 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10040 .input_mux = &macmini3_capture_source,
10041 .dig_out_nid = ALC882_DIGOUT_NID,
10042 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10043 .unsol_event = alc_automute_amp_unsol_event,
10044 .setup = alc885_macmini3_setup,
10045 .init_hook = alc_automute_amp,
e458b1fa 10046 },
4953550a
TI
10047 [ALC885_MACPRO] = {
10048 .mixers = { alc882_macpro_mixer },
10049 .init_verbs = { alc882_macpro_init_verbs },
10050 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10051 .dac_nids = alc882_dac_nids,
10052 .dig_out_nid = ALC882_DIGOUT_NID,
10053 .dig_in_nid = ALC882_DIGIN_NID,
10054 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10055 .channel_mode = alc882_ch_modes,
10056 .input_mux = &alc882_capture_source,
10057 .init_hook = alc885_macpro_init_hook,
10058 },
10059 [ALC885_IMAC24] = {
10060 .mixers = { alc885_imac24_mixer },
10061 .init_verbs = { alc885_imac24_init_verbs },
10062 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10063 .dac_nids = alc882_dac_nids,
10064 .dig_out_nid = ALC882_DIGOUT_NID,
10065 .dig_in_nid = ALC882_DIGIN_NID,
10066 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10067 .channel_mode = alc882_ch_modes,
10068 .input_mux = &alc882_capture_source,
10069 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 10070 .setup = alc885_imac24_setup,
4953550a
TI
10071 .init_hook = alc885_imac24_init_hook,
10072 },
4b7e1803 10073 [ALC885_IMAC91] = {
b7cccc52 10074 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10075 .init_verbs = { alc885_imac91_init_verbs,
10076 alc880_gpio1_init_verbs },
10077 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10078 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10079 .channel_mode = alc885_mba21_ch_modes,
10080 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10081 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10082 .dig_out_nid = ALC882_DIGOUT_NID,
10083 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10084 .unsol_event = alc_automute_amp_unsol_event,
10085 .setup = alc885_imac91_setup,
10086 .init_hook = alc_automute_amp,
4b7e1803 10087 },
4953550a
TI
10088 [ALC882_TARGA] = {
10089 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10090 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10091 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10092 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10093 .dac_nids = alc882_dac_nids,
10094 .dig_out_nid = ALC882_DIGOUT_NID,
10095 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10096 .adc_nids = alc882_adc_nids,
10097 .capsrc_nids = alc882_capsrc_nids,
10098 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10099 .channel_mode = alc882_3ST_6ch_modes,
10100 .need_dac_fix = 1,
10101 .input_mux = &alc882_capture_source,
10102 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10103 .setup = alc882_targa_setup,
10104 .init_hook = alc882_targa_automute,
4953550a
TI
10105 },
10106 [ALC882_ASUS_A7J] = {
10107 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10108 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10109 alc882_asus_a7j_verbs},
4953550a
TI
10110 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10111 .dac_nids = alc882_dac_nids,
10112 .dig_out_nid = ALC882_DIGOUT_NID,
10113 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10114 .adc_nids = alc882_adc_nids,
10115 .capsrc_nids = alc882_capsrc_nids,
10116 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10117 .channel_mode = alc882_3ST_6ch_modes,
10118 .need_dac_fix = 1,
10119 .input_mux = &alc882_capture_source,
10120 },
10121 [ALC882_ASUS_A7M] = {
10122 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10123 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10124 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10125 alc882_asus_a7m_verbs },
10126 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10127 .dac_nids = alc882_dac_nids,
10128 .dig_out_nid = ALC882_DIGOUT_NID,
10129 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10130 .channel_mode = alc880_threestack_modes,
10131 .need_dac_fix = 1,
10132 .input_mux = &alc882_capture_source,
10133 },
9c7f852e
TI
10134 [ALC883_3ST_2ch_DIG] = {
10135 .mixers = { alc883_3ST_2ch_mixer },
10136 .init_verbs = { alc883_init_verbs },
10137 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10138 .dac_nids = alc883_dac_nids,
10139 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10140 .dig_in_nid = ALC883_DIGIN_NID,
10141 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10142 .channel_mode = alc883_3ST_2ch_modes,
10143 .input_mux = &alc883_capture_source,
10144 },
10145 [ALC883_3ST_6ch_DIG] = {
10146 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10147 .init_verbs = { alc883_init_verbs },
10148 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10149 .dac_nids = alc883_dac_nids,
10150 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10151 .dig_in_nid = ALC883_DIGIN_NID,
10152 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10153 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10154 .need_dac_fix = 1,
9c7f852e 10155 .input_mux = &alc883_capture_source,
f12ab1e0 10156 },
9c7f852e
TI
10157 [ALC883_3ST_6ch] = {
10158 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10159 .init_verbs = { alc883_init_verbs },
10160 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10161 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10162 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10163 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10164 .need_dac_fix = 1,
9c7f852e 10165 .input_mux = &alc883_capture_source,
f12ab1e0 10166 },
17bba1b7
J
10167 [ALC883_3ST_6ch_INTEL] = {
10168 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10169 .init_verbs = { alc883_init_verbs },
10170 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10171 .dac_nids = alc883_dac_nids,
10172 .dig_out_nid = ALC883_DIGOUT_NID,
10173 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10174 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10175 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10176 .channel_mode = alc883_3ST_6ch_intel_modes,
10177 .need_dac_fix = 1,
10178 .input_mux = &alc883_3stack_6ch_intel,
10179 },
87a8c370
JK
10180 [ALC889A_INTEL] = {
10181 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10182 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10183 alc_hp15_unsol_verbs },
87a8c370
JK
10184 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10185 .dac_nids = alc883_dac_nids,
10186 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10187 .adc_nids = alc889_adc_nids,
10188 .dig_out_nid = ALC883_DIGOUT_NID,
10189 .dig_in_nid = ALC883_DIGIN_NID,
10190 .slave_dig_outs = alc883_slave_dig_outs,
10191 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10192 .channel_mode = alc889_8ch_intel_modes,
10193 .capsrc_nids = alc889_capsrc_nids,
10194 .input_mux = &alc889_capture_source,
4f5d1706
TI
10195 .setup = alc889_automute_setup,
10196 .init_hook = alc_automute_amp,
6732bd0d 10197 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10198 .need_dac_fix = 1,
10199 },
10200 [ALC889_INTEL] = {
10201 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10202 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10203 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10204 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10205 .dac_nids = alc883_dac_nids,
10206 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10207 .adc_nids = alc889_adc_nids,
10208 .dig_out_nid = ALC883_DIGOUT_NID,
10209 .dig_in_nid = ALC883_DIGIN_NID,
10210 .slave_dig_outs = alc883_slave_dig_outs,
10211 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10212 .channel_mode = alc889_8ch_intel_modes,
10213 .capsrc_nids = alc889_capsrc_nids,
10214 .input_mux = &alc889_capture_source,
4f5d1706 10215 .setup = alc889_automute_setup,
6732bd0d
WF
10216 .init_hook = alc889_intel_init_hook,
10217 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10218 .need_dac_fix = 1,
10219 },
9c7f852e
TI
10220 [ALC883_6ST_DIG] = {
10221 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10222 .init_verbs = { alc883_init_verbs },
10223 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10224 .dac_nids = alc883_dac_nids,
10225 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10226 .dig_in_nid = ALC883_DIGIN_NID,
10227 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10228 .channel_mode = alc883_sixstack_modes,
10229 .input_mux = &alc883_capture_source,
10230 },
ccc656ce 10231 [ALC883_TARGA_DIG] = {
c259249f 10232 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10233 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10234 alc883_targa_verbs},
ccc656ce
KY
10235 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10236 .dac_nids = alc883_dac_nids,
10237 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10238 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10239 .channel_mode = alc883_3ST_6ch_modes,
10240 .need_dac_fix = 1,
10241 .input_mux = &alc883_capture_source,
c259249f 10242 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10243 .setup = alc882_targa_setup,
10244 .init_hook = alc882_targa_automute,
ccc656ce
KY
10245 },
10246 [ALC883_TARGA_2ch_DIG] = {
c259249f 10247 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10248 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10249 alc883_targa_verbs},
ccc656ce
KY
10250 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10251 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10252 .adc_nids = alc883_adc_nids_alt,
10253 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10254 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10255 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10256 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10257 .channel_mode = alc883_3ST_2ch_modes,
10258 .input_mux = &alc883_capture_source,
c259249f 10259 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10260 .setup = alc882_targa_setup,
10261 .init_hook = alc882_targa_automute,
ccc656ce 10262 },
64a8be74 10263 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10264 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10265 alc883_chmode_mixer },
64a8be74 10266 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10267 alc883_targa_verbs },
64a8be74
DH
10268 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10269 .dac_nids = alc883_dac_nids,
10270 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10271 .adc_nids = alc883_adc_nids_rev,
10272 .capsrc_nids = alc883_capsrc_nids_rev,
10273 .dig_out_nid = ALC883_DIGOUT_NID,
10274 .dig_in_nid = ALC883_DIGIN_NID,
10275 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10276 .channel_mode = alc883_4ST_8ch_modes,
10277 .need_dac_fix = 1,
10278 .input_mux = &alc883_capture_source,
c259249f 10279 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10280 .setup = alc882_targa_setup,
10281 .init_hook = alc882_targa_automute,
64a8be74 10282 },
bab282b9 10283 [ALC883_ACER] = {
676a9b53 10284 .mixers = { alc883_base_mixer },
bab282b9
VA
10285 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10286 * and the headphone jack. Turn this on and rely on the
10287 * standard mute methods whenever the user wants to turn
10288 * these outputs off.
10289 */
10290 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10291 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10292 .dac_nids = alc883_dac_nids,
bab282b9
VA
10293 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10294 .channel_mode = alc883_3ST_2ch_modes,
10295 .input_mux = &alc883_capture_source,
10296 },
2880a867 10297 [ALC883_ACER_ASPIRE] = {
676a9b53 10298 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10299 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10300 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10301 .dac_nids = alc883_dac_nids,
10302 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10303 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10304 .channel_mode = alc883_3ST_2ch_modes,
10305 .input_mux = &alc883_capture_source,
a9fd4f3f 10306 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10307 .setup = alc883_acer_aspire_setup,
10308 .init_hook = alc_automute_amp,
d1a991a6 10309 },
5b2d1eca 10310 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10311 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10312 alc883_chmode_mixer },
10313 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10314 alc888_acer_aspire_4930g_verbs },
10315 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10316 .dac_nids = alc883_dac_nids,
10317 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10318 .adc_nids = alc883_adc_nids_rev,
10319 .capsrc_nids = alc883_capsrc_nids_rev,
10320 .dig_out_nid = ALC883_DIGOUT_NID,
10321 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10322 .channel_mode = alc883_3ST_6ch_modes,
10323 .need_dac_fix = 1,
973b8cb0 10324 .const_channel_count = 6,
5b2d1eca 10325 .num_mux_defs =
ef8ef5fb
VP
10326 ARRAY_SIZE(alc888_2_capture_sources),
10327 .input_mux = alc888_2_capture_sources,
d2fd4b09 10328 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10329 .setup = alc888_acer_aspire_4930g_setup,
10330 .init_hook = alc_automute_amp,
d2fd4b09
TV
10331 },
10332 [ALC888_ACER_ASPIRE_6530G] = {
10333 .mixers = { alc888_acer_aspire_6530_mixer },
10334 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10335 alc888_acer_aspire_6530g_verbs },
10336 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10337 .dac_nids = alc883_dac_nids,
10338 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10339 .adc_nids = alc883_adc_nids_rev,
10340 .capsrc_nids = alc883_capsrc_nids_rev,
10341 .dig_out_nid = ALC883_DIGOUT_NID,
10342 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10343 .channel_mode = alc883_3ST_2ch_modes,
10344 .num_mux_defs =
10345 ARRAY_SIZE(alc888_2_capture_sources),
10346 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10347 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10348 .setup = alc888_acer_aspire_6530g_setup,
10349 .init_hook = alc_automute_amp,
5b2d1eca 10350 },
3b315d70 10351 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10352 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10353 alc883_chmode_mixer },
10354 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10355 alc889_acer_aspire_8930g_verbs,
10356 alc889_eapd_verbs},
3b315d70
HM
10357 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10358 .dac_nids = alc883_dac_nids,
018df418
HM
10359 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10360 .adc_nids = alc889_adc_nids,
10361 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10362 .dig_out_nid = ALC883_DIGOUT_NID,
10363 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10364 .channel_mode = alc883_3ST_6ch_modes,
10365 .need_dac_fix = 1,
10366 .const_channel_count = 6,
10367 .num_mux_defs =
018df418
HM
10368 ARRAY_SIZE(alc889_capture_sources),
10369 .input_mux = alc889_capture_sources,
3b315d70 10370 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10371 .setup = alc889_acer_aspire_8930g_setup,
10372 .init_hook = alc_automute_amp,
f5de24b0 10373#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10374 .power_hook = alc_power_eapd,
f5de24b0 10375#endif
3b315d70 10376 },
fc86f954
DK
10377 [ALC888_ACER_ASPIRE_7730G] = {
10378 .mixers = { alc883_3ST_6ch_mixer,
10379 alc883_chmode_mixer },
10380 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10381 alc888_acer_aspire_7730G_verbs },
10382 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10383 .dac_nids = alc883_dac_nids,
10384 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10385 .adc_nids = alc883_adc_nids_rev,
10386 .capsrc_nids = alc883_capsrc_nids_rev,
10387 .dig_out_nid = ALC883_DIGOUT_NID,
10388 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10389 .channel_mode = alc883_3ST_6ch_modes,
10390 .need_dac_fix = 1,
10391 .const_channel_count = 6,
10392 .input_mux = &alc883_capture_source,
10393 .unsol_event = alc_automute_amp_unsol_event,
d9477207 10394 .setup = alc888_acer_aspire_7730g_setup,
fc86f954
DK
10395 .init_hook = alc_automute_amp,
10396 },
c07584c8
TD
10397 [ALC883_MEDION] = {
10398 .mixers = { alc883_fivestack_mixer,
10399 alc883_chmode_mixer },
10400 .init_verbs = { alc883_init_verbs,
b373bdeb 10401 alc883_medion_eapd_verbs },
c07584c8
TD
10402 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10403 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10404 .adc_nids = alc883_adc_nids_alt,
10405 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10406 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10407 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10408 .channel_mode = alc883_sixstack_modes,
10409 .input_mux = &alc883_capture_source,
b373bdeb 10410 },
7ad7b218
MC
10411 [ALC883_MEDION_WIM2160] = {
10412 .mixers = { alc883_medion_wim2160_mixer },
10413 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10414 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10415 .dac_nids = alc883_dac_nids,
10416 .dig_out_nid = ALC883_DIGOUT_NID,
10417 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10418 .adc_nids = alc883_adc_nids,
10419 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10420 .channel_mode = alc883_3ST_2ch_modes,
10421 .input_mux = &alc883_capture_source,
10422 .unsol_event = alc_automute_amp_unsol_event,
10423 .setup = alc883_medion_wim2160_setup,
10424 .init_hook = alc_automute_amp,
10425 },
b373bdeb 10426 [ALC883_LAPTOP_EAPD] = {
676a9b53 10427 .mixers = { alc883_base_mixer },
b373bdeb
AN
10428 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10429 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10430 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10431 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10432 .channel_mode = alc883_3ST_2ch_modes,
10433 .input_mux = &alc883_capture_source,
10434 },
a65cc60f 10435 [ALC883_CLEVO_M540R] = {
10436 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10437 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10438 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10439 .dac_nids = alc883_dac_nids,
10440 .dig_out_nid = ALC883_DIGOUT_NID,
10441 .dig_in_nid = ALC883_DIGIN_NID,
10442 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10443 .channel_mode = alc883_3ST_6ch_clevo_modes,
10444 .need_dac_fix = 1,
10445 .input_mux = &alc883_capture_source,
10446 /* This machine has the hardware HP auto-muting, thus
10447 * we need no software mute via unsol event
10448 */
10449 },
0c4cc443
HRK
10450 [ALC883_CLEVO_M720] = {
10451 .mixers = { alc883_clevo_m720_mixer },
10452 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10453 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10454 .dac_nids = alc883_dac_nids,
10455 .dig_out_nid = ALC883_DIGOUT_NID,
10456 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10457 .channel_mode = alc883_3ST_2ch_modes,
10458 .input_mux = &alc883_capture_source,
0c4cc443 10459 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10460 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10461 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10462 },
bc9f98a9
KY
10463 [ALC883_LENOVO_101E_2ch] = {
10464 .mixers = { alc883_lenovo_101e_2ch_mixer},
10465 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10466 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10467 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10468 .adc_nids = alc883_adc_nids_alt,
10469 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10470 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10471 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10472 .channel_mode = alc883_3ST_2ch_modes,
10473 .input_mux = &alc883_lenovo_101e_capture_source,
10474 .unsol_event = alc883_lenovo_101e_unsol_event,
10475 .init_hook = alc883_lenovo_101e_all_automute,
10476 },
272a527c
KY
10477 [ALC883_LENOVO_NB0763] = {
10478 .mixers = { alc883_lenovo_nb0763_mixer },
10479 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10480 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10481 .dac_nids = alc883_dac_nids,
272a527c
KY
10482 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10483 .channel_mode = alc883_3ST_2ch_modes,
10484 .need_dac_fix = 1,
10485 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10486 .unsol_event = alc_automute_amp_unsol_event,
dc427170 10487 .setup = alc883_lenovo_nb0763_setup,
4f5d1706 10488 .init_hook = alc_automute_amp,
272a527c
KY
10489 },
10490 [ALC888_LENOVO_MS7195_DIG] = {
10491 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10492 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10493 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10494 .dac_nids = alc883_dac_nids,
10495 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10496 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10497 .channel_mode = alc883_3ST_6ch_modes,
10498 .need_dac_fix = 1,
10499 .input_mux = &alc883_capture_source,
10500 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10501 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10502 },
10503 [ALC883_HAIER_W66] = {
c259249f 10504 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10505 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10506 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10507 .dac_nids = alc883_dac_nids,
10508 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10509 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10510 .channel_mode = alc883_3ST_2ch_modes,
10511 .input_mux = &alc883_capture_source,
a9fd4f3f 10512 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10513 .setup = alc883_haier_w66_setup,
10514 .init_hook = alc_automute_amp,
eea6419e 10515 },
4723c022 10516 [ALC888_3ST_HP] = {
eea6419e 10517 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10518 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10519 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10520 .dac_nids = alc883_dac_nids,
4723c022
CM
10521 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10522 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10523 .need_dac_fix = 1,
10524 .input_mux = &alc883_capture_source,
a9fd4f3f 10525 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10526 .setup = alc888_3st_hp_setup,
10527 .init_hook = alc_automute_amp,
8341de60 10528 },
5795b9e6 10529 [ALC888_6ST_DELL] = {
f24dbdc6 10530 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10531 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10532 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10533 .dac_nids = alc883_dac_nids,
10534 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10535 .dig_in_nid = ALC883_DIGIN_NID,
10536 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10537 .channel_mode = alc883_sixstack_modes,
10538 .input_mux = &alc883_capture_source,
a9fd4f3f 10539 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10540 .setup = alc888_6st_dell_setup,
10541 .init_hook = alc_automute_amp,
5795b9e6 10542 },
a8848bd6
AS
10543 [ALC883_MITAC] = {
10544 .mixers = { alc883_mitac_mixer },
10545 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10547 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10548 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10549 .channel_mode = alc883_3ST_2ch_modes,
10550 .input_mux = &alc883_capture_source,
a9fd4f3f 10551 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10552 .setup = alc883_mitac_setup,
10553 .init_hook = alc_automute_amp,
a8848bd6 10554 },
fb97dc67
J
10555 [ALC883_FUJITSU_PI2515] = {
10556 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10557 .init_verbs = { alc883_init_verbs,
10558 alc883_2ch_fujitsu_pi2515_verbs},
10559 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10560 .dac_nids = alc883_dac_nids,
10561 .dig_out_nid = ALC883_DIGOUT_NID,
10562 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10563 .channel_mode = alc883_3ST_2ch_modes,
10564 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10565 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10566 .setup = alc883_2ch_fujitsu_pi2515_setup,
10567 .init_hook = alc_automute_amp,
fb97dc67 10568 },
ef8ef5fb
VP
10569 [ALC888_FUJITSU_XA3530] = {
10570 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10571 .init_verbs = { alc883_init_verbs,
10572 alc888_fujitsu_xa3530_verbs },
10573 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10574 .dac_nids = alc883_dac_nids,
10575 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10576 .adc_nids = alc883_adc_nids_rev,
10577 .capsrc_nids = alc883_capsrc_nids_rev,
10578 .dig_out_nid = ALC883_DIGOUT_NID,
10579 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10580 .channel_mode = alc888_4ST_8ch_intel_modes,
10581 .num_mux_defs =
10582 ARRAY_SIZE(alc888_2_capture_sources),
10583 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10584 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10585 .setup = alc888_fujitsu_xa3530_setup,
10586 .init_hook = alc_automute_amp,
ef8ef5fb 10587 },
e2757d5e
KY
10588 [ALC888_LENOVO_SKY] = {
10589 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10590 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10591 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10592 .dac_nids = alc883_dac_nids,
10593 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10594 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10595 .channel_mode = alc883_sixstack_modes,
10596 .need_dac_fix = 1,
10597 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10598 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10599 .setup = alc888_lenovo_sky_setup,
10600 .init_hook = alc_automute_amp,
e2757d5e
KY
10601 },
10602 [ALC888_ASUS_M90V] = {
10603 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10604 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10605 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10606 .dac_nids = alc883_dac_nids,
10607 .dig_out_nid = ALC883_DIGOUT_NID,
10608 .dig_in_nid = ALC883_DIGIN_NID,
10609 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10610 .channel_mode = alc883_3ST_6ch_modes,
10611 .need_dac_fix = 1,
10612 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10613 .unsol_event = alc_sku_unsol_event,
10614 .setup = alc883_mode2_setup,
10615 .init_hook = alc_inithook,
e2757d5e
KY
10616 },
10617 [ALC888_ASUS_EEE1601] = {
10618 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10619 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10620 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10621 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10622 .dac_nids = alc883_dac_nids,
10623 .dig_out_nid = ALC883_DIGOUT_NID,
10624 .dig_in_nid = ALC883_DIGIN_NID,
10625 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10626 .channel_mode = alc883_3ST_2ch_modes,
10627 .need_dac_fix = 1,
10628 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10629 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10630 .init_hook = alc883_eee1601_inithook,
10631 },
3ab90935
WF
10632 [ALC1200_ASUS_P5Q] = {
10633 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10634 .init_verbs = { alc883_init_verbs },
10635 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10636 .dac_nids = alc883_dac_nids,
10637 .dig_out_nid = ALC1200_DIGOUT_NID,
10638 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10639 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10640 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10641 .channel_mode = alc883_sixstack_modes,
10642 .input_mux = &alc883_capture_source,
10643 },
eb4c41d3
TS
10644 [ALC889A_MB31] = {
10645 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10646 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10647 alc880_gpio1_init_verbs },
10648 .adc_nids = alc883_adc_nids,
10649 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10650 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10651 .dac_nids = alc883_dac_nids,
10652 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10653 .channel_mode = alc889A_mb31_6ch_modes,
10654 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10655 .input_mux = &alc889A_mb31_capture_source,
10656 .dig_out_nid = ALC883_DIGOUT_NID,
10657 .unsol_event = alc889A_mb31_unsol_event,
10658 .init_hook = alc889A_mb31_automute,
10659 },
3e1647c5
GG
10660 [ALC883_SONY_VAIO_TT] = {
10661 .mixers = { alc883_vaiott_mixer },
10662 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10663 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10664 .dac_nids = alc883_dac_nids,
10665 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10666 .channel_mode = alc883_3ST_2ch_modes,
10667 .input_mux = &alc883_capture_source,
10668 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10669 .setup = alc883_vaiott_setup,
10670 .init_hook = alc_automute_amp,
3e1647c5 10671 },
9c7f852e
TI
10672};
10673
10674
4953550a
TI
10675/*
10676 * Pin config fixes
10677 */
10678enum {
954a29c8
TI
10679 PINFIX_ABIT_AW9D_MAX,
10680 PINFIX_PB_M5210,
c3d226ab 10681 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10682};
10683
f8f25ba3
TI
10684static const struct alc_fixup alc882_fixups[] = {
10685 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10686 .type = ALC_FIXUP_PINS,
10687 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10688 { 0x15, 0x01080104 }, /* side */
10689 { 0x16, 0x01011012 }, /* rear */
10690 { 0x17, 0x01016011 }, /* clfe */
10691 { }
10692 }
f8f25ba3 10693 },
954a29c8 10694 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10695 .type = ALC_FIXUP_VERBS,
10696 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10697 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10698 {}
10699 }
954a29c8 10700 },
c3d226ab 10701 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10702 .type = ALC_FIXUP_SKU,
10703 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10704 },
4953550a
TI
10705};
10706
f8f25ba3 10707static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10708 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a 10709 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10710 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10711 {}
10712};
10713
9c7f852e
TI
10714/*
10715 * BIOS auto configuration
10716 */
05f5f477
TI
10717static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10718 const struct auto_pin_cfg *cfg)
10719{
10720 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10721}
10722
4953550a 10723static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10724 hda_nid_t nid, int pin_type,
489008cd 10725 hda_nid_t dac)
9c7f852e 10726{
f12ab1e0
TI
10727 int idx;
10728
489008cd 10729 /* set as output */
f6c7e546 10730 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10731
10732 if (dac == 0x25)
9c7f852e 10733 idx = 4;
489008cd
TI
10734 else if (dac >= 0x02 && dac <= 0x05)
10735 idx = dac - 2;
f9700d5a 10736 else
489008cd 10737 return;
9c7f852e 10738 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10739}
10740
4953550a 10741static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10742{
10743 struct alc_spec *spec = codec->spec;
10744 int i;
10745
10746 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10747 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10748 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10749 if (nid)
4953550a 10750 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10751 spec->multiout.dac_nids[i]);
9c7f852e
TI
10752 }
10753}
10754
4953550a 10755static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10756{
10757 struct alc_spec *spec = codec->spec;
489008cd 10758 hda_nid_t pin, dac;
5855fb80 10759 int i;
9c7f852e 10760
5855fb80
TI
10761 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10762 pin = spec->autocfg.hp_pins[i];
10763 if (!pin)
10764 break;
489008cd
TI
10765 dac = spec->multiout.hp_nid;
10766 if (!dac)
10767 dac = spec->multiout.dac_nids[0]; /* to front */
10768 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10769 }
5855fb80
TI
10770 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10771 pin = spec->autocfg.speaker_pins[i];
10772 if (!pin)
10773 break;
489008cd
TI
10774 dac = spec->multiout.extra_out_nid[0];
10775 if (!dac)
10776 dac = spec->multiout.dac_nids[0]; /* to front */
10777 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10778 }
9c7f852e
TI
10779}
10780
4953550a 10781static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10782{
10783 struct alc_spec *spec = codec->spec;
66ceeb6b 10784 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10785 int i;
10786
66ceeb6b
TI
10787 for (i = 0; i < cfg->num_inputs; i++) {
10788 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10789 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10790 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10791 snd_hda_codec_write(codec, nid, 0,
10792 AC_VERB_SET_AMP_GAIN_MUTE,
10793 AMP_OUT_MUTE);
10794 }
10795}
10796
10797static void alc882_auto_init_input_src(struct hda_codec *codec)
10798{
10799 struct alc_spec *spec = codec->spec;
10800 int c;
10801
10802 for (c = 0; c < spec->num_adc_nids; c++) {
10803 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10804 hda_nid_t nid = spec->capsrc_nids[c];
10805 unsigned int mux_idx;
10806 const struct hda_input_mux *imux;
10807 int conns, mute, idx, item;
10808
10809 conns = snd_hda_get_connections(codec, nid, conn_list,
10810 ARRAY_SIZE(conn_list));
10811 if (conns < 0)
10812 continue;
10813 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10814 imux = &spec->input_mux[mux_idx];
5311114d
TI
10815 if (!imux->num_items && mux_idx > 0)
10816 imux = &spec->input_mux[0];
4953550a
TI
10817 for (idx = 0; idx < conns; idx++) {
10818 /* if the current connection is the selected one,
10819 * unmute it as default - otherwise mute it
10820 */
10821 mute = AMP_IN_MUTE(idx);
10822 for (item = 0; item < imux->num_items; item++) {
10823 if (imux->items[item].index == idx) {
10824 if (spec->cur_mux[c] == item)
10825 mute = AMP_IN_UNMUTE(idx);
10826 break;
10827 }
10828 }
10829 /* check if we have a selector or mixer
10830 * we could check for the widget type instead, but
10831 * just check for Amp-In presence (in case of mixer
10832 * without amp-in there is something wrong, this
10833 * function shouldn't be used or capsrc nid is wrong)
10834 */
10835 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10836 snd_hda_codec_write(codec, nid, 0,
10837 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10838 mute);
10839 else if (mute != AMP_IN_MUTE(idx))
10840 snd_hda_codec_write(codec, nid, 0,
10841 AC_VERB_SET_CONNECT_SEL,
10842 idx);
9c7f852e
TI
10843 }
10844 }
10845}
10846
4953550a
TI
10847/* add mic boosts if needed */
10848static int alc_auto_add_mic_boost(struct hda_codec *codec)
10849{
10850 struct alc_spec *spec = codec->spec;
66ceeb6b 10851 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10852 int i, err;
53e8c323 10853 int type_idx = 0;
4953550a 10854 hda_nid_t nid;
5322bf27 10855 const char *prev_label = NULL;
4953550a 10856
66ceeb6b 10857 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10858 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10859 break;
10860 nid = cfg->inputs[i].pin;
10861 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10862 const char *label;
10863 char boost_label[32];
10864
10865 label = hda_get_autocfg_input_label(codec, cfg, i);
10866 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10867 type_idx++;
10868 else
10869 type_idx = 0;
5322bf27
DH
10870 prev_label = label;
10871
10872 snprintf(boost_label, sizeof(boost_label),
10873 "%s Boost Volume", label);
10874 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10875 boost_label, type_idx,
4953550a 10876 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10877 if (err < 0)
10878 return err;
10879 }
4953550a
TI
10880 }
10881 return 0;
10882}
f511b01c 10883
9c7f852e 10884/* almost identical with ALC880 parser... */
4953550a 10885static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10886{
10887 struct alc_spec *spec = codec->spec;
05f5f477 10888 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10889 int err;
9c7f852e 10890
05f5f477
TI
10891 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10892 alc882_ignore);
9c7f852e
TI
10893 if (err < 0)
10894 return err;
05f5f477
TI
10895 if (!spec->autocfg.line_outs)
10896 return 0; /* can't find valid BIOS pin config */
776e184e 10897
05f5f477
TI
10898 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10899 if (err < 0)
10900 return err;
569ed348 10901 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10902 if (err < 0)
10903 return err;
10904 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10905 "Headphone");
05f5f477
TI
10906 if (err < 0)
10907 return err;
10908 err = alc880_auto_create_extra_out(spec,
10909 spec->autocfg.speaker_pins[0],
10910 "Speaker");
10911 if (err < 0)
10912 return err;
05f5f477 10913 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10914 if (err < 0)
10915 return err;
10916
05f5f477
TI
10917 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10918
757899ac 10919 alc_auto_parse_digital(codec);
05f5f477
TI
10920
10921 if (spec->kctls.list)
10922 add_mixer(spec, spec->kctls.list);
10923
10924 add_verb(spec, alc883_auto_init_verbs);
4953550a 10925 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10926 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10927 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10928
05f5f477
TI
10929 spec->num_mux_defs = 1;
10930 spec->input_mux = &spec->private_imux[0];
10931
6227cdce 10932 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10933
10934 err = alc_auto_add_mic_boost(codec);
10935 if (err < 0)
10936 return err;
61b9b9b1 10937
776e184e 10938 return 1; /* config found */
9c7f852e
TI
10939}
10940
10941/* additional initialization for auto-configuration model */
4953550a 10942static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10943{
f6c7e546 10944 struct alc_spec *spec = codec->spec;
4953550a
TI
10945 alc882_auto_init_multi_out(codec);
10946 alc882_auto_init_hp_out(codec);
10947 alc882_auto_init_analog_input(codec);
10948 alc882_auto_init_input_src(codec);
757899ac 10949 alc_auto_init_digital(codec);
f6c7e546 10950 if (spec->unsol_event)
7fb0d78f 10951 alc_inithook(codec);
9c7f852e
TI
10952}
10953
4953550a 10954static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10955{
10956 struct alc_spec *spec;
10957 int err, board_config;
10958
10959 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10960 if (spec == NULL)
10961 return -ENOMEM;
10962
10963 codec->spec = spec;
10964
4953550a
TI
10965 switch (codec->vendor_id) {
10966 case 0x10ec0882:
10967 case 0x10ec0885:
10968 break;
10969 default:
10970 /* ALC883 and variants */
10971 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10972 break;
10973 }
2c3bf9ab 10974
4953550a
TI
10975 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10976 alc882_models,
10977 alc882_cfg_tbl);
10978
10979 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10980 board_config = snd_hda_check_board_codec_sid_config(codec,
10981 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10982
10983 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10984 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10985 codec->chip_name);
10986 board_config = ALC882_AUTO;
9c7f852e
TI
10987 }
10988
b5bfbc67
TI
10989 if (board_config == ALC882_AUTO) {
10990 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
10991 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
10992 }
4953550a 10993
90622917
DH
10994 alc_auto_parse_customize_define(codec);
10995
4953550a 10996 if (board_config == ALC882_AUTO) {
9c7f852e 10997 /* automatic parse from the BIOS config */
4953550a 10998 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10999 if (err < 0) {
11000 alc_free(codec);
11001 return err;
f12ab1e0 11002 } else if (!err) {
9c7f852e
TI
11003 printk(KERN_INFO
11004 "hda_codec: Cannot set up configuration "
11005 "from BIOS. Using base mode...\n");
4953550a 11006 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11007 }
11008 }
11009
dc1eae25 11010 if (has_cdefine_beep(codec)) {
8af2591d
TI
11011 err = snd_hda_attach_beep_device(codec, 0x1);
11012 if (err < 0) {
11013 alc_free(codec);
11014 return err;
11015 }
680cd536
KK
11016 }
11017
4953550a 11018 if (board_config != ALC882_AUTO)
e9c364c0 11019 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11020
4953550a
TI
11021 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11022 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11023 /* FIXME: setup DAC5 */
11024 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11025 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11026
11027 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11028 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11029
4953550a 11030 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11031 int i, j;
4953550a
TI
11032 spec->num_adc_nids = 0;
11033 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11034 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11035 hda_nid_t cap;
d11f74c6 11036 hda_nid_t items[16];
4953550a
TI
11037 hda_nid_t nid = alc882_adc_nids[i];
11038 unsigned int wcap = get_wcaps(codec, nid);
11039 /* get type */
a22d543a 11040 wcap = get_wcaps_type(wcap);
4953550a
TI
11041 if (wcap != AC_WID_AUD_IN)
11042 continue;
11043 spec->private_adc_nids[spec->num_adc_nids] = nid;
11044 err = snd_hda_get_connections(codec, nid, &cap, 1);
11045 if (err < 0)
11046 continue;
d11f74c6
TI
11047 err = snd_hda_get_connections(codec, cap, items,
11048 ARRAY_SIZE(items));
11049 if (err < 0)
11050 continue;
11051 for (j = 0; j < imux->num_items; j++)
11052 if (imux->items[j].index >= err)
11053 break;
11054 if (j < imux->num_items)
11055 continue;
4953550a
TI
11056 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11057 spec->num_adc_nids++;
61b9b9b1 11058 }
4953550a
TI
11059 spec->adc_nids = spec->private_adc_nids;
11060 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11061 }
11062
b59bdf3b 11063 set_capture_mixer(codec);
da00c244 11064
dc1eae25 11065 if (has_cdefine_beep(codec))
da00c244 11066 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11067
b5bfbc67 11068 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11069
2134ea4f
TI
11070 spec->vmaster_nid = 0x0c;
11071
9c7f852e 11072 codec->patch_ops = alc_patch_ops;
4953550a
TI
11073 if (board_config == ALC882_AUTO)
11074 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11075
11076 alc_init_jacks(codec);
cb53c626
TI
11077#ifdef CONFIG_SND_HDA_POWER_SAVE
11078 if (!spec->loopback.amplist)
4953550a 11079 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11080#endif
9c7f852e
TI
11081
11082 return 0;
11083}
11084
4953550a 11085
9c7f852e
TI
11086/*
11087 * ALC262 support
11088 */
11089
11090#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11091#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11092
11093#define alc262_dac_nids alc260_dac_nids
11094#define alc262_adc_nids alc882_adc_nids
11095#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11096#define alc262_capsrc_nids alc882_capsrc_nids
11097#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11098
11099#define alc262_modes alc260_modes
11100#define alc262_capture_source alc882_capture_source
11101
4e555fe5
KY
11102static hda_nid_t alc262_dmic_adc_nids[1] = {
11103 /* ADC0 */
11104 0x09
11105};
11106
11107static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11108
9c7f852e
TI
11109static struct snd_kcontrol_new alc262_base_mixer[] = {
11110 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11111 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11112 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11113 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11114 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11115 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11117 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11118 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11119 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11120 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11121 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11122 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11123 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11124 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11125 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11126 { } /* end */
11127};
11128
ce875f07
TI
11129/* update HP, line and mono-out pins according to the master switch */
11130static void alc262_hp_master_update(struct hda_codec *codec)
11131{
11132 struct alc_spec *spec = codec->spec;
11133 int val = spec->master_sw;
11134
11135 /* HP & line-out */
11136 snd_hda_codec_write_cache(codec, 0x1b, 0,
11137 AC_VERB_SET_PIN_WIDGET_CONTROL,
11138 val ? PIN_HP : 0);
11139 snd_hda_codec_write_cache(codec, 0x15, 0,
11140 AC_VERB_SET_PIN_WIDGET_CONTROL,
11141 val ? PIN_HP : 0);
11142 /* mono (speaker) depending on the HP jack sense */
11143 val = val && !spec->jack_present;
11144 snd_hda_codec_write_cache(codec, 0x16, 0,
11145 AC_VERB_SET_PIN_WIDGET_CONTROL,
11146 val ? PIN_OUT : 0);
11147}
11148
11149static void alc262_hp_bpc_automute(struct hda_codec *codec)
11150{
11151 struct alc_spec *spec = codec->spec;
864f92be
WF
11152
11153 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11154 alc262_hp_master_update(codec);
11155}
11156
11157static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11158{
11159 if ((res >> 26) != ALC880_HP_EVENT)
11160 return;
11161 alc262_hp_bpc_automute(codec);
11162}
11163
11164static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11165{
11166 struct alc_spec *spec = codec->spec;
864f92be
WF
11167
11168 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11169 alc262_hp_master_update(codec);
11170}
11171
11172static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11173 unsigned int res)
11174{
11175 if ((res >> 26) != ALC880_HP_EVENT)
11176 return;
11177 alc262_hp_wildwest_automute(codec);
11178}
11179
b72519b5 11180#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11181
11182static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11183 struct snd_ctl_elem_value *ucontrol)
11184{
11185 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11186 struct alc_spec *spec = codec->spec;
11187 int val = !!*ucontrol->value.integer.value;
11188
11189 if (val == spec->master_sw)
11190 return 0;
11191 spec->master_sw = val;
11192 alc262_hp_master_update(codec);
11193 return 1;
11194}
11195
b72519b5
TI
11196#define ALC262_HP_MASTER_SWITCH \
11197 { \
11198 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11199 .name = "Master Playback Switch", \
11200 .info = snd_ctl_boolean_mono_info, \
11201 .get = alc262_hp_master_sw_get, \
11202 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11203 }, \
11204 { \
11205 .iface = NID_MAPPING, \
11206 .name = "Master Playback Switch", \
11207 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11208 }
11209
5b0cb1d8 11210
9c7f852e 11211static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11212 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11213 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11214 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11216 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11217 HDA_OUTPUT),
11218 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11219 HDA_OUTPUT),
9c7f852e
TI
11220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11221 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11222 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11223 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11224 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11225 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11226 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11227 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11228 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11229 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11230 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11231 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11232 { } /* end */
11233};
11234
cd7509a4 11235static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11236 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11237 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11238 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11239 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11240 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11241 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11242 HDA_OUTPUT),
11243 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11244 HDA_OUTPUT),
cd7509a4
KY
11245 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11246 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11247 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11248 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11249 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11250 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11251 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11252 { } /* end */
11253};
11254
11255static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11256 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11257 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11258 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11259 { } /* end */
11260};
11261
66d2a9d6 11262/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11263static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11264{
11265 struct alc_spec *spec = codec->spec;
66d2a9d6 11266
a9fd4f3f 11267 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11268 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11269}
11270
66d2a9d6 11271static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11272 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11273 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11274 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11276 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11277 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11278 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11279 { } /* end */
11280};
11281
11282static struct hda_verb alc262_hp_t5735_verbs[] = {
11283 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11284 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11285
11286 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11287 { }
11288};
11289
8c427226 11290static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11291 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11292 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11293 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11294 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11295 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11296 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11297 { } /* end */
11298};
11299
11300static struct hda_verb alc262_hp_rp5700_verbs[] = {
11301 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11302 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11303 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11304 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11305 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11306 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11308 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11310 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11311 {}
11312};
11313
11314static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11315 .num_items = 1,
11316 .items = {
11317 { "Line", 0x1 },
11318 },
11319};
11320
42171c17
TI
11321/* bind hp and internal speaker mute (with plug check) as master switch */
11322static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11323{
42171c17
TI
11324 struct alc_spec *spec = codec->spec;
11325 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11326 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11327 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11328 unsigned int mute;
0724ea2a 11329
42171c17
TI
11330 /* HP */
11331 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11332 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11333 HDA_AMP_MUTE, mute);
11334 /* mute internal speaker per jack sense */
11335 if (spec->jack_present)
11336 mute = HDA_AMP_MUTE;
11337 if (line_nid)
11338 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11339 HDA_AMP_MUTE, mute);
11340 if (speaker_nid && speaker_nid != line_nid)
11341 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11342 HDA_AMP_MUTE, mute);
42171c17
TI
11343}
11344
11345#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11346
11347static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11348 struct snd_ctl_elem_value *ucontrol)
11349{
11350 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11351 struct alc_spec *spec = codec->spec;
11352 int val = !!*ucontrol->value.integer.value;
11353
11354 if (val == spec->master_sw)
11355 return 0;
11356 spec->master_sw = val;
11357 alc262_hippo_master_update(codec);
11358 return 1;
11359}
11360
11361#define ALC262_HIPPO_MASTER_SWITCH \
11362 { \
11363 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11364 .name = "Master Playback Switch", \
11365 .info = snd_ctl_boolean_mono_info, \
11366 .get = alc262_hippo_master_sw_get, \
11367 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11368 }, \
11369 { \
11370 .iface = NID_MAPPING, \
11371 .name = "Master Playback Switch", \
11372 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11373 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11374 }
42171c17
TI
11375
11376static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11377 ALC262_HIPPO_MASTER_SWITCH,
11378 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11379 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11380 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11381 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11382 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11383 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11385 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11386 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11387 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11388 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11389 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11390 { } /* end */
11391};
11392
11393static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11394 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11395 ALC262_HIPPO_MASTER_SWITCH,
11396 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11397 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11398 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11399 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11400 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11401 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11402 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11403 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11404 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11405 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11406 { } /* end */
11407};
11408
11409/* mute/unmute internal speaker according to the hp jack and mute state */
11410static void alc262_hippo_automute(struct hda_codec *codec)
11411{
11412 struct alc_spec *spec = codec->spec;
11413 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11414
864f92be 11415 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11416 alc262_hippo_master_update(codec);
0724ea2a 11417}
5b31954e 11418
42171c17
TI
11419static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11420{
11421 if ((res >> 26) != ALC880_HP_EVENT)
11422 return;
11423 alc262_hippo_automute(codec);
11424}
11425
4f5d1706 11426static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11427{
11428 struct alc_spec *spec = codec->spec;
11429
11430 spec->autocfg.hp_pins[0] = 0x15;
11431 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11432}
11433
4f5d1706 11434static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11435{
11436 struct alc_spec *spec = codec->spec;
11437
11438 spec->autocfg.hp_pins[0] = 0x1b;
11439 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11440}
11441
11442
272a527c 11443static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11444 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11445 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11448 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11449 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11450 { } /* end */
11451};
11452
83c34218 11453static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11454 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11455 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11456 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11458 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11459 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11460 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11461 { } /* end */
11462};
272a527c 11463
ba340e82
TV
11464static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11465 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11466 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11467 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11468 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11469 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11470 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11472 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11473 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11474 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11475 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11476 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11477 { } /* end */
11478};
11479
11480static struct hda_verb alc262_tyan_verbs[] = {
11481 /* Headphone automute */
11482 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11483 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11484 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11485
11486 /* P11 AUX_IN, white 4-pin connector */
11487 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11488 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11489 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11490 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11491
11492 {}
11493};
11494
11495/* unsolicited event for HP jack sensing */
4f5d1706 11496static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11497{
a9fd4f3f 11498 struct alc_spec *spec = codec->spec;
ba340e82 11499
a9fd4f3f
TI
11500 spec->autocfg.hp_pins[0] = 0x1b;
11501 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11502}
11503
ba340e82 11504
9c7f852e
TI
11505#define alc262_capture_mixer alc882_capture_mixer
11506#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11507
11508/*
11509 * generic initialization of ADC, input mixers and output mixers
11510 */
11511static struct hda_verb alc262_init_verbs[] = {
11512 /*
11513 * Unmute ADC0-2 and set the default input to mic-in
11514 */
11515 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11517 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11518 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11519 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11520 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11521
cb53c626 11522 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11523 * mixer widget
f12ab1e0
TI
11524 * Note: PASD motherboards uses the Line In 2 as the input for
11525 * front panel mic (mic 2)
9c7f852e
TI
11526 */
11527 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11528 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11529 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11530 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11531 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11532 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11533
11534 /*
df694daa
KY
11535 * Set up output mixers (0x0c - 0x0e)
11536 */
11537 /* set vol=0 to output mixers */
11538 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11539 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11540 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11541 /* set up input amps for analog loopback */
11542 /* Amp Indices: DAC = 0, mixer = 1 */
11543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11546 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11547 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11548 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11549
11550 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11551 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11552 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11553 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11554 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11555 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11556
11557 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11559 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11560 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11561 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11562
df694daa
KY
11563 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11564 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11565
df694daa
KY
11566 /* FIXME: use matrix-type input source selection */
11567 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11568 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11569 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11570 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11571 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11572 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11573 /* Input mixer2 */
11574 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11575 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11576 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11577 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11578 /* Input mixer3 */
11579 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11580 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11581 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11582 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11583
11584 { }
11585};
1da177e4 11586
4e555fe5
KY
11587static struct hda_verb alc262_eapd_verbs[] = {
11588 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11589 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11590 { }
11591};
11592
ccc656ce
KY
11593static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11594 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11595 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11596 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11597
11598 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11599 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11600 {}
11601};
11602
272a527c
KY
11603static struct hda_verb alc262_sony_unsol_verbs[] = {
11604 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11605 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11606 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11607
11608 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11610 {}
272a527c
KY
11611};
11612
4e555fe5
KY
11613static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11614 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11615 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11618 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11619 { } /* end */
11620};
11621
11622static struct hda_verb alc262_toshiba_s06_verbs[] = {
11623 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11624 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11626 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11627 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11628 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11629 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11630 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11631 {}
11632};
11633
4f5d1706 11634static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11635{
a9fd4f3f
TI
11636 struct alc_spec *spec = codec->spec;
11637
11638 spec->autocfg.hp_pins[0] = 0x15;
11639 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11640 spec->ext_mic.pin = 0x18;
11641 spec->ext_mic.mux_idx = 0;
11642 spec->int_mic.pin = 0x12;
11643 spec->int_mic.mux_idx = 9;
11644 spec->auto_mic = 1;
4e555fe5
KY
11645}
11646
e8f9ae2a
PT
11647/*
11648 * nec model
11649 * 0x15 = headphone
11650 * 0x16 = internal speaker
11651 * 0x18 = external mic
11652 */
11653
11654static struct snd_kcontrol_new alc262_nec_mixer[] = {
11655 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11656 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11657
11658 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11659 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11660 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11661
11662 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11663 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11664 { } /* end */
11665};
11666
11667static struct hda_verb alc262_nec_verbs[] = {
11668 /* Unmute Speaker */
11669 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11670
11671 /* Headphone */
11672 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11673 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11674
11675 /* External mic to headphone */
11676 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11677 /* External mic to speaker */
11678 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11679 {}
11680};
11681
834be88d
TI
11682/*
11683 * fujitsu model
5d9fab2d
TV
11684 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11685 * 0x1b = port replicator headphone out
834be88d
TI
11686 */
11687
11688#define ALC_HP_EVENT 0x37
11689
11690static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11691 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11692 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11693 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11694 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11695 {}
11696};
11697
0e31daf7
J
11698static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11699 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11700 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11701 {}
11702};
11703
e2595322
DC
11704static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11705 /* Front Mic pin: input vref at 50% */
11706 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11707 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11708 {}
11709};
11710
834be88d 11711static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11712 .num_items = 3,
834be88d
TI
11713 .items = {
11714 { "Mic", 0x0 },
28c4edb7 11715 { "Internal Mic", 0x1 },
834be88d
TI
11716 { "CD", 0x4 },
11717 },
11718};
11719
9c7f852e
TI
11720static struct hda_input_mux alc262_HP_capture_source = {
11721 .num_items = 5,
11722 .items = {
11723 { "Mic", 0x0 },
accbe498 11724 { "Front Mic", 0x1 },
9c7f852e
TI
11725 { "Line", 0x2 },
11726 { "CD", 0x4 },
11727 { "AUX IN", 0x6 },
11728 },
11729};
11730
accbe498 11731static struct hda_input_mux alc262_HP_D7000_capture_source = {
11732 .num_items = 4,
11733 .items = {
11734 { "Mic", 0x0 },
11735 { "Front Mic", 0x2 },
11736 { "Line", 0x1 },
11737 { "CD", 0x4 },
11738 },
11739};
11740
ebc7a406 11741/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11742static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11743{
11744 struct alc_spec *spec = codec->spec;
11745 unsigned int mute;
11746
f12ab1e0 11747 if (force || !spec->sense_updated) {
864f92be
WF
11748 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11749 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11750 spec->sense_updated = 1;
11751 }
ebc7a406
TI
11752 /* unmute internal speaker only if both HPs are unplugged and
11753 * master switch is on
11754 */
11755 if (spec->jack_present)
11756 mute = HDA_AMP_MUTE;
11757 else
834be88d 11758 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11759 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11760 HDA_AMP_MUTE, mute);
834be88d
TI
11761}
11762
11763/* unsolicited event for HP jack sensing */
11764static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11765 unsigned int res)
11766{
11767 if ((res >> 26) != ALC_HP_EVENT)
11768 return;
11769 alc262_fujitsu_automute(codec, 1);
11770}
11771
ebc7a406
TI
11772static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11773{
11774 alc262_fujitsu_automute(codec, 1);
11775}
11776
834be88d 11777/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11778static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11779 .ops = &snd_hda_bind_vol,
11780 .values = {
11781 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11782 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11783 0
11784 },
11785};
834be88d 11786
0e31daf7
J
11787/* mute/unmute internal speaker according to the hp jack and mute state */
11788static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11789{
11790 struct alc_spec *spec = codec->spec;
11791 unsigned int mute;
11792
11793 if (force || !spec->sense_updated) {
864f92be 11794 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11795 spec->sense_updated = 1;
11796 }
11797 if (spec->jack_present) {
11798 /* mute internal speaker */
11799 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11800 HDA_AMP_MUTE, HDA_AMP_MUTE);
11801 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11802 HDA_AMP_MUTE, HDA_AMP_MUTE);
11803 } else {
11804 /* unmute internal speaker if necessary */
11805 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11806 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11807 HDA_AMP_MUTE, mute);
11808 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11809 HDA_AMP_MUTE, mute);
11810 }
11811}
11812
11813/* unsolicited event for HP jack sensing */
11814static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11815 unsigned int res)
11816{
11817 if ((res >> 26) != ALC_HP_EVENT)
11818 return;
11819 alc262_lenovo_3000_automute(codec, 1);
11820}
11821
8de56b7d
TI
11822static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11823 int dir, int idx, long *valp)
11824{
11825 int i, change = 0;
11826
11827 for (i = 0; i < 2; i++, valp++)
11828 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11829 HDA_AMP_MUTE,
11830 *valp ? 0 : HDA_AMP_MUTE);
11831 return change;
11832}
11833
834be88d
TI
11834/* bind hp and internal speaker mute (with plug check) */
11835static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11836 struct snd_ctl_elem_value *ucontrol)
11837{
11838 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11839 long *valp = ucontrol->value.integer.value;
11840 int change;
11841
8de56b7d
TI
11842 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11843 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11844 if (change)
11845 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11846 return change;
11847}
11848
11849static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11850 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11851 {
11852 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11853 .name = "Master Playback Switch",
5e26dfd0 11854 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11855 .info = snd_hda_mixer_amp_switch_info,
11856 .get = snd_hda_mixer_amp_switch_get,
11857 .put = alc262_fujitsu_master_sw_put,
11858 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11859 },
5b0cb1d8
JK
11860 {
11861 .iface = NID_MAPPING,
11862 .name = "Master Playback Switch",
11863 .private_value = 0x1b,
11864 },
834be88d
TI
11865 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11866 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11867 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11869 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11870 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11871 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11872 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11873 { } /* end */
11874};
11875
0e31daf7
J
11876/* bind hp and internal speaker mute (with plug check) */
11877static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11878 struct snd_ctl_elem_value *ucontrol)
11879{
11880 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11881 long *valp = ucontrol->value.integer.value;
11882 int change;
11883
8de56b7d 11884 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11885 if (change)
11886 alc262_lenovo_3000_automute(codec, 0);
11887 return change;
11888}
11889
11890static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11891 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11892 {
11893 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11894 .name = "Master Playback Switch",
5e26dfd0 11895 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11896 .info = snd_hda_mixer_amp_switch_info,
11897 .get = snd_hda_mixer_amp_switch_get,
11898 .put = alc262_lenovo_3000_master_sw_put,
11899 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11900 },
11901 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11902 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11903 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11906 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11907 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11908 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11909 { } /* end */
11910};
11911
9f99a638
HM
11912static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11913 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11914 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11915 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11916 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11917 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11918 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11919 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11920 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11921 { } /* end */
11922};
11923
304dcaac
TI
11924/* additional init verbs for Benq laptops */
11925static struct hda_verb alc262_EAPD_verbs[] = {
11926 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11927 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11928 {}
11929};
11930
83c34218
KY
11931static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11932 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11933 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11934
11935 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11936 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11937 {}
11938};
11939
f651b50b
TD
11940/* Samsung Q1 Ultra Vista model setup */
11941static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11942 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11943 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11944 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11945 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11946 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11947 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11948 { } /* end */
11949};
11950
11951static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11952 /* output mixer */
11953 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11954 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11955 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11956 /* speaker */
11957 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11958 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11959 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11960 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11961 /* HP */
f651b50b 11962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11963 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11964 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11965 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11966 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11967 /* internal mic */
11968 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11969 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11970 /* ADC, choose mic */
11971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11972 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11973 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11974 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11977 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11978 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11979 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11980 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11981 {}
11982};
11983
f651b50b
TD
11984/* mute/unmute internal speaker according to the hp jack and mute state */
11985static void alc262_ultra_automute(struct hda_codec *codec)
11986{
11987 struct alc_spec *spec = codec->spec;
11988 unsigned int mute;
f651b50b 11989
bb9f76cd
TI
11990 mute = 0;
11991 /* auto-mute only when HP is used as HP */
11992 if (!spec->cur_mux[0]) {
864f92be 11993 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11994 if (spec->jack_present)
11995 mute = HDA_AMP_MUTE;
f651b50b 11996 }
bb9f76cd
TI
11997 /* mute/unmute internal speaker */
11998 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11999 HDA_AMP_MUTE, mute);
12000 /* mute/unmute HP */
12001 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12002 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12003}
12004
12005/* unsolicited event for HP jack sensing */
12006static void alc262_ultra_unsol_event(struct hda_codec *codec,
12007 unsigned int res)
12008{
12009 if ((res >> 26) != ALC880_HP_EVENT)
12010 return;
12011 alc262_ultra_automute(codec);
12012}
12013
bb9f76cd
TI
12014static struct hda_input_mux alc262_ultra_capture_source = {
12015 .num_items = 2,
12016 .items = {
12017 { "Mic", 0x1 },
12018 { "Headphone", 0x7 },
12019 },
12020};
12021
12022static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12023 struct snd_ctl_elem_value *ucontrol)
12024{
12025 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12026 struct alc_spec *spec = codec->spec;
12027 int ret;
12028
54cbc9ab 12029 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12030 if (!ret)
12031 return 0;
12032 /* reprogram the HP pin as mic or HP according to the input source */
12033 snd_hda_codec_write_cache(codec, 0x15, 0,
12034 AC_VERB_SET_PIN_WIDGET_CONTROL,
12035 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12036 alc262_ultra_automute(codec); /* mute/unmute HP */
12037 return ret;
12038}
12039
12040static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12041 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12042 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12043 {
12044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12045 .name = "Capture Source",
54cbc9ab
TI
12046 .info = alc_mux_enum_info,
12047 .get = alc_mux_enum_get,
bb9f76cd
TI
12048 .put = alc262_ultra_mux_enum_put,
12049 },
5b0cb1d8
JK
12050 {
12051 .iface = NID_MAPPING,
12052 .name = "Capture Source",
12053 .private_value = 0x15,
12054 },
bb9f76cd
TI
12055 { } /* end */
12056};
12057
c3fc1f50
TI
12058/* We use two mixers depending on the output pin; 0x16 is a mono output
12059 * and thus it's bound with a different mixer.
12060 * This function returns which mixer amp should be used.
12061 */
12062static int alc262_check_volbit(hda_nid_t nid)
12063{
12064 if (!nid)
12065 return 0;
12066 else if (nid == 0x16)
12067 return 2;
12068 else
12069 return 1;
12070}
12071
12072static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12073 const char *pfx, int *vbits, int idx)
c3fc1f50 12074{
c3fc1f50
TI
12075 unsigned long val;
12076 int vbit;
12077
12078 vbit = alc262_check_volbit(nid);
12079 if (!vbit)
12080 return 0;
12081 if (*vbits & vbit) /* a volume control for this mixer already there */
12082 return 0;
12083 *vbits |= vbit;
c3fc1f50
TI
12084 if (vbit == 2)
12085 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12086 else
12087 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12088 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12089}
12090
12091static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12092 const char *pfx, int idx)
c3fc1f50 12093{
c3fc1f50
TI
12094 unsigned long val;
12095
12096 if (!nid)
12097 return 0;
c3fc1f50
TI
12098 if (nid == 0x16)
12099 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12100 else
12101 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12102 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12103}
12104
df694daa 12105/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12106static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12107 const struct auto_pin_cfg *cfg)
df694daa 12108{
c3fc1f50
TI
12109 const char *pfx;
12110 int vbits;
033688a5 12111 int i, err;
df694daa
KY
12112
12113 spec->multiout.num_dacs = 1; /* only use one dac */
12114 spec->multiout.dac_nids = spec->private_dac_nids;
12115 spec->multiout.dac_nids[0] = 2;
12116
bcb2f0f5
TI
12117 pfx = alc_get_line_out_pfx(cfg, true);
12118 if (!pfx)
c3fc1f50 12119 pfx = "Front";
033688a5
TI
12120 for (i = 0; i < 2; i++) {
12121 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12122 if (err < 0)
12123 return err;
12124 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12125 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12126 "Speaker", i);
12127 if (err < 0)
12128 return err;
12129 }
12130 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12131 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12132 "Headphone", i);
12133 if (err < 0)
12134 return err;
12135 }
12136 }
df694daa 12137
c3fc1f50
TI
12138 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12139 alc262_check_volbit(cfg->speaker_pins[0]) |
12140 alc262_check_volbit(cfg->hp_pins[0]);
12141 if (vbits == 1 || vbits == 2)
12142 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12143 vbits = 0;
033688a5
TI
12144 for (i = 0; i < 2; i++) {
12145 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12146 &vbits, i);
12147 if (err < 0)
12148 return err;
12149 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12150 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12151 "Speaker", &vbits, i);
12152 if (err < 0)
12153 return err;
12154 }
12155 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12156 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12157 "Headphone", &vbits, i);
12158 if (err < 0)
12159 return err;
12160 }
12161 }
f12ab1e0 12162 return 0;
df694daa
KY
12163}
12164
05f5f477 12165#define alc262_auto_create_input_ctls \
eaa9b3a7 12166 alc882_auto_create_input_ctls
df694daa
KY
12167
12168/*
12169 * generic initialization of ADC, input mixers and output mixers
12170 */
12171static struct hda_verb alc262_volume_init_verbs[] = {
12172 /*
12173 * Unmute ADC0-2 and set the default input to mic-in
12174 */
12175 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12176 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12177 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12178 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12179 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12180 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12181
cb53c626 12182 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12183 * mixer widget
f12ab1e0
TI
12184 * Note: PASD motherboards uses the Line In 2 as the input for
12185 * front panel mic (mic 2)
df694daa
KY
12186 */
12187 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12188 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12189 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12190 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12191 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12192 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12193
12194 /*
12195 * Set up output mixers (0x0c - 0x0f)
12196 */
12197 /* set vol=0 to output mixers */
12198 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12199 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12200 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12201
df694daa
KY
12202 /* set up input amps for analog loopback */
12203 /* Amp Indices: DAC = 0, mixer = 1 */
12204 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12205 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12206 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12207 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12208 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12209 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12210
12211 /* FIXME: use matrix-type input source selection */
12212 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12213 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12214 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12215 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12216 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12217 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12218 /* Input mixer2 */
12219 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12220 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12221 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12222 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12223 /* Input mixer3 */
12224 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12225 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12228
12229 { }
12230};
12231
9c7f852e
TI
12232static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12233 /*
12234 * Unmute ADC0-2 and set the default input to mic-in
12235 */
12236 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12237 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12238 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12239 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12240 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12241 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12242
cb53c626 12243 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12244 * mixer widget
f12ab1e0
TI
12245 * Note: PASD motherboards uses the Line In 2 as the input for
12246 * front panel mic (mic 2)
9c7f852e
TI
12247 */
12248 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12255 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12256
9c7f852e
TI
12257 /*
12258 * Set up output mixers (0x0c - 0x0e)
12259 */
12260 /* set vol=0 to output mixers */
12261 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12262 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12263 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12264
12265 /* set up input amps for analog loopback */
12266 /* Amp Indices: DAC = 0, mixer = 1 */
12267 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12268 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12269 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12270 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12271 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12272 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12273
ce875f07 12274 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12276 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12277
12278 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12279 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12280
12281 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12282 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12283
12284 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12285 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12286 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12287 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12288 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12289
0e4835c1 12290 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12291 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12292 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12293 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12294 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12295 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12296
12297
12298 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12299 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12300 /* Input mixer1: only unmute Mic */
9c7f852e 12301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12303 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12304 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12305 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12306 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12307 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12308 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12309 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12310 /* Input mixer2 */
12311 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12313 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12314 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12315 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12316 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12317 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12318 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12320 /* Input mixer3 */
12321 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12328 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12329 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12330
ce875f07
TI
12331 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12332
9c7f852e
TI
12333 { }
12334};
12335
cd7509a4
KY
12336static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12337 /*
12338 * Unmute ADC0-2 and set the default input to mic-in
12339 */
12340 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12341 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12342 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12343 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12344 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12345 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12346
cb53c626 12347 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12348 * mixer widget
12349 * Note: PASD motherboards uses the Line In 2 as the input for front
12350 * panel mic (mic 2)
12351 */
12352 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12353 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12354 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12355 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12356 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12357 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12358 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12359 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12360 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12361 /*
12362 * Set up output mixers (0x0c - 0x0e)
12363 */
12364 /* set vol=0 to output mixers */
12365 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12366 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12367 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12368
12369 /* set up input amps for analog loopback */
12370 /* Amp Indices: DAC = 0, mixer = 1 */
12371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12375 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12377
12378
12379 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12380 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12381 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12382 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12383 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12384 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12385 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12386
12387 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12389
12390 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12391 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12392
12393 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12394 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12395 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12396 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12397 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12398 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12399
12400 /* FIXME: use matrix-type input source selection */
12401 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12402 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12405 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12406 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12407 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12408 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12409 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12410 /* Input mixer2 */
12411 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12412 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12413 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12414 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12415 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12416 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12418 /* Input mixer3 */
12419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12420 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12421 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12424 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12426
ce875f07
TI
12427 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12428
cd7509a4
KY
12429 { }
12430};
12431
9f99a638
HM
12432static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12433
12434 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12435 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12436 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12437
12438 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12439 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12440 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12441 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12442
12443 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12444 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12445 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12446 {}
12447};
12448
18675e42
TI
12449/*
12450 * Pin config fixes
12451 */
12452enum {
12453 PINFIX_FSC_H270,
12454};
12455
12456static const struct alc_fixup alc262_fixups[] = {
12457 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12458 .type = ALC_FIXUP_PINS,
12459 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12460 { 0x14, 0x99130110 }, /* speaker */
12461 { 0x15, 0x0221142f }, /* front HP */
12462 { 0x1b, 0x0121141f }, /* rear HP */
12463 { }
12464 }
12465 },
18675e42
TI
12466};
12467
12468static struct snd_pci_quirk alc262_fixup_tbl[] = {
12469 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12470 {}
12471};
12472
9f99a638 12473
cb53c626
TI
12474#ifdef CONFIG_SND_HDA_POWER_SAVE
12475#define alc262_loopbacks alc880_loopbacks
12476#endif
12477
def319f9 12478/* pcm configuration: identical with ALC880 */
df694daa
KY
12479#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12480#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12481#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12482#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12483
12484/*
12485 * BIOS auto configuration
12486 */
12487static int alc262_parse_auto_config(struct hda_codec *codec)
12488{
12489 struct alc_spec *spec = codec->spec;
12490 int err;
12491 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12492
f12ab1e0
TI
12493 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12494 alc262_ignore);
12495 if (err < 0)
df694daa 12496 return err;
e64f14f4 12497 if (!spec->autocfg.line_outs) {
0852d7a6 12498 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12499 spec->multiout.max_channels = 2;
12500 spec->no_analog = 1;
12501 goto dig_only;
12502 }
df694daa 12503 return 0; /* can't find valid BIOS pin config */
e64f14f4 12504 }
f12ab1e0
TI
12505 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12506 if (err < 0)
12507 return err;
05f5f477 12508 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12509 if (err < 0)
df694daa
KY
12510 return err;
12511
12512 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12513
e64f14f4 12514 dig_only:
757899ac 12515 alc_auto_parse_digital(codec);
df694daa 12516
603c4019 12517 if (spec->kctls.list)
d88897ea 12518 add_mixer(spec, spec->kctls.list);
df694daa 12519
d88897ea 12520 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12521 spec->num_mux_defs = 1;
61b9b9b1 12522 spec->input_mux = &spec->private_imux[0];
df694daa 12523
776e184e
TI
12524 err = alc_auto_add_mic_boost(codec);
12525 if (err < 0)
12526 return err;
12527
6227cdce 12528 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12529
df694daa
KY
12530 return 1;
12531}
12532
12533#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12534#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12535#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12536#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12537
12538
12539/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12540static void alc262_auto_init(struct hda_codec *codec)
df694daa 12541{
f6c7e546 12542 struct alc_spec *spec = codec->spec;
df694daa
KY
12543 alc262_auto_init_multi_out(codec);
12544 alc262_auto_init_hp_out(codec);
12545 alc262_auto_init_analog_input(codec);
f511b01c 12546 alc262_auto_init_input_src(codec);
757899ac 12547 alc_auto_init_digital(codec);
f6c7e546 12548 if (spec->unsol_event)
7fb0d78f 12549 alc_inithook(codec);
df694daa
KY
12550}
12551
12552/*
12553 * configuration and preset
12554 */
ea734963 12555static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12556 [ALC262_BASIC] = "basic",
12557 [ALC262_HIPPO] = "hippo",
12558 [ALC262_HIPPO_1] = "hippo_1",
12559 [ALC262_FUJITSU] = "fujitsu",
12560 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12561 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12562 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12563 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12564 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12565 [ALC262_BENQ_T31] = "benq-t31",
12566 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12567 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12568 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12569 [ALC262_ULTRA] = "ultra",
0e31daf7 12570 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12571 [ALC262_NEC] = "nec",
ba340e82 12572 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12573 [ALC262_AUTO] = "auto",
12574};
12575
12576static struct snd_pci_quirk alc262_cfg_tbl[] = {
12577 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12578 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12579 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12580 ALC262_HP_BPC),
12581 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12582 ALC262_HP_BPC),
5734a07c
TI
12583 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12584 ALC262_HP_BPC),
53eff7e1
TI
12585 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12586 ALC262_HP_BPC),
cd7509a4 12587 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12588 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12589 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12590 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12591 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12592 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12593 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12594 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12595 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12596 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12597 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12598 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12599 ALC262_HP_TC_T5735),
8c427226 12600 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12601 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12602 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12603 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12604 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12605 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12606 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12607 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12608#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12609 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12610 ALC262_SONY_ASSAMD),
c5b5165c 12611#endif
36ca6e13 12612 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12613 ALC262_TOSHIBA_RX1),
80ffe869 12614 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12615 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12616 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12617 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12618 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12619 ALC262_ULTRA),
3e420e78 12620 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12621 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12622 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12623 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12624 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12625 {}
12626};
12627
12628static struct alc_config_preset alc262_presets[] = {
12629 [ALC262_BASIC] = {
12630 .mixers = { alc262_base_mixer },
12631 .init_verbs = { alc262_init_verbs },
12632 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12633 .dac_nids = alc262_dac_nids,
12634 .hp_nid = 0x03,
12635 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12636 .channel_mode = alc262_modes,
a3bcba38 12637 .input_mux = &alc262_capture_source,
df694daa 12638 },
ccc656ce 12639 [ALC262_HIPPO] = {
42171c17 12640 .mixers = { alc262_hippo_mixer },
6732bd0d 12641 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12642 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12643 .dac_nids = alc262_dac_nids,
12644 .hp_nid = 0x03,
12645 .dig_out_nid = ALC262_DIGOUT_NID,
12646 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12647 .channel_mode = alc262_modes,
12648 .input_mux = &alc262_capture_source,
12649 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12650 .setup = alc262_hippo_setup,
12651 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12652 },
12653 [ALC262_HIPPO_1] = {
12654 .mixers = { alc262_hippo1_mixer },
12655 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12656 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12657 .dac_nids = alc262_dac_nids,
12658 .hp_nid = 0x02,
12659 .dig_out_nid = ALC262_DIGOUT_NID,
12660 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12661 .channel_mode = alc262_modes,
12662 .input_mux = &alc262_capture_source,
42171c17 12663 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12664 .setup = alc262_hippo1_setup,
12665 .init_hook = alc262_hippo_automute,
ccc656ce 12666 },
834be88d
TI
12667 [ALC262_FUJITSU] = {
12668 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12669 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12670 alc262_fujitsu_unsol_verbs },
834be88d
TI
12671 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12672 .dac_nids = alc262_dac_nids,
12673 .hp_nid = 0x03,
12674 .dig_out_nid = ALC262_DIGOUT_NID,
12675 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12676 .channel_mode = alc262_modes,
12677 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12678 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12679 .init_hook = alc262_fujitsu_init_hook,
834be88d 12680 },
9c7f852e
TI
12681 [ALC262_HP_BPC] = {
12682 .mixers = { alc262_HP_BPC_mixer },
12683 .init_verbs = { alc262_HP_BPC_init_verbs },
12684 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12685 .dac_nids = alc262_dac_nids,
12686 .hp_nid = 0x03,
12687 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12688 .channel_mode = alc262_modes,
12689 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12690 .unsol_event = alc262_hp_bpc_unsol_event,
12691 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12692 },
cd7509a4
KY
12693 [ALC262_HP_BPC_D7000_WF] = {
12694 .mixers = { alc262_HP_BPC_WildWest_mixer },
12695 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12696 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12697 .dac_nids = alc262_dac_nids,
12698 .hp_nid = 0x03,
12699 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12700 .channel_mode = alc262_modes,
accbe498 12701 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12702 .unsol_event = alc262_hp_wildwest_unsol_event,
12703 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12704 },
cd7509a4
KY
12705 [ALC262_HP_BPC_D7000_WL] = {
12706 .mixers = { alc262_HP_BPC_WildWest_mixer,
12707 alc262_HP_BPC_WildWest_option_mixer },
12708 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12709 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12710 .dac_nids = alc262_dac_nids,
12711 .hp_nid = 0x03,
12712 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12713 .channel_mode = alc262_modes,
accbe498 12714 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12715 .unsol_event = alc262_hp_wildwest_unsol_event,
12716 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12717 },
66d2a9d6
KY
12718 [ALC262_HP_TC_T5735] = {
12719 .mixers = { alc262_hp_t5735_mixer },
12720 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12721 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12722 .dac_nids = alc262_dac_nids,
12723 .hp_nid = 0x03,
12724 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12725 .channel_mode = alc262_modes,
12726 .input_mux = &alc262_capture_source,
dc99be47 12727 .unsol_event = alc_sku_unsol_event,
4f5d1706 12728 .setup = alc262_hp_t5735_setup,
dc99be47 12729 .init_hook = alc_inithook,
8c427226
KY
12730 },
12731 [ALC262_HP_RP5700] = {
12732 .mixers = { alc262_hp_rp5700_mixer },
12733 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12734 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12735 .dac_nids = alc262_dac_nids,
12736 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12737 .channel_mode = alc262_modes,
12738 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12739 },
304dcaac
TI
12740 [ALC262_BENQ_ED8] = {
12741 .mixers = { alc262_base_mixer },
12742 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12743 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12744 .dac_nids = alc262_dac_nids,
12745 .hp_nid = 0x03,
12746 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12747 .channel_mode = alc262_modes,
12748 .input_mux = &alc262_capture_source,
f12ab1e0 12749 },
272a527c
KY
12750 [ALC262_SONY_ASSAMD] = {
12751 .mixers = { alc262_sony_mixer },
12752 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12753 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12754 .dac_nids = alc262_dac_nids,
12755 .hp_nid = 0x02,
12756 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12757 .channel_mode = alc262_modes,
12758 .input_mux = &alc262_capture_source,
12759 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12760 .setup = alc262_hippo_setup,
12761 .init_hook = alc262_hippo_automute,
83c34218
KY
12762 },
12763 [ALC262_BENQ_T31] = {
12764 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12765 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12766 alc_hp15_unsol_verbs },
83c34218
KY
12767 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12768 .dac_nids = alc262_dac_nids,
12769 .hp_nid = 0x03,
12770 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12771 .channel_mode = alc262_modes,
12772 .input_mux = &alc262_capture_source,
12773 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12774 .setup = alc262_hippo_setup,
12775 .init_hook = alc262_hippo_automute,
ea1fb29a 12776 },
f651b50b 12777 [ALC262_ULTRA] = {
f9e336f6
TI
12778 .mixers = { alc262_ultra_mixer },
12779 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12780 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12781 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12782 .dac_nids = alc262_dac_nids,
f651b50b
TD
12783 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12784 .channel_mode = alc262_modes,
12785 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12786 .adc_nids = alc262_adc_nids, /* ADC0 */
12787 .capsrc_nids = alc262_capsrc_nids,
12788 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12789 .unsol_event = alc262_ultra_unsol_event,
12790 .init_hook = alc262_ultra_automute,
12791 },
0e31daf7
J
12792 [ALC262_LENOVO_3000] = {
12793 .mixers = { alc262_lenovo_3000_mixer },
12794 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12795 alc262_lenovo_3000_unsol_verbs,
12796 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12797 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12798 .dac_nids = alc262_dac_nids,
12799 .hp_nid = 0x03,
12800 .dig_out_nid = ALC262_DIGOUT_NID,
12801 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12802 .channel_mode = alc262_modes,
12803 .input_mux = &alc262_fujitsu_capture_source,
12804 .unsol_event = alc262_lenovo_3000_unsol_event,
12805 },
e8f9ae2a
PT
12806 [ALC262_NEC] = {
12807 .mixers = { alc262_nec_mixer },
12808 .init_verbs = { alc262_nec_verbs },
12809 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12810 .dac_nids = alc262_dac_nids,
12811 .hp_nid = 0x03,
12812 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12813 .channel_mode = alc262_modes,
12814 .input_mux = &alc262_capture_source,
12815 },
4e555fe5
KY
12816 [ALC262_TOSHIBA_S06] = {
12817 .mixers = { alc262_toshiba_s06_mixer },
12818 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12819 alc262_eapd_verbs },
12820 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12821 .capsrc_nids = alc262_dmic_capsrc_nids,
12822 .dac_nids = alc262_dac_nids,
12823 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12824 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12825 .dig_out_nid = ALC262_DIGOUT_NID,
12826 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12827 .channel_mode = alc262_modes,
4f5d1706
TI
12828 .unsol_event = alc_sku_unsol_event,
12829 .setup = alc262_toshiba_s06_setup,
12830 .init_hook = alc_inithook,
4e555fe5 12831 },
9f99a638
HM
12832 [ALC262_TOSHIBA_RX1] = {
12833 .mixers = { alc262_toshiba_rx1_mixer },
12834 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12835 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12836 .dac_nids = alc262_dac_nids,
12837 .hp_nid = 0x03,
12838 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12839 .channel_mode = alc262_modes,
12840 .input_mux = &alc262_capture_source,
12841 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12842 .setup = alc262_hippo_setup,
12843 .init_hook = alc262_hippo_automute,
9f99a638 12844 },
ba340e82
TV
12845 [ALC262_TYAN] = {
12846 .mixers = { alc262_tyan_mixer },
12847 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12848 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12849 .dac_nids = alc262_dac_nids,
12850 .hp_nid = 0x02,
12851 .dig_out_nid = ALC262_DIGOUT_NID,
12852 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12853 .channel_mode = alc262_modes,
12854 .input_mux = &alc262_capture_source,
a9fd4f3f 12855 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12856 .setup = alc262_tyan_setup,
12857 .init_hook = alc_automute_amp,
ba340e82 12858 },
df694daa
KY
12859};
12860
12861static int patch_alc262(struct hda_codec *codec)
12862{
12863 struct alc_spec *spec;
12864 int board_config;
12865 int err;
12866
dc041e0b 12867 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12868 if (spec == NULL)
12869 return -ENOMEM;
12870
12871 codec->spec = spec;
12872#if 0
f12ab1e0
TI
12873 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12874 * under-run
12875 */
df694daa
KY
12876 {
12877 int tmp;
12878 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12879 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12880 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12881 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12882 }
12883#endif
da00c244 12884 alc_auto_parse_customize_define(codec);
df694daa 12885
2c3bf9ab
TI
12886 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12887
f5fcc13c
TI
12888 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12889 alc262_models,
12890 alc262_cfg_tbl);
cd7509a4 12891
f5fcc13c 12892 if (board_config < 0) {
9a11f1aa
TI
12893 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12894 codec->chip_name);
df694daa
KY
12895 board_config = ALC262_AUTO;
12896 }
12897
b5bfbc67
TI
12898 if (board_config == ALC262_AUTO) {
12899 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12900 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12901 }
18675e42 12902
df694daa
KY
12903 if (board_config == ALC262_AUTO) {
12904 /* automatic parse from the BIOS config */
12905 err = alc262_parse_auto_config(codec);
12906 if (err < 0) {
12907 alc_free(codec);
12908 return err;
f12ab1e0 12909 } else if (!err) {
9c7f852e
TI
12910 printk(KERN_INFO
12911 "hda_codec: Cannot set up configuration "
12912 "from BIOS. Using base mode...\n");
df694daa
KY
12913 board_config = ALC262_BASIC;
12914 }
12915 }
12916
dc1eae25 12917 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12918 err = snd_hda_attach_beep_device(codec, 0x1);
12919 if (err < 0) {
12920 alc_free(codec);
12921 return err;
12922 }
680cd536
KK
12923 }
12924
df694daa 12925 if (board_config != ALC262_AUTO)
e9c364c0 12926 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12927
df694daa
KY
12928 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12929 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12930
df694daa
KY
12931 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12932 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12933
f12ab1e0 12934 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12935 int i;
12936 /* check whether the digital-mic has to be supported */
12937 for (i = 0; i < spec->input_mux->num_items; i++) {
12938 if (spec->input_mux->items[i].index >= 9)
12939 break;
12940 }
12941 if (i < spec->input_mux->num_items) {
12942 /* use only ADC0 */
12943 spec->adc_nids = alc262_dmic_adc_nids;
12944 spec->num_adc_nids = 1;
12945 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12946 } else {
8c927b4a
TI
12947 /* all analog inputs */
12948 /* check whether NID 0x07 is valid */
12949 unsigned int wcap = get_wcaps(codec, 0x07);
12950
12951 /* get type */
a22d543a 12952 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12953 if (wcap != AC_WID_AUD_IN) {
12954 spec->adc_nids = alc262_adc_nids_alt;
12955 spec->num_adc_nids =
12956 ARRAY_SIZE(alc262_adc_nids_alt);
12957 spec->capsrc_nids = alc262_capsrc_nids_alt;
12958 } else {
12959 spec->adc_nids = alc262_adc_nids;
12960 spec->num_adc_nids =
12961 ARRAY_SIZE(alc262_adc_nids);
12962 spec->capsrc_nids = alc262_capsrc_nids;
12963 }
df694daa
KY
12964 }
12965 }
e64f14f4 12966 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12967 set_capture_mixer(codec);
dc1eae25 12968 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12969 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12970
b5bfbc67 12971 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 12972
2134ea4f
TI
12973 spec->vmaster_nid = 0x0c;
12974
df694daa
KY
12975 codec->patch_ops = alc_patch_ops;
12976 if (board_config == ALC262_AUTO)
ae6b813a 12977 spec->init_hook = alc262_auto_init;
bf1b0225
KY
12978
12979 alc_init_jacks(codec);
cb53c626
TI
12980#ifdef CONFIG_SND_HDA_POWER_SAVE
12981 if (!spec->loopback.amplist)
12982 spec->loopback.amplist = alc262_loopbacks;
12983#endif
ea1fb29a 12984
df694daa
KY
12985 return 0;
12986}
12987
a361d84b
KY
12988/*
12989 * ALC268 channel source setting (2 channel)
12990 */
12991#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12992#define alc268_modes alc260_modes
ea1fb29a 12993
a361d84b
KY
12994static hda_nid_t alc268_dac_nids[2] = {
12995 /* front, hp */
12996 0x02, 0x03
12997};
12998
12999static hda_nid_t alc268_adc_nids[2] = {
13000 /* ADC0-1 */
13001 0x08, 0x07
13002};
13003
13004static hda_nid_t alc268_adc_nids_alt[1] = {
13005 /* ADC0 */
13006 0x08
13007};
13008
e1406348
TI
13009static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13010
a361d84b
KY
13011static struct snd_kcontrol_new alc268_base_mixer[] = {
13012 /* output mixer control */
13013 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13014 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13015 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13016 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13017 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13018 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13019 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13020 { }
13021};
13022
42171c17
TI
13023static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13024 /* output mixer control */
13025 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13026 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13027 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13028 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13029 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13030 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13031 { }
13032};
13033
aef9d318
TI
13034/* bind Beep switches of both NID 0x0f and 0x10 */
13035static struct hda_bind_ctls alc268_bind_beep_sw = {
13036 .ops = &snd_hda_bind_sw,
13037 .values = {
13038 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13039 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13040 0
13041 },
13042};
13043
13044static struct snd_kcontrol_new alc268_beep_mixer[] = {
13045 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13046 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13047 { }
13048};
13049
d1a991a6
KY
13050static struct hda_verb alc268_eapd_verbs[] = {
13051 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13052 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13053 { }
13054};
13055
d273809e 13056/* Toshiba specific */
d273809e
TI
13057static struct hda_verb alc268_toshiba_verbs[] = {
13058 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13059 { } /* end */
13060};
13061
13062/* Acer specific */
889c4395 13063/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13064static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13065 .ops = &snd_hda_bind_vol,
13066 .values = {
13067 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13068 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13069 0
13070 },
13071};
13072
889c4395
TI
13073/* mute/unmute internal speaker according to the hp jack and mute state */
13074static void alc268_acer_automute(struct hda_codec *codec, int force)
13075{
13076 struct alc_spec *spec = codec->spec;
13077 unsigned int mute;
13078
13079 if (force || !spec->sense_updated) {
864f92be 13080 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
13081 spec->sense_updated = 1;
13082 }
13083 if (spec->jack_present)
13084 mute = HDA_AMP_MUTE; /* mute internal speaker */
13085 else /* unmute internal speaker if necessary */
13086 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13087 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13088 HDA_AMP_MUTE, mute);
13089}
13090
13091
13092/* bind hp and internal speaker mute (with plug check) */
13093static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13094 struct snd_ctl_elem_value *ucontrol)
13095{
13096 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13097 long *valp = ucontrol->value.integer.value;
13098 int change;
13099
8de56b7d 13100 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13101 if (change)
13102 alc268_acer_automute(codec, 0);
13103 return change;
13104}
d273809e 13105
8ef355da
KY
13106static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13107 /* output mixer control */
13108 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13109 {
13110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13111 .name = "Master Playback Switch",
5e26dfd0 13112 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13113 .info = snd_hda_mixer_amp_switch_info,
13114 .get = snd_hda_mixer_amp_switch_get,
13115 .put = alc268_acer_master_sw_put,
13116 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13117 },
13118 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13119 { }
13120};
13121
d273809e
TI
13122static struct snd_kcontrol_new alc268_acer_mixer[] = {
13123 /* output mixer control */
13124 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13125 {
13126 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13127 .name = "Master Playback Switch",
5e26dfd0 13128 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13129 .info = snd_hda_mixer_amp_switch_info,
13130 .get = snd_hda_mixer_amp_switch_get,
13131 .put = alc268_acer_master_sw_put,
13132 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13133 },
5f99f86a
DH
13134 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13135 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13136 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13137 { }
13138};
13139
c238b4f4
TI
13140static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13141 /* output mixer control */
13142 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13143 {
13144 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13145 .name = "Master Playback Switch",
5e26dfd0 13146 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13147 .info = snd_hda_mixer_amp_switch_info,
13148 .get = snd_hda_mixer_amp_switch_get,
13149 .put = alc268_acer_master_sw_put,
13150 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13151 },
5f99f86a
DH
13152 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13153 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13154 { }
13155};
13156
8ef355da
KY
13157static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13158 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13159 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13160 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13161 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13162 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13163 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13164 { }
13165};
13166
d273809e 13167static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13168 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13169 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13170 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13171 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13172 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13173 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13174 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13175 { }
13176};
13177
13178/* unsolicited event for HP jack sensing */
42171c17 13179#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13180#define alc268_toshiba_setup alc262_hippo_setup
13181#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13182
13183static void alc268_acer_unsol_event(struct hda_codec *codec,
13184 unsigned int res)
13185{
889c4395 13186 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13187 return;
13188 alc268_acer_automute(codec, 1);
13189}
13190
889c4395
TI
13191static void alc268_acer_init_hook(struct hda_codec *codec)
13192{
13193 alc268_acer_automute(codec, 1);
13194}
13195
8ef355da
KY
13196/* toggle speaker-output according to the hp-jack state */
13197static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13198{
13199 unsigned int present;
13200 unsigned char bits;
13201
864f92be 13202 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13203 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13204 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13205 HDA_AMP_MUTE, bits);
8ef355da 13206 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13207 HDA_AMP_MUTE, bits);
8ef355da
KY
13208}
13209
8ef355da
KY
13210static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13211 unsigned int res)
13212{
4f5d1706
TI
13213 switch (res >> 26) {
13214 case ALC880_HP_EVENT:
8ef355da 13215 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13216 break;
13217 case ALC880_MIC_EVENT:
13218 alc_mic_automute(codec);
13219 break;
13220 }
13221}
13222
13223static void alc268_acer_lc_setup(struct hda_codec *codec)
13224{
13225 struct alc_spec *spec = codec->spec;
13226 spec->ext_mic.pin = 0x18;
13227 spec->ext_mic.mux_idx = 0;
13228 spec->int_mic.pin = 0x12;
13229 spec->int_mic.mux_idx = 6;
13230 spec->auto_mic = 1;
8ef355da
KY
13231}
13232
13233static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13234{
13235 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13236 alc_mic_automute(codec);
8ef355da
KY
13237}
13238
3866f0b0
TI
13239static struct snd_kcontrol_new alc268_dell_mixer[] = {
13240 /* output mixer control */
13241 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13242 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13243 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13244 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13245 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13246 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13247 { }
13248};
13249
13250static struct hda_verb alc268_dell_verbs[] = {
13251 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13252 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13253 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13254 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13255 { }
13256};
13257
13258/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13259static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13260{
a9fd4f3f 13261 struct alc_spec *spec = codec->spec;
3866f0b0 13262
a9fd4f3f
TI
13263 spec->autocfg.hp_pins[0] = 0x15;
13264 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13265 spec->ext_mic.pin = 0x18;
13266 spec->ext_mic.mux_idx = 0;
13267 spec->int_mic.pin = 0x19;
13268 spec->int_mic.mux_idx = 1;
13269 spec->auto_mic = 1;
3866f0b0
TI
13270}
13271
eb5a6621
HRK
13272static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13273 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13274 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13275 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13276 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13277 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13278 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13279 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13280 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13281 { }
13282};
13283
13284static struct hda_verb alc267_quanta_il1_verbs[] = {
13285 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13286 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13287 { }
13288};
13289
4f5d1706 13290static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13291{
a9fd4f3f 13292 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13293 spec->autocfg.hp_pins[0] = 0x15;
13294 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13295 spec->ext_mic.pin = 0x18;
13296 spec->ext_mic.mux_idx = 0;
13297 spec->int_mic.pin = 0x19;
13298 spec->int_mic.mux_idx = 1;
13299 spec->auto_mic = 1;
eb5a6621
HRK
13300}
13301
a361d84b
KY
13302/*
13303 * generic initialization of ADC, input mixers and output mixers
13304 */
13305static struct hda_verb alc268_base_init_verbs[] = {
13306 /* Unmute DAC0-1 and set vol = 0 */
13307 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13308 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13309
13310 /*
13311 * Set up output mixers (0x0c - 0x0e)
13312 */
13313 /* set vol=0 to output mixers */
13314 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13315 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13316
13317 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13318 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13319
13320 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13321 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13322 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13323 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13324 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13326 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13327 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13328
13329 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13330 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13331 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13332 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13333 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13334
13335 /* set PCBEEP vol = 0, mute connections */
13336 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13337 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13338 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13339
a9b3aa8a 13340 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13341
a9b3aa8a
JZ
13342 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13343 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13344 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13345 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13346
a361d84b
KY
13347 { }
13348};
13349
13350/*
13351 * generic initialization of ADC, input mixers and output mixers
13352 */
13353static struct hda_verb alc268_volume_init_verbs[] = {
13354 /* set output DAC */
4cfb91c6
TI
13355 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13356 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13357
13358 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13359 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13360 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13361 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13362 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13363
a361d84b 13364 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13365 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13366 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13367
13368 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13369 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13370
aef9d318
TI
13371 /* set PCBEEP vol = 0, mute connections */
13372 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13373 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13374 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13375
13376 { }
13377};
13378
fdbc6626
TI
13379static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13380 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13381 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13382 { } /* end */
13383};
13384
a361d84b
KY
13385static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13386 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13387 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13388 _DEFINE_CAPSRC(1),
a361d84b
KY
13389 { } /* end */
13390};
13391
13392static struct snd_kcontrol_new alc268_capture_mixer[] = {
13393 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13394 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13395 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13396 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13397 _DEFINE_CAPSRC(2),
a361d84b
KY
13398 { } /* end */
13399};
13400
13401static struct hda_input_mux alc268_capture_source = {
13402 .num_items = 4,
13403 .items = {
13404 { "Mic", 0x0 },
13405 { "Front Mic", 0x1 },
13406 { "Line", 0x2 },
13407 { "CD", 0x3 },
13408 },
13409};
13410
0ccb541c 13411static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13412 .num_items = 3,
13413 .items = {
13414 { "Mic", 0x0 },
13415 { "Internal Mic", 0x1 },
13416 { "Line", 0x2 },
13417 },
13418};
13419
13420static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13421 .num_items = 3,
13422 .items = {
13423 { "Mic", 0x0 },
13424 { "Internal Mic", 0x6 },
13425 { "Line", 0x2 },
13426 },
13427};
13428
86c53bd2
JW
13429#ifdef CONFIG_SND_DEBUG
13430static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13431 /* Volume widgets */
13432 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13433 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13434 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13435 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13436 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13437 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13438 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13439 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13440 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13441 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13442 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13443 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13444 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13445 /* The below appears problematic on some hardwares */
13446 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13447 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13448 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13449 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13450 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13451
13452 /* Modes for retasking pin widgets */
13453 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13454 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13455 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13456 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13457
13458 /* Controls for GPIO pins, assuming they are configured as outputs */
13459 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13460 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13461 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13462 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13463
13464 /* Switches to allow the digital SPDIF output pin to be enabled.
13465 * The ALC268 does not have an SPDIF input.
13466 */
13467 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13468
13469 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13470 * this output to turn on an external amplifier.
13471 */
13472 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13473 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13474
13475 { } /* end */
13476};
13477#endif
13478
a361d84b
KY
13479/* create input playback/capture controls for the given pin */
13480static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13481 const char *ctlname, int idx)
13482{
3f3b7c1a 13483 hda_nid_t dac;
a361d84b
KY
13484 int err;
13485
3f3b7c1a
TI
13486 switch (nid) {
13487 case 0x14:
13488 case 0x16:
13489 dac = 0x02;
13490 break;
13491 case 0x15:
b08b1637
TI
13492 case 0x1a: /* ALC259/269 only */
13493 case 0x1b: /* ALC259/269 only */
531d8791 13494 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13495 dac = 0x03;
13496 break;
13497 default:
c7a9434d
TI
13498 snd_printd(KERN_WARNING "hda_codec: "
13499 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13500 return 0;
13501 }
13502 if (spec->multiout.dac_nids[0] != dac &&
13503 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13504 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13505 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13506 HDA_OUTPUT));
13507 if (err < 0)
13508 return err;
3f3b7c1a
TI
13509 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13510 }
13511
3f3b7c1a 13512 if (nid != 0x16)
0afe5f89 13513 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13514 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13515 else /* mono */
0afe5f89 13516 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13517 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13518 if (err < 0)
13519 return err;
13520 return 0;
13521}
13522
13523/* add playback controls from the parsed DAC table */
13524static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13525 const struct auto_pin_cfg *cfg)
13526{
13527 hda_nid_t nid;
13528 int err;
13529
a361d84b 13530 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13531
13532 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13533 if (nid) {
13534 const char *name;
13535 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13536 name = "Speaker";
13537 else
13538 name = "Front";
13539 err = alc268_new_analog_output(spec, nid, name, 0);
13540 if (err < 0)
13541 return err;
13542 }
a361d84b
KY
13543
13544 nid = cfg->speaker_pins[0];
13545 if (nid == 0x1d) {
0afe5f89 13546 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13547 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13548 if (err < 0)
13549 return err;
7bfb9c03 13550 } else if (nid) {
3f3b7c1a
TI
13551 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13552 if (err < 0)
13553 return err;
a361d84b
KY
13554 }
13555 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13556 if (nid) {
13557 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13558 if (err < 0)
13559 return err;
13560 }
a361d84b
KY
13561
13562 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13563 if (nid == 0x16) {
0afe5f89 13564 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13565 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13566 if (err < 0)
13567 return err;
13568 }
ea1fb29a 13569 return 0;
a361d84b
KY
13570}
13571
13572/* create playback/capture controls for input pins */
05f5f477 13573static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13574 const struct auto_pin_cfg *cfg)
13575{
05f5f477 13576 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13577}
13578
e9af4f36
TI
13579static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13580 hda_nid_t nid, int pin_type)
13581{
13582 int idx;
13583
13584 alc_set_pin_output(codec, nid, pin_type);
13585 if (nid == 0x14 || nid == 0x16)
13586 idx = 0;
13587 else
13588 idx = 1;
13589 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13590}
13591
13592static void alc268_auto_init_multi_out(struct hda_codec *codec)
13593{
13594 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13595 int i;
13596
13597 for (i = 0; i < spec->autocfg.line_outs; i++) {
13598 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13599 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13600 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13601 }
13602}
13603
13604static void alc268_auto_init_hp_out(struct hda_codec *codec)
13605{
13606 struct alc_spec *spec = codec->spec;
13607 hda_nid_t pin;
e1ca7b4e 13608 int i;
e9af4f36 13609
e1ca7b4e
TI
13610 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13611 pin = spec->autocfg.hp_pins[i];
e9af4f36 13612 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13613 }
13614 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13615 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13616 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13617 }
13618 if (spec->autocfg.mono_out_pin)
13619 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13620 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13621}
13622
a361d84b
KY
13623static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13624{
13625 struct alc_spec *spec = codec->spec;
13626 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13627 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13628 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13629 unsigned int dac_vol1, dac_vol2;
13630
e9af4f36 13631 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13632 snd_hda_codec_write(codec, speaker_nid, 0,
13633 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13634 /* mute mixer inputs from 0x1d */
a361d84b
KY
13635 snd_hda_codec_write(codec, 0x0f, 0,
13636 AC_VERB_SET_AMP_GAIN_MUTE,
13637 AMP_IN_UNMUTE(1));
13638 snd_hda_codec_write(codec, 0x10, 0,
13639 AC_VERB_SET_AMP_GAIN_MUTE,
13640 AMP_IN_UNMUTE(1));
13641 } else {
e9af4f36 13642 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13643 snd_hda_codec_write(codec, 0x0f, 0,
13644 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13645 snd_hda_codec_write(codec, 0x10, 0,
13646 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13647 }
13648
13649 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13650 if (line_nid == 0x14)
a361d84b
KY
13651 dac_vol2 = AMP_OUT_ZERO;
13652 else if (line_nid == 0x15)
13653 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13654 if (hp_nid == 0x14)
a361d84b
KY
13655 dac_vol2 = AMP_OUT_ZERO;
13656 else if (hp_nid == 0x15)
13657 dac_vol1 = AMP_OUT_ZERO;
13658 if (line_nid != 0x16 || hp_nid != 0x16 ||
13659 spec->autocfg.line_out_pins[1] != 0x16 ||
13660 spec->autocfg.line_out_pins[2] != 0x16)
13661 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13662
13663 snd_hda_codec_write(codec, 0x02, 0,
13664 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13665 snd_hda_codec_write(codec, 0x03, 0,
13666 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13667}
13668
def319f9 13669/* pcm configuration: identical with ALC880 */
a361d84b
KY
13670#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13671#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13672#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13673#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13674
13675/*
13676 * BIOS auto configuration
13677 */
13678static int alc268_parse_auto_config(struct hda_codec *codec)
13679{
13680 struct alc_spec *spec = codec->spec;
13681 int err;
13682 static hda_nid_t alc268_ignore[] = { 0 };
13683
13684 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13685 alc268_ignore);
13686 if (err < 0)
13687 return err;
7e0e44d4
TI
13688 if (!spec->autocfg.line_outs) {
13689 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13690 spec->multiout.max_channels = 2;
13691 spec->no_analog = 1;
13692 goto dig_only;
13693 }
a361d84b 13694 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13695 }
a361d84b
KY
13696 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13697 if (err < 0)
13698 return err;
05f5f477 13699 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13700 if (err < 0)
13701 return err;
13702
13703 spec->multiout.max_channels = 2;
13704
7e0e44d4 13705 dig_only:
a361d84b 13706 /* digital only support output */
757899ac 13707 alc_auto_parse_digital(codec);
603c4019 13708 if (spec->kctls.list)
d88897ea 13709 add_mixer(spec, spec->kctls.list);
a361d84b 13710
892981ff 13711 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13712 add_mixer(spec, alc268_beep_mixer);
aef9d318 13713
d88897ea 13714 add_verb(spec, alc268_volume_init_verbs);
5908589f 13715 spec->num_mux_defs = 2;
61b9b9b1 13716 spec->input_mux = &spec->private_imux[0];
a361d84b 13717
776e184e
TI
13718 err = alc_auto_add_mic_boost(codec);
13719 if (err < 0)
13720 return err;
13721
6227cdce 13722 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13723
a361d84b
KY
13724 return 1;
13725}
13726
a361d84b
KY
13727#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13728
13729/* init callback for auto-configuration model -- overriding the default init */
13730static void alc268_auto_init(struct hda_codec *codec)
13731{
f6c7e546 13732 struct alc_spec *spec = codec->spec;
a361d84b
KY
13733 alc268_auto_init_multi_out(codec);
13734 alc268_auto_init_hp_out(codec);
13735 alc268_auto_init_mono_speaker_out(codec);
13736 alc268_auto_init_analog_input(codec);
757899ac 13737 alc_auto_init_digital(codec);
f6c7e546 13738 if (spec->unsol_event)
7fb0d78f 13739 alc_inithook(codec);
a361d84b
KY
13740}
13741
13742/*
13743 * configuration and preset
13744 */
ea734963 13745static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13746 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13747 [ALC268_3ST] = "3stack",
983f8ae4 13748 [ALC268_TOSHIBA] = "toshiba",
d273809e 13749 [ALC268_ACER] = "acer",
c238b4f4 13750 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13751 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13752 [ALC268_DELL] = "dell",
f12462c5 13753 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13754#ifdef CONFIG_SND_DEBUG
13755 [ALC268_TEST] = "test",
13756#endif
a361d84b
KY
13757 [ALC268_AUTO] = "auto",
13758};
13759
13760static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13761 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13762 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13763 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13764 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13765 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13766 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13767 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13768 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13769 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13770 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13771 /* almost compatible with toshiba but with optional digital outs;
13772 * auto-probing seems working fine
13773 */
8871e5b9 13774 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13775 ALC268_AUTO),
a361d84b 13776 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13777 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13778 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13779 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13780 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13781 {}
13782};
13783
3abf2f36
TI
13784/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13785static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13786 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13787 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13788 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13789 ALC268_TOSHIBA),
13790 {}
13791};
13792
a361d84b 13793static struct alc_config_preset alc268_presets[] = {
eb5a6621 13794 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13795 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13796 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13797 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13798 alc267_quanta_il1_verbs },
13799 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13800 .dac_nids = alc268_dac_nids,
13801 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13802 .adc_nids = alc268_adc_nids_alt,
13803 .hp_nid = 0x03,
13804 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13805 .channel_mode = alc268_modes,
4f5d1706
TI
13806 .unsol_event = alc_sku_unsol_event,
13807 .setup = alc267_quanta_il1_setup,
13808 .init_hook = alc_inithook,
eb5a6621 13809 },
a361d84b 13810 [ALC268_3ST] = {
aef9d318
TI
13811 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13812 alc268_beep_mixer },
a361d84b
KY
13813 .init_verbs = { alc268_base_init_verbs },
13814 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13815 .dac_nids = alc268_dac_nids,
13816 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13817 .adc_nids = alc268_adc_nids_alt,
e1406348 13818 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13819 .hp_nid = 0x03,
13820 .dig_out_nid = ALC268_DIGOUT_NID,
13821 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13822 .channel_mode = alc268_modes,
13823 .input_mux = &alc268_capture_source,
13824 },
d1a991a6 13825 [ALC268_TOSHIBA] = {
42171c17 13826 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13827 alc268_beep_mixer },
d273809e
TI
13828 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13829 alc268_toshiba_verbs },
d1a991a6
KY
13830 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13831 .dac_nids = alc268_dac_nids,
13832 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13833 .adc_nids = alc268_adc_nids_alt,
e1406348 13834 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13835 .hp_nid = 0x03,
13836 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13837 .channel_mode = alc268_modes,
13838 .input_mux = &alc268_capture_source,
d273809e 13839 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13840 .setup = alc268_toshiba_setup,
13841 .init_hook = alc268_toshiba_automute,
d273809e
TI
13842 },
13843 [ALC268_ACER] = {
432fd133 13844 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13845 alc268_beep_mixer },
d273809e
TI
13846 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13847 alc268_acer_verbs },
13848 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13849 .dac_nids = alc268_dac_nids,
13850 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13851 .adc_nids = alc268_adc_nids_alt,
e1406348 13852 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13853 .hp_nid = 0x02,
13854 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13855 .channel_mode = alc268_modes,
0ccb541c 13856 .input_mux = &alc268_acer_capture_source,
d273809e 13857 .unsol_event = alc268_acer_unsol_event,
889c4395 13858 .init_hook = alc268_acer_init_hook,
d1a991a6 13859 },
c238b4f4
TI
13860 [ALC268_ACER_DMIC] = {
13861 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13862 alc268_beep_mixer },
13863 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13864 alc268_acer_verbs },
13865 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13866 .dac_nids = alc268_dac_nids,
13867 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13868 .adc_nids = alc268_adc_nids_alt,
13869 .capsrc_nids = alc268_capsrc_nids,
13870 .hp_nid = 0x02,
13871 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13872 .channel_mode = alc268_modes,
13873 .input_mux = &alc268_acer_dmic_capture_source,
13874 .unsol_event = alc268_acer_unsol_event,
13875 .init_hook = alc268_acer_init_hook,
13876 },
8ef355da
KY
13877 [ALC268_ACER_ASPIRE_ONE] = {
13878 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13879 alc268_beep_mixer,
fdbc6626 13880 alc268_capture_nosrc_mixer },
8ef355da
KY
13881 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13882 alc268_acer_aspire_one_verbs },
13883 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13884 .dac_nids = alc268_dac_nids,
13885 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13886 .adc_nids = alc268_adc_nids_alt,
13887 .capsrc_nids = alc268_capsrc_nids,
13888 .hp_nid = 0x03,
13889 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13890 .channel_mode = alc268_modes,
8ef355da 13891 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13892 .setup = alc268_acer_lc_setup,
8ef355da
KY
13893 .init_hook = alc268_acer_lc_init_hook,
13894 },
3866f0b0 13895 [ALC268_DELL] = {
fdbc6626
TI
13896 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13897 alc268_capture_nosrc_mixer },
3866f0b0
TI
13898 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13899 alc268_dell_verbs },
13900 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13901 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13902 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13903 .adc_nids = alc268_adc_nids_alt,
13904 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13905 .hp_nid = 0x02,
13906 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13907 .channel_mode = alc268_modes,
a9fd4f3f 13908 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13909 .setup = alc268_dell_setup,
13910 .init_hook = alc_inithook,
3866f0b0 13911 },
f12462c5 13912 [ALC268_ZEPTO] = {
aef9d318
TI
13913 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13914 alc268_beep_mixer },
f12462c5
MT
13915 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13916 alc268_toshiba_verbs },
13917 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13918 .dac_nids = alc268_dac_nids,
13919 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13920 .adc_nids = alc268_adc_nids_alt,
e1406348 13921 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13922 .hp_nid = 0x03,
13923 .dig_out_nid = ALC268_DIGOUT_NID,
13924 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13925 .channel_mode = alc268_modes,
13926 .input_mux = &alc268_capture_source,
4f5d1706
TI
13927 .setup = alc268_toshiba_setup,
13928 .init_hook = alc268_toshiba_automute,
f12462c5 13929 },
86c53bd2
JW
13930#ifdef CONFIG_SND_DEBUG
13931 [ALC268_TEST] = {
13932 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13933 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13934 alc268_volume_init_verbs },
13935 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13936 .dac_nids = alc268_dac_nids,
13937 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13938 .adc_nids = alc268_adc_nids_alt,
e1406348 13939 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13940 .hp_nid = 0x03,
13941 .dig_out_nid = ALC268_DIGOUT_NID,
13942 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13943 .channel_mode = alc268_modes,
13944 .input_mux = &alc268_capture_source,
13945 },
13946#endif
a361d84b
KY
13947};
13948
13949static int patch_alc268(struct hda_codec *codec)
13950{
13951 struct alc_spec *spec;
13952 int board_config;
22971e3a 13953 int i, has_beep, err;
a361d84b 13954
ef86f581 13955 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13956 if (spec == NULL)
13957 return -ENOMEM;
13958
13959 codec->spec = spec;
13960
13961 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13962 alc268_models,
13963 alc268_cfg_tbl);
13964
3abf2f36
TI
13965 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13966 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13967 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13968
a361d84b 13969 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13970 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13971 codec->chip_name);
a361d84b
KY
13972 board_config = ALC268_AUTO;
13973 }
13974
13975 if (board_config == ALC268_AUTO) {
13976 /* automatic parse from the BIOS config */
13977 err = alc268_parse_auto_config(codec);
13978 if (err < 0) {
13979 alc_free(codec);
13980 return err;
13981 } else if (!err) {
13982 printk(KERN_INFO
13983 "hda_codec: Cannot set up configuration "
13984 "from BIOS. Using base mode...\n");
13985 board_config = ALC268_3ST;
13986 }
13987 }
13988
13989 if (board_config != ALC268_AUTO)
e9c364c0 13990 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13991
a361d84b
KY
13992 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13993 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13994 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13995
a361d84b
KY
13996 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13997
22971e3a
TI
13998 has_beep = 0;
13999 for (i = 0; i < spec->num_mixers; i++) {
14000 if (spec->mixers[i] == alc268_beep_mixer) {
14001 has_beep = 1;
14002 break;
14003 }
14004 }
14005
14006 if (has_beep) {
14007 err = snd_hda_attach_beep_device(codec, 0x1);
14008 if (err < 0) {
14009 alc_free(codec);
14010 return err;
14011 }
14012 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14013 /* override the amp caps for beep generator */
14014 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14015 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14016 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14017 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14018 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14019 }
aef9d318 14020
7e0e44d4 14021 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14022 /* check whether NID 0x07 is valid */
14023 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 14024 int i;
3866f0b0 14025
defb5ab2 14026 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14027 /* get type */
a22d543a 14028 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14029 if (spec->auto_mic ||
14030 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14031 spec->adc_nids = alc268_adc_nids_alt;
14032 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14033 if (spec->auto_mic)
14034 fixup_automic_adc(codec);
fdbc6626
TI
14035 if (spec->auto_mic || spec->input_mux->num_items == 1)
14036 add_mixer(spec, alc268_capture_nosrc_mixer);
14037 else
14038 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14039 } else {
14040 spec->adc_nids = alc268_adc_nids;
14041 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14042 add_mixer(spec, alc268_capture_mixer);
a361d84b 14043 }
85860c06
TI
14044 /* set default input source */
14045 for (i = 0; i < spec->num_adc_nids; i++)
14046 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14047 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
14048 i < spec->num_mux_defs ?
14049 spec->input_mux[i].items[0].index :
85860c06 14050 spec->input_mux->items[0].index);
a361d84b 14051 }
2134ea4f
TI
14052
14053 spec->vmaster_nid = 0x02;
14054
a361d84b
KY
14055 codec->patch_ops = alc_patch_ops;
14056 if (board_config == ALC268_AUTO)
14057 spec->init_hook = alc268_auto_init;
ea1fb29a 14058
bf1b0225
KY
14059 alc_init_jacks(codec);
14060
a361d84b
KY
14061 return 0;
14062}
14063
f6a92248
KY
14064/*
14065 * ALC269 channel source setting (2 channel)
14066 */
14067#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14068
14069#define alc269_dac_nids alc260_dac_nids
14070
14071static hda_nid_t alc269_adc_nids[1] = {
14072 /* ADC1 */
f53281e6
KY
14073 0x08,
14074};
14075
e01bf509
TI
14076static hda_nid_t alc269_capsrc_nids[1] = {
14077 0x23,
14078};
14079
84898e87
KY
14080static hda_nid_t alc269vb_adc_nids[1] = {
14081 /* ADC1 */
14082 0x09,
14083};
14084
14085static hda_nid_t alc269vb_capsrc_nids[1] = {
14086 0x22,
14087};
14088
6694635d
TI
14089static hda_nid_t alc269_adc_candidates[] = {
14090 0x08, 0x09, 0x07,
14091};
e01bf509 14092
f6a92248
KY
14093#define alc269_modes alc260_modes
14094#define alc269_capture_source alc880_lg_lw_capture_source
14095
14096static struct snd_kcontrol_new alc269_base_mixer[] = {
14097 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14098 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14099 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14100 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14101 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14103 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14104 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14105 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14106 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14107 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14108 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14109 { } /* end */
14110};
14111
60db6b53
KY
14112static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14113 /* output mixer control */
14114 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14115 {
14116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14117 .name = "Master Playback Switch",
5e26dfd0 14118 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14119 .info = snd_hda_mixer_amp_switch_info,
14120 .get = snd_hda_mixer_amp_switch_get,
14121 .put = alc268_acer_master_sw_put,
14122 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14123 },
14124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14126 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14127 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14128 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14129 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14130 { }
14131};
14132
64154835
TV
14133static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14134 /* output mixer control */
14135 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14136 {
14137 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14138 .name = "Master Playback Switch",
5e26dfd0 14139 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14140 .info = snd_hda_mixer_amp_switch_info,
14141 .get = snd_hda_mixer_amp_switch_get,
14142 .put = alc268_acer_master_sw_put,
14143 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14144 },
14145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14146 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14147 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14148 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14149 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14150 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14151 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14152 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14153 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14154 { }
14155};
14156
84898e87 14157static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14158 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14159 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14160 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14161 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14162 { } /* end */
14163};
14164
84898e87
KY
14165static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14166 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14167 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14168 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14169 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14170 { } /* end */
14171};
14172
fe3eb0a7
KY
14173static struct snd_kcontrol_new alc269_asus_mixer[] = {
14174 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14175 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14176 { } /* end */
14177};
14178
f53281e6 14179/* capture mixer elements */
84898e87
KY
14180static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14181 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14182 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14183 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14184 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14185 { } /* end */
14186};
14187
14188static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14189 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14190 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14191 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14192 { } /* end */
14193};
14194
84898e87
KY
14195static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14196 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14197 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14198 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14199 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14200 { } /* end */
14201};
14202
14203static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14204 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14205 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14206 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14207 { } /* end */
14208};
14209
26f5df26 14210/* FSC amilo */
84898e87 14211#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14212
60db6b53
KY
14213static struct hda_verb alc269_quanta_fl1_verbs[] = {
14214 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14215 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14216 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14217 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14218 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14219 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14220 { }
14221};
f6a92248 14222
64154835
TV
14223static struct hda_verb alc269_lifebook_verbs[] = {
14224 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14225 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14226 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14227 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14228 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14229 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14231 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14232 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14233 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14234 { }
14235};
14236
60db6b53
KY
14237/* toggle speaker-output according to the hp-jack state */
14238static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14239{
14240 unsigned int present;
14241 unsigned char bits;
f6a92248 14242
864f92be 14243 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14244 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14245 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14246 HDA_AMP_MUTE, bits);
60db6b53 14247 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14248 HDA_AMP_MUTE, bits);
f6a92248 14249
60db6b53
KY
14250 snd_hda_codec_write(codec, 0x20, 0,
14251 AC_VERB_SET_COEF_INDEX, 0x0c);
14252 snd_hda_codec_write(codec, 0x20, 0,
14253 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14254
60db6b53
KY
14255 snd_hda_codec_write(codec, 0x20, 0,
14256 AC_VERB_SET_COEF_INDEX, 0x0c);
14257 snd_hda_codec_write(codec, 0x20, 0,
14258 AC_VERB_SET_PROC_COEF, 0x480);
14259}
f6a92248 14260
64154835
TV
14261/* toggle speaker-output according to the hp-jacks state */
14262static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14263{
14264 unsigned int present;
14265 unsigned char bits;
14266
14267 /* Check laptop headphone socket */
864f92be 14268 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14269
14270 /* Check port replicator headphone socket */
864f92be 14271 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14272
5dbd5ec6 14273 bits = present ? HDA_AMP_MUTE : 0;
64154835 14274 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14275 HDA_AMP_MUTE, bits);
64154835 14276 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14277 HDA_AMP_MUTE, bits);
64154835
TV
14278
14279 snd_hda_codec_write(codec, 0x20, 0,
14280 AC_VERB_SET_COEF_INDEX, 0x0c);
14281 snd_hda_codec_write(codec, 0x20, 0,
14282 AC_VERB_SET_PROC_COEF, 0x680);
14283
14284 snd_hda_codec_write(codec, 0x20, 0,
14285 AC_VERB_SET_COEF_INDEX, 0x0c);
14286 snd_hda_codec_write(codec, 0x20, 0,
14287 AC_VERB_SET_PROC_COEF, 0x480);
14288}
14289
64154835
TV
14290static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14291{
14292 unsigned int present_laptop;
14293 unsigned int present_dock;
14294
864f92be
WF
14295 present_laptop = snd_hda_jack_detect(codec, 0x18);
14296 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14297
14298 /* Laptop mic port overrides dock mic port, design decision */
14299 if (present_dock)
14300 snd_hda_codec_write(codec, 0x23, 0,
14301 AC_VERB_SET_CONNECT_SEL, 0x3);
14302 if (present_laptop)
14303 snd_hda_codec_write(codec, 0x23, 0,
14304 AC_VERB_SET_CONNECT_SEL, 0x0);
14305 if (!present_dock && !present_laptop)
14306 snd_hda_codec_write(codec, 0x23, 0,
14307 AC_VERB_SET_CONNECT_SEL, 0x1);
14308}
14309
60db6b53
KY
14310static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14311 unsigned int res)
14312{
4f5d1706
TI
14313 switch (res >> 26) {
14314 case ALC880_HP_EVENT:
60db6b53 14315 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14316 break;
14317 case ALC880_MIC_EVENT:
14318 alc_mic_automute(codec);
14319 break;
14320 }
60db6b53 14321}
f6a92248 14322
64154835
TV
14323static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14324 unsigned int res)
14325{
14326 if ((res >> 26) == ALC880_HP_EVENT)
14327 alc269_lifebook_speaker_automute(codec);
14328 if ((res >> 26) == ALC880_MIC_EVENT)
14329 alc269_lifebook_mic_autoswitch(codec);
14330}
14331
4f5d1706
TI
14332static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14333{
14334 struct alc_spec *spec = codec->spec;
20645d70
TI
14335 spec->autocfg.hp_pins[0] = 0x15;
14336 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14337 spec->ext_mic.pin = 0x18;
14338 spec->ext_mic.mux_idx = 0;
14339 spec->int_mic.pin = 0x19;
14340 spec->int_mic.mux_idx = 1;
14341 spec->auto_mic = 1;
14342}
14343
60db6b53
KY
14344static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14345{
14346 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14347 alc_mic_automute(codec);
60db6b53 14348}
f6a92248 14349
64154835
TV
14350static void alc269_lifebook_init_hook(struct hda_codec *codec)
14351{
14352 alc269_lifebook_speaker_automute(codec);
14353 alc269_lifebook_mic_autoswitch(codec);
14354}
14355
84898e87 14356static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14357 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14358 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14359 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14360 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14361 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14362 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14363 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14364 {}
14365};
14366
84898e87 14367static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14368 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14369 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14370 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14371 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14372 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14373 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14374 {}
14375};
14376
84898e87
KY
14377static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14378 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14379 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14380 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14381 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14382 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14383 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14384 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14385 {}
14386};
14387
14388static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14389 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14390 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14391 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14392 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14393 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14394 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14395 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14396 {}
14397};
14398
fe3eb0a7
KY
14399static struct hda_verb alc271_acer_dmic_verbs[] = {
14400 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14401 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14402 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14403 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14404 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14405 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14406 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14407 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14408 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14409 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14410 { }
14411};
14412
f53281e6
KY
14413/* toggle speaker-output according to the hp-jack state */
14414static void alc269_speaker_automute(struct hda_codec *codec)
14415{
ebb83eeb
KY
14416 struct alc_spec *spec = codec->spec;
14417 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14418 unsigned int present;
60db6b53 14419 unsigned char bits;
f53281e6 14420
ebb83eeb 14421 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14422 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14423 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14424 HDA_AMP_MUTE, bits);
f53281e6 14425 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14426 HDA_AMP_MUTE, bits);
cd372fb3 14427 snd_hda_input_jack_report(codec, nid);
f53281e6
KY
14428}
14429
f53281e6 14430/* unsolicited event for HP jack sensing */
84898e87 14431static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14432 unsigned int res)
f53281e6 14433{
4f5d1706
TI
14434 switch (res >> 26) {
14435 case ALC880_HP_EVENT:
f53281e6 14436 alc269_speaker_automute(codec);
4f5d1706
TI
14437 break;
14438 case ALC880_MIC_EVENT:
14439 alc_mic_automute(codec);
14440 break;
14441 }
f53281e6
KY
14442}
14443
226b1ec8 14444static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14445{
4f5d1706 14446 struct alc_spec *spec = codec->spec;
20645d70
TI
14447 spec->autocfg.hp_pins[0] = 0x15;
14448 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14449 spec->ext_mic.pin = 0x18;
14450 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14451 spec->int_mic.pin = 0x19;
14452 spec->int_mic.mux_idx = 1;
4f5d1706 14453 spec->auto_mic = 1;
f53281e6
KY
14454}
14455
226b1ec8 14456static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14457{
14458 struct alc_spec *spec = codec->spec;
20645d70
TI
14459 spec->autocfg.hp_pins[0] = 0x15;
14460 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14461 spec->ext_mic.pin = 0x18;
14462 spec->ext_mic.mux_idx = 0;
14463 spec->int_mic.pin = 0x12;
226b1ec8 14464 spec->int_mic.mux_idx = 5;
84898e87
KY
14465 spec->auto_mic = 1;
14466}
14467
226b1ec8 14468static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14469{
4f5d1706 14470 struct alc_spec *spec = codec->spec;
226b1ec8 14471 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14472 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14473 spec->ext_mic.pin = 0x18;
14474 spec->ext_mic.mux_idx = 0;
14475 spec->int_mic.pin = 0x19;
14476 spec->int_mic.mux_idx = 1;
14477 spec->auto_mic = 1;
f53281e6
KY
14478}
14479
226b1ec8
KY
14480static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14481{
14482 struct alc_spec *spec = codec->spec;
14483 spec->autocfg.hp_pins[0] = 0x21;
14484 spec->autocfg.speaker_pins[0] = 0x14;
14485 spec->ext_mic.pin = 0x18;
14486 spec->ext_mic.mux_idx = 0;
14487 spec->int_mic.pin = 0x12;
14488 spec->int_mic.mux_idx = 6;
14489 spec->auto_mic = 1;
14490}
14491
84898e87 14492static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14493{
14494 alc269_speaker_automute(codec);
4f5d1706 14495 alc_mic_automute(codec);
f53281e6
KY
14496}
14497
60db6b53
KY
14498/*
14499 * generic initialization of ADC, input mixers and output mixers
14500 */
14501static struct hda_verb alc269_init_verbs[] = {
14502 /*
14503 * Unmute ADC0 and set the default input to mic-in
14504 */
84898e87 14505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14506
14507 /*
84898e87 14508 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14509 */
14510 /* set vol=0 to output mixers */
14511 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14512 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14513
14514 /* set up input amps for analog loopback */
14515 /* Amp Indices: DAC = 0, mixer = 1 */
14516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14519 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14520 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14521 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14522
14523 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14525 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14526 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14527 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14530
14531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14532 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14533
84898e87
KY
14534 /* FIXME: use Mux-type input source selection */
14535 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14536 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14537 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14538
84898e87
KY
14539 /* set EAPD */
14540 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14541 { }
14542};
14543
14544static struct hda_verb alc269vb_init_verbs[] = {
14545 /*
14546 * Unmute ADC0 and set the default input to mic-in
14547 */
14548 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14549
14550 /*
14551 * Set up output mixers (0x02 - 0x03)
14552 */
14553 /* set vol=0 to output mixers */
14554 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14555 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14556
14557 /* set up input amps for analog loopback */
14558 /* Amp Indices: DAC = 0, mixer = 1 */
14559 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14560 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14561 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14562 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14563 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14564 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14565
14566 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14567 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14568 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14569 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14570 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14571 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14572 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14573
14574 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14575 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14576
14577 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14578 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14579 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14580 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14581
14582 /* set EAPD */
14583 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14584 { }
14585};
14586
9d0b71b1
TI
14587#define alc269_auto_create_multi_out_ctls \
14588 alc268_auto_create_multi_out_ctls
05f5f477
TI
14589#define alc269_auto_create_input_ctls \
14590 alc268_auto_create_input_ctls
f6a92248
KY
14591
14592#ifdef CONFIG_SND_HDA_POWER_SAVE
14593#define alc269_loopbacks alc880_loopbacks
14594#endif
14595
def319f9 14596/* pcm configuration: identical with ALC880 */
f6a92248
KY
14597#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14598#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14599#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14600#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14601
f03d3115
TI
14602static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14603 .substreams = 1,
14604 .channels_min = 2,
14605 .channels_max = 8,
14606 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14607 /* NID is set in alc_build_pcms */
14608 .ops = {
14609 .open = alc880_playback_pcm_open,
14610 .prepare = alc880_playback_pcm_prepare,
14611 .cleanup = alc880_playback_pcm_cleanup
14612 },
14613};
14614
14615static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14616 .substreams = 1,
14617 .channels_min = 2,
14618 .channels_max = 2,
14619 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14620 /* NID is set in alc_build_pcms */
14621};
14622
ad35879a
TI
14623#ifdef CONFIG_SND_HDA_POWER_SAVE
14624static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14625{
14626 switch (codec->subsystem_id) {
14627 case 0x103c1586:
14628 return 1;
14629 }
14630 return 0;
14631}
14632
14633static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14634{
14635 /* update mute-LED according to the speaker mute state */
14636 if (nid == 0x01 || nid == 0x14) {
14637 int pinval;
14638 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14639 HDA_AMP_MUTE)
14640 pinval = 0x24;
14641 else
14642 pinval = 0x20;
14643 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14644 snd_hda_codec_update_cache(codec, 0x19, 0,
14645 AC_VERB_SET_PIN_WIDGET_CONTROL,
14646 pinval);
ad35879a
TI
14647 }
14648 return alc_check_power_status(codec, nid);
14649}
14650#endif /* CONFIG_SND_HDA_POWER_SAVE */
14651
840b64c0
TI
14652static int alc275_setup_dual_adc(struct hda_codec *codec)
14653{
14654 struct alc_spec *spec = codec->spec;
14655
14656 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14657 return 0;
14658 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14659 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14660 if (spec->ext_mic.pin <= 0x12) {
14661 spec->private_adc_nids[0] = 0x08;
14662 spec->private_adc_nids[1] = 0x11;
14663 spec->private_capsrc_nids[0] = 0x23;
14664 spec->private_capsrc_nids[1] = 0x22;
14665 } else {
14666 spec->private_adc_nids[0] = 0x11;
14667 spec->private_adc_nids[1] = 0x08;
14668 spec->private_capsrc_nids[0] = 0x22;
14669 spec->private_capsrc_nids[1] = 0x23;
14670 }
14671 spec->adc_nids = spec->private_adc_nids;
14672 spec->capsrc_nids = spec->private_capsrc_nids;
14673 spec->num_adc_nids = 2;
14674 spec->dual_adc_switch = 1;
14675 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14676 spec->adc_nids[0], spec->adc_nids[1]);
14677 return 1;
14678 }
14679 return 0;
14680}
14681
d433a678
TI
14682/* different alc269-variants */
14683enum {
14684 ALC269_TYPE_NORMAL,
48c88e82 14685 ALC269_TYPE_ALC258,
d433a678 14686 ALC269_TYPE_ALC259,
48c88e82
KY
14687 ALC269_TYPE_ALC269VB,
14688 ALC269_TYPE_ALC270,
d433a678
TI
14689 ALC269_TYPE_ALC271X,
14690};
14691
f6a92248
KY
14692/*
14693 * BIOS auto configuration
14694 */
14695static int alc269_parse_auto_config(struct hda_codec *codec)
14696{
14697 struct alc_spec *spec = codec->spec;
cfb9fb55 14698 int err;
f6a92248
KY
14699 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14700
14701 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14702 alc269_ignore);
14703 if (err < 0)
14704 return err;
14705
14706 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14707 if (err < 0)
14708 return err;
f3550d1b
TI
14709 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14710 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14711 else
14712 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14713 0x22, 0);
f6a92248
KY
14714 if (err < 0)
14715 return err;
14716
14717 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14718
757899ac 14719 alc_auto_parse_digital(codec);
f6a92248 14720
603c4019 14721 if (spec->kctls.list)
d88897ea 14722 add_mixer(spec, spec->kctls.list);
f6a92248 14723
d433a678 14724 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14725 add_verb(spec, alc269vb_init_verbs);
6227cdce 14726 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14727 } else {
14728 add_verb(spec, alc269_init_verbs);
6227cdce 14729 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14730 }
14731
f6a92248 14732 spec->num_mux_defs = 1;
61b9b9b1 14733 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14734
14735 if (!alc275_setup_dual_adc(codec))
14736 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14737 sizeof(alc269_adc_candidates));
6694635d 14738
e01bf509 14739 /* set default input source */
840b64c0 14740 if (!spec->dual_adc_switch)
748cce43
TI
14741 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14742 spec->input_mux->items[0].index);
f6a92248
KY
14743
14744 err = alc_auto_add_mic_boost(codec);
14745 if (err < 0)
14746 return err;
14747
7e0e44d4 14748 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14749 set_capture_mixer(codec);
f53281e6 14750
f6a92248
KY
14751 return 1;
14752}
14753
e9af4f36
TI
14754#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14755#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14756#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14757
14758
14759/* init callback for auto-configuration model -- overriding the default init */
14760static void alc269_auto_init(struct hda_codec *codec)
14761{
f6c7e546 14762 struct alc_spec *spec = codec->spec;
f6a92248
KY
14763 alc269_auto_init_multi_out(codec);
14764 alc269_auto_init_hp_out(codec);
14765 alc269_auto_init_analog_input(codec);
757899ac 14766 alc_auto_init_digital(codec);
f6c7e546 14767 if (spec->unsol_event)
7fb0d78f 14768 alc_inithook(codec);
f6a92248
KY
14769}
14770
0ec33d1f
TI
14771#ifdef SND_HDA_NEEDS_RESUME
14772static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14773{
14774 int val = alc_read_coef_idx(codec, 0x04);
14775 if (power_up)
14776 val |= 1 << 11;
14777 else
14778 val &= ~(1 << 11);
14779 alc_write_coef_idx(codec, 0x04, val);
14780}
14781
977ddd6b
KY
14782#ifdef CONFIG_SND_HDA_POWER_SAVE
14783static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14784{
14785 struct alc_spec *spec = codec->spec;
977ddd6b 14786
0ec33d1f
TI
14787 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14788 alc269_toggle_power_output(codec, 0);
977ddd6b 14789 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14790 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14791 msleep(150);
14792 }
14793
14794 alc_shutup(codec);
14795 if (spec && spec->power_hook)
14796 spec->power_hook(codec);
14797 return 0;
14798}
0ec33d1f
TI
14799#endif /* CONFIG_SND_HDA_POWER_SAVE */
14800
977ddd6b
KY
14801static int alc269_resume(struct hda_codec *codec)
14802{
977ddd6b 14803 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14804 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14805 msleep(150);
14806 }
14807
14808 codec->patch_ops.init(codec);
14809
14810 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14811 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14812 msleep(200);
14813 }
14814
0ec33d1f
TI
14815 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14816 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14817
14818 snd_hda_codec_resume_amp(codec);
14819 snd_hda_codec_resume_cache(codec);
9e5341b9 14820 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14821 return 0;
14822}
0ec33d1f 14823#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14824
1a99d4a4 14825static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14826 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14827{
14828 int coef;
14829
58701120 14830 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14831 return;
1a99d4a4
KY
14832 coef = alc_read_coef_idx(codec, 0x1e);
14833 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14834}
14835
ff818c24
TI
14836enum {
14837 ALC269_FIXUP_SONY_VAIO,
74dc8909 14838 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14839 ALC269_FIXUP_DELL_M101Z,
022c92be 14840 ALC269_FIXUP_SKU_IGNORE,
ac612407 14841 ALC269_FIXUP_ASUS_G73JW,
357f915e 14842 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14843 ALC275_FIXUP_SONY_HWEQ,
ff818c24
TI
14844};
14845
ff818c24
TI
14846static const struct alc_fixup alc269_fixups[] = {
14847 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14848 .type = ALC_FIXUP_VERBS,
14849 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14850 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14851 {}
14852 }
ff818c24 14853 },
74dc8909 14854 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14855 .type = ALC_FIXUP_VERBS,
14856 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14857 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14858 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14859 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14860 { }
b5bfbc67
TI
14861 },
14862 .chained = true,
14863 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14864 },
145a902b 14865 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14866 .type = ALC_FIXUP_VERBS,
14867 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14868 /* Enables internal speaker */
14869 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14870 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14871 {}
14872 }
14873 },
022c92be 14874 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14875 .type = ALC_FIXUP_SKU,
14876 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14877 },
ac612407 14878 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14879 .type = ALC_FIXUP_PINS,
14880 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14881 { 0x17, 0x99130111 }, /* subwoofer */
14882 { }
14883 }
14884 },
357f915e 14885 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14886 .type = ALC_FIXUP_VERBS,
14887 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14888 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14889 {}
14890 }
14891 },
1a99d4a4 14892 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14893 .type = ALC_FIXUP_FUNC,
14894 .v.func = alc269_fixup_hweq,
14895 .chained = true,
14896 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
1a99d4a4 14897 }
ff818c24
TI
14898};
14899
14900static struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14901 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14902 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14903 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14904 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14905 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
022c92be 14906 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14907 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14908 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14909 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14910 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14911 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14912 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14913 {}
14914};
14915
14916
f6a92248
KY
14917/*
14918 * configuration and preset
14919 */
ea734963 14920static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14921 [ALC269_BASIC] = "basic",
2922c9af 14922 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14923 [ALC269_AMIC] = "laptop-amic",
14924 [ALC269_DMIC] = "laptop-dmic",
64154835 14925 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14926 [ALC269_LIFEBOOK] = "lifebook",
14927 [ALC269_AUTO] = "auto",
f6a92248
KY
14928};
14929
14930static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14931 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14932 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14933 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14934 ALC269_AMIC),
14935 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14936 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14937 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14938 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14939 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14940 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14941 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14942 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14943 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14944 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14945 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14946 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14947 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14948 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14949 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14950 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14951 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14952 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14953 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14954 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14955 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14956 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14957 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14958 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14959 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14960 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14961 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14962 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14963 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14964 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14965 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14966 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14967 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14968 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14969 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14970 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14971 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14972 ALC269_DMIC),
60db6b53 14973 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14974 ALC269_DMIC),
14975 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14976 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14977 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14978 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14979 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14980 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14981 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14982 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14983 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14984 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14985 {}
14986};
14987
14988static struct alc_config_preset alc269_presets[] = {
14989 [ALC269_BASIC] = {
f9e336f6 14990 .mixers = { alc269_base_mixer },
f6a92248
KY
14991 .init_verbs = { alc269_init_verbs },
14992 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14993 .dac_nids = alc269_dac_nids,
14994 .hp_nid = 0x03,
14995 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14996 .channel_mode = alc269_modes,
14997 .input_mux = &alc269_capture_source,
14998 },
60db6b53
KY
14999 [ALC269_QUANTA_FL1] = {
15000 .mixers = { alc269_quanta_fl1_mixer },
15001 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15002 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15003 .dac_nids = alc269_dac_nids,
15004 .hp_nid = 0x03,
15005 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15006 .channel_mode = alc269_modes,
15007 .input_mux = &alc269_capture_source,
15008 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15009 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15010 .init_hook = alc269_quanta_fl1_init_hook,
15011 },
84898e87
KY
15012 [ALC269_AMIC] = {
15013 .mixers = { alc269_laptop_mixer },
15014 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15015 .init_verbs = { alc269_init_verbs,
84898e87 15016 alc269_laptop_amic_init_verbs },
f53281e6
KY
15017 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15018 .dac_nids = alc269_dac_nids,
15019 .hp_nid = 0x03,
15020 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15021 .channel_mode = alc269_modes,
84898e87
KY
15022 .unsol_event = alc269_laptop_unsol_event,
15023 .setup = alc269_laptop_amic_setup,
15024 .init_hook = alc269_laptop_inithook,
f53281e6 15025 },
84898e87
KY
15026 [ALC269_DMIC] = {
15027 .mixers = { alc269_laptop_mixer },
15028 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15029 .init_verbs = { alc269_init_verbs,
84898e87
KY
15030 alc269_laptop_dmic_init_verbs },
15031 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15032 .dac_nids = alc269_dac_nids,
15033 .hp_nid = 0x03,
15034 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15035 .channel_mode = alc269_modes,
15036 .unsol_event = alc269_laptop_unsol_event,
15037 .setup = alc269_laptop_dmic_setup,
15038 .init_hook = alc269_laptop_inithook,
15039 },
15040 [ALC269VB_AMIC] = {
15041 .mixers = { alc269vb_laptop_mixer },
15042 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15043 .init_verbs = { alc269vb_init_verbs,
15044 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15045 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15046 .dac_nids = alc269_dac_nids,
15047 .hp_nid = 0x03,
15048 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15049 .channel_mode = alc269_modes,
84898e87 15050 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 15051 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
15052 .init_hook = alc269_laptop_inithook,
15053 },
15054 [ALC269VB_DMIC] = {
15055 .mixers = { alc269vb_laptop_mixer },
15056 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15057 .init_verbs = { alc269vb_init_verbs,
15058 alc269vb_laptop_dmic_init_verbs },
15059 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15060 .dac_nids = alc269_dac_nids,
15061 .hp_nid = 0x03,
15062 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15063 .channel_mode = alc269_modes,
15064 .unsol_event = alc269_laptop_unsol_event,
15065 .setup = alc269vb_laptop_dmic_setup,
15066 .init_hook = alc269_laptop_inithook,
f53281e6 15067 },
26f5df26 15068 [ALC269_FUJITSU] = {
45bdd1c1 15069 .mixers = { alc269_fujitsu_mixer },
84898e87 15070 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15071 .init_verbs = { alc269_init_verbs,
84898e87 15072 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15073 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15074 .dac_nids = alc269_dac_nids,
15075 .hp_nid = 0x03,
15076 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15077 .channel_mode = alc269_modes,
84898e87
KY
15078 .unsol_event = alc269_laptop_unsol_event,
15079 .setup = alc269_laptop_dmic_setup,
15080 .init_hook = alc269_laptop_inithook,
26f5df26 15081 },
64154835
TV
15082 [ALC269_LIFEBOOK] = {
15083 .mixers = { alc269_lifebook_mixer },
15084 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15085 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15086 .dac_nids = alc269_dac_nids,
15087 .hp_nid = 0x03,
15088 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15089 .channel_mode = alc269_modes,
15090 .input_mux = &alc269_capture_source,
15091 .unsol_event = alc269_lifebook_unsol_event,
15092 .init_hook = alc269_lifebook_init_hook,
15093 },
fe3eb0a7
KY
15094 [ALC271_ACER] = {
15095 .mixers = { alc269_asus_mixer },
15096 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15097 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15098 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15099 .dac_nids = alc269_dac_nids,
15100 .adc_nids = alc262_dmic_adc_nids,
15101 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15102 .capsrc_nids = alc262_dmic_capsrc_nids,
15103 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15104 .channel_mode = alc269_modes,
15105 .input_mux = &alc269_capture_source,
15106 .dig_out_nid = ALC880_DIGOUT_NID,
15107 .unsol_event = alc_sku_unsol_event,
15108 .setup = alc269vb_laptop_dmic_setup,
15109 .init_hook = alc_inithook,
15110 },
f6a92248
KY
15111};
15112
977ddd6b
KY
15113static int alc269_fill_coef(struct hda_codec *codec)
15114{
15115 int val;
15116
15117 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15118 alc_write_coef_idx(codec, 0xf, 0x960b);
15119 alc_write_coef_idx(codec, 0xe, 0x8817);
15120 }
15121
15122 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15123 alc_write_coef_idx(codec, 0xf, 0x960b);
15124 alc_write_coef_idx(codec, 0xe, 0x8814);
15125 }
15126
15127 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15128 val = alc_read_coef_idx(codec, 0x04);
15129 /* Power up output pin */
15130 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15131 }
15132
15133 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15134 val = alc_read_coef_idx(codec, 0xd);
15135 if ((val & 0x0c00) >> 10 != 0x1) {
15136 /* Capless ramp up clock control */
15137 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15138 }
15139 val = alc_read_coef_idx(codec, 0x17);
15140 if ((val & 0x01c0) >> 6 != 0x4) {
15141 /* Class D power on reset */
15142 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15143 }
15144 }
15145 return 0;
15146}
15147
f6a92248
KY
15148static int patch_alc269(struct hda_codec *codec)
15149{
15150 struct alc_spec *spec;
48c88e82 15151 int board_config, coef;
f6a92248
KY
15152 int err;
15153
15154 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15155 if (spec == NULL)
15156 return -ENOMEM;
15157
15158 codec->spec = spec;
15159
da00c244
KY
15160 alc_auto_parse_customize_define(codec);
15161
c793bec5
KY
15162 if (codec->vendor_id == 0x10ec0269) {
15163 coef = alc_read_coef_idx(codec, 0);
15164 if ((coef & 0x00f0) == 0x0010) {
15165 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15166 spec->cdefine.platform_type == 1) {
15167 alc_codec_rename(codec, "ALC271X");
15168 spec->codec_variant = ALC269_TYPE_ALC271X;
15169 } else if ((coef & 0xf000) == 0x1000) {
15170 spec->codec_variant = ALC269_TYPE_ALC270;
15171 } else if ((coef & 0xf000) == 0x2000) {
15172 alc_codec_rename(codec, "ALC259");
15173 spec->codec_variant = ALC269_TYPE_ALC259;
15174 } else if ((coef & 0xf000) == 0x3000) {
15175 alc_codec_rename(codec, "ALC258");
15176 spec->codec_variant = ALC269_TYPE_ALC258;
15177 } else {
15178 alc_codec_rename(codec, "ALC269VB");
15179 spec->codec_variant = ALC269_TYPE_ALC269VB;
15180 }
15181 } else
15182 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15183 alc269_fill_coef(codec);
15184 }
977ddd6b 15185
f6a92248
KY
15186 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15187 alc269_models,
15188 alc269_cfg_tbl);
15189
15190 if (board_config < 0) {
9a11f1aa
TI
15191 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15192 codec->chip_name);
f6a92248
KY
15193 board_config = ALC269_AUTO;
15194 }
15195
b5bfbc67
TI
15196 if (board_config == ALC269_AUTO) {
15197 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15198 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15199 }
ff818c24 15200
f6a92248
KY
15201 if (board_config == ALC269_AUTO) {
15202 /* automatic parse from the BIOS config */
15203 err = alc269_parse_auto_config(codec);
15204 if (err < 0) {
15205 alc_free(codec);
15206 return err;
15207 } else if (!err) {
15208 printk(KERN_INFO
15209 "hda_codec: Cannot set up configuration "
15210 "from BIOS. Using base mode...\n");
15211 board_config = ALC269_BASIC;
15212 }
15213 }
15214
dc1eae25 15215 if (has_cdefine_beep(codec)) {
8af2591d
TI
15216 err = snd_hda_attach_beep_device(codec, 0x1);
15217 if (err < 0) {
15218 alc_free(codec);
15219 return err;
15220 }
680cd536
KK
15221 }
15222
f6a92248 15223 if (board_config != ALC269_AUTO)
e9c364c0 15224 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15225
84898e87 15226 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15227 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15228 * fix the sample rate of analog I/O to 44.1kHz
15229 */
15230 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15231 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15232 } else if (spec->dual_adc_switch) {
15233 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15234 /* switch ADC dynamically */
15235 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15236 } else {
15237 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15238 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15239 }
f6a92248
KY
15240 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15241 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15242
6694635d 15243 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15244 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15245 spec->adc_nids = alc269_adc_nids;
15246 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15247 spec->capsrc_nids = alc269_capsrc_nids;
15248 } else {
15249 spec->adc_nids = alc269vb_adc_nids;
15250 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15251 spec->capsrc_nids = alc269vb_capsrc_nids;
15252 }
84898e87
KY
15253 }
15254
f9e336f6 15255 if (!spec->cap_mixer)
b59bdf3b 15256 set_capture_mixer(codec);
dc1eae25 15257 if (has_cdefine_beep(codec))
da00c244 15258 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15259
b5bfbc67 15260 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15261
100d5eb3
TI
15262 spec->vmaster_nid = 0x02;
15263
f6a92248 15264 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15265#ifdef CONFIG_SND_HDA_POWER_SAVE
15266 codec->patch_ops.suspend = alc269_suspend;
15267#endif
15268#ifdef SND_HDA_NEEDS_RESUME
15269 codec->patch_ops.resume = alc269_resume;
15270#endif
f6a92248
KY
15271 if (board_config == ALC269_AUTO)
15272 spec->init_hook = alc269_auto_init;
bf1b0225
KY
15273
15274 alc_init_jacks(codec);
f6a92248
KY
15275#ifdef CONFIG_SND_HDA_POWER_SAVE
15276 if (!spec->loopback.amplist)
15277 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15278 if (alc269_mic2_for_mute_led(codec))
15279 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15280#endif
15281
15282 return 0;
15283}
15284
df694daa
KY
15285/*
15286 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15287 */
15288
15289/*
15290 * set the path ways for 2 channel output
15291 * need to set the codec line out and mic 1 pin widgets to inputs
15292 */
15293static struct hda_verb alc861_threestack_ch2_init[] = {
15294 /* set pin widget 1Ah (line in) for input */
15295 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15296 /* set pin widget 18h (mic1/2) for input, for mic also enable
15297 * the vref
15298 */
df694daa
KY
15299 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15300
9c7f852e
TI
15301 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15302#if 0
15303 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15304 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15305#endif
df694daa
KY
15306 { } /* end */
15307};
15308/*
15309 * 6ch mode
15310 * need to set the codec line out and mic 1 pin widgets to outputs
15311 */
15312static struct hda_verb alc861_threestack_ch6_init[] = {
15313 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15314 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15315 /* set pin widget 18h (mic1) for output (CLFE)*/
15316 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15317
15318 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15319 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15320
9c7f852e
TI
15321 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15322#if 0
15323 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15324 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15325#endif
df694daa
KY
15326 { } /* end */
15327};
15328
15329static struct hda_channel_mode alc861_threestack_modes[2] = {
15330 { 2, alc861_threestack_ch2_init },
15331 { 6, alc861_threestack_ch6_init },
15332};
22309c3e
TI
15333/* Set mic1 as input and unmute the mixer */
15334static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15335 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15336 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15337 { } /* end */
15338};
15339/* Set mic1 as output and mute mixer */
15340static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15341 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15342 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15343 { } /* end */
15344};
15345
15346static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15347 { 2, alc861_uniwill_m31_ch2_init },
15348 { 4, alc861_uniwill_m31_ch4_init },
15349};
df694daa 15350
7cdbff94
MD
15351/* Set mic1 and line-in as input and unmute the mixer */
15352static struct hda_verb alc861_asus_ch2_init[] = {
15353 /* set pin widget 1Ah (line in) for input */
15354 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15355 /* set pin widget 18h (mic1/2) for input, for mic also enable
15356 * the vref
15357 */
7cdbff94
MD
15358 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15359
15360 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15361#if 0
15362 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15363 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15364#endif
15365 { } /* end */
15366};
15367/* Set mic1 nad line-in as output and mute mixer */
15368static struct hda_verb alc861_asus_ch6_init[] = {
15369 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15370 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15371 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15372 /* set pin widget 18h (mic1) for output (CLFE)*/
15373 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15374 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15375 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15376 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15377
15378 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15379#if 0
15380 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15381 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15382#endif
15383 { } /* end */
15384};
15385
15386static struct hda_channel_mode alc861_asus_modes[2] = {
15387 { 2, alc861_asus_ch2_init },
15388 { 6, alc861_asus_ch6_init },
15389};
15390
df694daa
KY
15391/* patch-ALC861 */
15392
15393static struct snd_kcontrol_new alc861_base_mixer[] = {
15394 /* output mixer control */
15395 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15396 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15397 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15398 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15399 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15400
15401 /*Input mixer control */
15402 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15403 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15404 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15405 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15406 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15407 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15408 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15409 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15410 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15412
df694daa
KY
15413 { } /* end */
15414};
15415
15416static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15417 /* output mixer control */
15418 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15419 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15420 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15421 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15422 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15423
15424 /* Input mixer control */
15425 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15426 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15427 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15428 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15429 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15430 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15432 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15433 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15434 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15435
df694daa
KY
15436 {
15437 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15438 .name = "Channel Mode",
15439 .info = alc_ch_mode_info,
15440 .get = alc_ch_mode_get,
15441 .put = alc_ch_mode_put,
15442 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15443 },
15444 { } /* end */
a53d1aec
TD
15445};
15446
d1d985f0 15447static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15448 /* output mixer control */
15449 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15450 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15451 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15452
a53d1aec 15453 { } /* end */
f12ab1e0 15454};
a53d1aec 15455
22309c3e
TI
15456static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15457 /* output mixer control */
15458 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15459 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15460 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15462 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15463
15464 /* Input mixer control */
15465 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15466 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15467 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15468 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15469 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15470 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15472 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15473 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15474 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15475
22309c3e
TI
15476 {
15477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15478 .name = "Channel Mode",
15479 .info = alc_ch_mode_info,
15480 .get = alc_ch_mode_get,
15481 .put = alc_ch_mode_put,
15482 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15483 },
15484 { } /* end */
f12ab1e0 15485};
7cdbff94
MD
15486
15487static struct snd_kcontrol_new alc861_asus_mixer[] = {
15488 /* output mixer control */
15489 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15490 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15491 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15492 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15493 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15494
15495 /* Input mixer control */
15496 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15497 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15498 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15499 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15500 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15501 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15502 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15503 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15504 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15506
7cdbff94
MD
15507 {
15508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15509 .name = "Channel Mode",
15510 .info = alc_ch_mode_info,
15511 .get = alc_ch_mode_get,
15512 .put = alc_ch_mode_put,
15513 .private_value = ARRAY_SIZE(alc861_asus_modes),
15514 },
15515 { }
56bb0cab
TI
15516};
15517
15518/* additional mixer */
d1d985f0 15519static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15520 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15521 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15522 { }
15523};
7cdbff94 15524
df694daa
KY
15525/*
15526 * generic initialization of ADC, input mixers and output mixers
15527 */
15528static struct hda_verb alc861_base_init_verbs[] = {
15529 /*
15530 * Unmute ADC0 and set the default input to mic-in
15531 */
15532 /* port-A for surround (rear panel) */
15533 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15534 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15535 /* port-B for mic-in (rear panel) with vref */
15536 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15537 /* port-C for line-in (rear panel) */
15538 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15539 /* port-D for Front */
15540 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15541 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15542 /* port-E for HP out (front panel) */
15543 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15544 /* route front PCM to HP */
9dece1d7 15545 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15546 /* port-F for mic-in (front panel) with vref */
15547 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15548 /* port-G for CLFE (rear panel) */
15549 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15550 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15551 /* port-H for side (rear panel) */
15552 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15553 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15554 /* CD-in */
15555 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15556 /* route front mic to ADC1*/
15557 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15558 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15559
df694daa
KY
15560 /* Unmute DAC0~3 & spdif out*/
15561 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15562 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15563 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15564 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15566
df694daa
KY
15567 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15568 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15569 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15570 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15571 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15572
df694daa
KY
15573 /* Unmute Stereo Mixer 15 */
15574 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15578
15579 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15580 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15581 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15582 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15583 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15585 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15587 /* hp used DAC 3 (Front) */
15588 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15590
15591 { }
15592};
15593
15594static struct hda_verb alc861_threestack_init_verbs[] = {
15595 /*
15596 * Unmute ADC0 and set the default input to mic-in
15597 */
15598 /* port-A for surround (rear panel) */
15599 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15600 /* port-B for mic-in (rear panel) with vref */
15601 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15602 /* port-C for line-in (rear panel) */
15603 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15604 /* port-D for Front */
15605 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15606 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15607 /* port-E for HP out (front panel) */
15608 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15609 /* route front PCM to HP */
9dece1d7 15610 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15611 /* port-F for mic-in (front panel) with vref */
15612 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15613 /* port-G for CLFE (rear panel) */
15614 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15615 /* port-H for side (rear panel) */
15616 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15617 /* CD-in */
15618 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15619 /* route front mic to ADC1*/
15620 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15621 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15622 /* Unmute DAC0~3 & spdif out*/
15623 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15624 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15625 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15626 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15627 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15628
df694daa
KY
15629 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15630 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15631 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15632 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15633 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15634
df694daa
KY
15635 /* Unmute Stereo Mixer 15 */
15636 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15640
15641 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15642 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15643 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15644 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15645 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15646 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15647 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15648 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15649 /* hp used DAC 3 (Front) */
15650 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15651 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15652 { }
15653};
22309c3e
TI
15654
15655static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15656 /*
15657 * Unmute ADC0 and set the default input to mic-in
15658 */
15659 /* port-A for surround (rear panel) */
15660 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15661 /* port-B for mic-in (rear panel) with vref */
15662 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15663 /* port-C for line-in (rear panel) */
15664 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15665 /* port-D for Front */
15666 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15667 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15668 /* port-E for HP out (front panel) */
f12ab1e0
TI
15669 /* this has to be set to VREF80 */
15670 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15671 /* route front PCM to HP */
9dece1d7 15672 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15673 /* port-F for mic-in (front panel) with vref */
15674 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15675 /* port-G for CLFE (rear panel) */
15676 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15677 /* port-H for side (rear panel) */
15678 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15679 /* CD-in */
15680 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15681 /* route front mic to ADC1*/
15682 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15683 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15684 /* Unmute DAC0~3 & spdif out*/
15685 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15686 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15687 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15688 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15689 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15690
22309c3e
TI
15691 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15692 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15693 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15694 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15695 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15696
22309c3e
TI
15697 /* Unmute Stereo Mixer 15 */
15698 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15699 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15700 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15701 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15702
15703 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15704 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15705 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15706 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15707 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15708 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15709 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15710 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15711 /* hp used DAC 3 (Front) */
15712 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15713 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15714 { }
15715};
15716
7cdbff94
MD
15717static struct hda_verb alc861_asus_init_verbs[] = {
15718 /*
15719 * Unmute ADC0 and set the default input to mic-in
15720 */
f12ab1e0
TI
15721 /* port-A for surround (rear panel)
15722 * according to codec#0 this is the HP jack
15723 */
7cdbff94
MD
15724 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15725 /* route front PCM to HP */
15726 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15727 /* port-B for mic-in (rear panel) with vref */
15728 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15729 /* port-C for line-in (rear panel) */
15730 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15731 /* port-D for Front */
15732 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15733 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15734 /* port-E for HP out (front panel) */
f12ab1e0
TI
15735 /* this has to be set to VREF80 */
15736 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15737 /* route front PCM to HP */
9dece1d7 15738 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15739 /* port-F for mic-in (front panel) with vref */
15740 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15741 /* port-G for CLFE (rear panel) */
15742 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15743 /* port-H for side (rear panel) */
15744 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15745 /* CD-in */
15746 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15747 /* route front mic to ADC1*/
15748 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15749 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15750 /* Unmute DAC0~3 & spdif out*/
15751 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15752 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15753 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15754 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15755 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15756 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15757 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15758 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15759 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15760 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15761
7cdbff94
MD
15762 /* Unmute Stereo Mixer 15 */
15763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15764 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15765 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15766 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15767
15768 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15769 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15770 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15771 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15772 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15773 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15774 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15775 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15776 /* hp used DAC 3 (Front) */
15777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15778 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15779 { }
15780};
15781
56bb0cab
TI
15782/* additional init verbs for ASUS laptops */
15783static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15784 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15785 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15786 { }
15787};
7cdbff94 15788
df694daa
KY
15789/*
15790 * generic initialization of ADC, input mixers and output mixers
15791 */
15792static struct hda_verb alc861_auto_init_verbs[] = {
15793 /*
15794 * Unmute ADC0 and set the default input to mic-in
15795 */
f12ab1e0 15796 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15797 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15798
df694daa
KY
15799 /* Unmute DAC0~3 & spdif out*/
15800 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15801 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15802 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15803 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15804 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15805
df694daa
KY
15806 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15807 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15808 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15809 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15810 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15811
df694daa
KY
15812 /* Unmute Stereo Mixer 15 */
15813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15814 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15815 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15817
1c20930a
TI
15818 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15819 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15820 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15821 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15822 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15823 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15824 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15825 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15826
15827 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15828 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15829 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15830 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15831 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15832 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15833 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15834 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15835
f12ab1e0 15836 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15837
15838 { }
15839};
15840
a53d1aec
TD
15841static struct hda_verb alc861_toshiba_init_verbs[] = {
15842 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15843
a53d1aec
TD
15844 { }
15845};
15846
15847/* toggle speaker-output according to the hp-jack state */
15848static void alc861_toshiba_automute(struct hda_codec *codec)
15849{
864f92be 15850 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15851
47fd830a
TI
15852 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15853 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15854 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15855 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15856}
15857
15858static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15859 unsigned int res)
15860{
a53d1aec
TD
15861 if ((res >> 26) == ALC880_HP_EVENT)
15862 alc861_toshiba_automute(codec);
15863}
15864
def319f9 15865/* pcm configuration: identical with ALC880 */
df694daa
KY
15866#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15867#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15868#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15869#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15870
15871
15872#define ALC861_DIGOUT_NID 0x07
15873
15874static struct hda_channel_mode alc861_8ch_modes[1] = {
15875 { 8, NULL }
15876};
15877
15878static hda_nid_t alc861_dac_nids[4] = {
15879 /* front, surround, clfe, side */
15880 0x03, 0x06, 0x05, 0x04
15881};
15882
9c7f852e
TI
15883static hda_nid_t alc660_dac_nids[3] = {
15884 /* front, clfe, surround */
15885 0x03, 0x05, 0x06
15886};
15887
df694daa
KY
15888static hda_nid_t alc861_adc_nids[1] = {
15889 /* ADC0-2 */
15890 0x08,
15891};
15892
15893static struct hda_input_mux alc861_capture_source = {
15894 .num_items = 5,
15895 .items = {
15896 { "Mic", 0x0 },
15897 { "Front Mic", 0x3 },
15898 { "Line", 0x1 },
15899 { "CD", 0x4 },
15900 { "Mixer", 0x5 },
15901 },
15902};
15903
1c20930a
TI
15904static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15905{
15906 struct alc_spec *spec = codec->spec;
15907 hda_nid_t mix, srcs[5];
15908 int i, j, num;
15909
15910 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15911 return 0;
15912 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15913 if (num < 0)
15914 return 0;
15915 for (i = 0; i < num; i++) {
15916 unsigned int type;
a22d543a 15917 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15918 if (type != AC_WID_AUD_OUT)
15919 continue;
15920 for (j = 0; j < spec->multiout.num_dacs; j++)
15921 if (spec->multiout.dac_nids[j] == srcs[i])
15922 break;
15923 if (j >= spec->multiout.num_dacs)
15924 return srcs[i];
15925 }
15926 return 0;
15927}
15928
df694daa 15929/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15930static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15931 const struct auto_pin_cfg *cfg)
df694daa 15932{
1c20930a 15933 struct alc_spec *spec = codec->spec;
df694daa 15934 int i;
1c20930a 15935 hda_nid_t nid, dac;
df694daa
KY
15936
15937 spec->multiout.dac_nids = spec->private_dac_nids;
15938 for (i = 0; i < cfg->line_outs; i++) {
15939 nid = cfg->line_out_pins[i];
1c20930a
TI
15940 dac = alc861_look_for_dac(codec, nid);
15941 if (!dac)
15942 continue;
15943 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15944 }
df694daa
KY
15945 return 0;
15946}
15947
bcb2f0f5
TI
15948static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15949 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15950{
bcb2f0f5 15951 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15952 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15953}
15954
bcb2f0f5
TI
15955#define alc861_create_out_sw(codec, pfx, nid, chs) \
15956 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15957
df694daa 15958/* add playback controls from the parsed DAC table */
1c20930a 15959static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15960 const struct auto_pin_cfg *cfg)
15961{
1c20930a 15962 struct alc_spec *spec = codec->spec;
ea734963 15963 static const char * const chname[4] = {
f12ab1e0
TI
15964 "Front", "Surround", NULL /*CLFE*/, "Side"
15965 };
bcb2f0f5 15966 const char *pfx = alc_get_line_out_pfx(cfg, true);
df694daa 15967 hda_nid_t nid;
1c20930a
TI
15968 int i, err;
15969
df694daa
KY
15970 for (i = 0; i < cfg->line_outs; i++) {
15971 nid = spec->multiout.dac_nids[i];
f12ab1e0 15972 if (!nid)
df694daa 15973 continue;
bcb2f0f5 15974 if (!pfx && i == 2) {
df694daa 15975 /* Center/LFE */
1c20930a 15976 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15977 if (err < 0)
df694daa 15978 return err;
1c20930a 15979 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15980 if (err < 0)
df694daa
KY
15981 return err;
15982 } else {
bcb2f0f5
TI
15983 const char *name = pfx;
15984 if (!name)
15985 name = chname[i];
15986 err = __alc861_create_out_sw(codec, name, nid, i, 3);
f12ab1e0 15987 if (err < 0)
df694daa
KY
15988 return err;
15989 }
15990 }
15991 return 0;
15992}
15993
1c20930a 15994static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15995{
1c20930a 15996 struct alc_spec *spec = codec->spec;
df694daa
KY
15997 int err;
15998 hda_nid_t nid;
15999
f12ab1e0 16000 if (!pin)
df694daa
KY
16001 return 0;
16002
16003 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16004 nid = alc861_look_for_dac(codec, pin);
16005 if (nid) {
16006 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16007 if (err < 0)
16008 return err;
16009 spec->multiout.hp_nid = nid;
16010 }
df694daa
KY
16011 }
16012 return 0;
16013}
16014
16015/* create playback/capture controls for input pins */
05f5f477 16016static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16017 const struct auto_pin_cfg *cfg)
df694daa 16018{
05f5f477 16019 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16020}
16021
f12ab1e0
TI
16022static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16023 hda_nid_t nid,
1c20930a 16024 int pin_type, hda_nid_t dac)
df694daa 16025{
1c20930a
TI
16026 hda_nid_t mix, srcs[5];
16027 int i, num;
16028
564c5bea
JL
16029 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16030 pin_type);
1c20930a 16031 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16032 AMP_OUT_UNMUTE);
1c20930a
TI
16033 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16034 return;
16035 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16036 if (num < 0)
16037 return;
16038 for (i = 0; i < num; i++) {
16039 unsigned int mute;
16040 if (srcs[i] == dac || srcs[i] == 0x15)
16041 mute = AMP_IN_UNMUTE(i);
16042 else
16043 mute = AMP_IN_MUTE(i);
16044 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16045 mute);
16046 }
df694daa
KY
16047}
16048
16049static void alc861_auto_init_multi_out(struct hda_codec *codec)
16050{
16051 struct alc_spec *spec = codec->spec;
16052 int i;
16053
16054 for (i = 0; i < spec->autocfg.line_outs; i++) {
16055 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16056 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16057 if (nid)
baba8ee9 16058 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16059 spec->multiout.dac_nids[i]);
df694daa
KY
16060 }
16061}
16062
16063static void alc861_auto_init_hp_out(struct hda_codec *codec)
16064{
16065 struct alc_spec *spec = codec->spec;
df694daa 16066
15870f05
TI
16067 if (spec->autocfg.hp_outs)
16068 alc861_auto_set_output_and_unmute(codec,
16069 spec->autocfg.hp_pins[0],
16070 PIN_HP,
1c20930a 16071 spec->multiout.hp_nid);
15870f05
TI
16072 if (spec->autocfg.speaker_outs)
16073 alc861_auto_set_output_and_unmute(codec,
16074 spec->autocfg.speaker_pins[0],
16075 PIN_OUT,
1c20930a 16076 spec->multiout.dac_nids[0]);
df694daa
KY
16077}
16078
16079static void alc861_auto_init_analog_input(struct hda_codec *codec)
16080{
16081 struct alc_spec *spec = codec->spec;
66ceeb6b 16082 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16083 int i;
16084
66ceeb6b
TI
16085 for (i = 0; i < cfg->num_inputs; i++) {
16086 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16087 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16088 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16089 }
16090}
16091
16092/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16093/* return 1 if successful, 0 if the proper config is not found,
16094 * or a negative error code
16095 */
df694daa
KY
16096static int alc861_parse_auto_config(struct hda_codec *codec)
16097{
16098 struct alc_spec *spec = codec->spec;
16099 int err;
16100 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16101
f12ab1e0
TI
16102 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16103 alc861_ignore);
16104 if (err < 0)
df694daa 16105 return err;
f12ab1e0 16106 if (!spec->autocfg.line_outs)
df694daa
KY
16107 return 0; /* can't find valid BIOS pin config */
16108
1c20930a 16109 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
16110 if (err < 0)
16111 return err;
1c20930a 16112 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16113 if (err < 0)
16114 return err;
1c20930a 16115 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16116 if (err < 0)
16117 return err;
05f5f477 16118 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16119 if (err < 0)
df694daa
KY
16120 return err;
16121
16122 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16123
757899ac 16124 alc_auto_parse_digital(codec);
df694daa 16125
603c4019 16126 if (spec->kctls.list)
d88897ea 16127 add_mixer(spec, spec->kctls.list);
df694daa 16128
d88897ea 16129 add_verb(spec, alc861_auto_init_verbs);
df694daa 16130
a1e8d2da 16131 spec->num_mux_defs = 1;
61b9b9b1 16132 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16133
16134 spec->adc_nids = alc861_adc_nids;
16135 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16136 set_capture_mixer(codec);
df694daa 16137
6227cdce 16138 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16139
df694daa
KY
16140 return 1;
16141}
16142
ae6b813a
TI
16143/* additional initialization for auto-configuration model */
16144static void alc861_auto_init(struct hda_codec *codec)
df694daa 16145{
f6c7e546 16146 struct alc_spec *spec = codec->spec;
df694daa
KY
16147 alc861_auto_init_multi_out(codec);
16148 alc861_auto_init_hp_out(codec);
16149 alc861_auto_init_analog_input(codec);
757899ac 16150 alc_auto_init_digital(codec);
f6c7e546 16151 if (spec->unsol_event)
7fb0d78f 16152 alc_inithook(codec);
df694daa
KY
16153}
16154
cb53c626
TI
16155#ifdef CONFIG_SND_HDA_POWER_SAVE
16156static struct hda_amp_list alc861_loopbacks[] = {
16157 { 0x15, HDA_INPUT, 0 },
16158 { 0x15, HDA_INPUT, 1 },
16159 { 0x15, HDA_INPUT, 2 },
16160 { 0x15, HDA_INPUT, 3 },
16161 { } /* end */
16162};
16163#endif
16164
df694daa
KY
16165
16166/*
16167 * configuration and preset
16168 */
ea734963 16169static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16170 [ALC861_3ST] = "3stack",
16171 [ALC660_3ST] = "3stack-660",
16172 [ALC861_3ST_DIG] = "3stack-dig",
16173 [ALC861_6ST_DIG] = "6stack-dig",
16174 [ALC861_UNIWILL_M31] = "uniwill-m31",
16175 [ALC861_TOSHIBA] = "toshiba",
16176 [ALC861_ASUS] = "asus",
16177 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16178 [ALC861_AUTO] = "auto",
16179};
16180
16181static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16182 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16183 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16184 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16185 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16186 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16187 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16188 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16189 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16190 * Any other models that need this preset?
16191 */
16192 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16193 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16194 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16195 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16196 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16197 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16198 /* FIXME: the below seems conflict */
16199 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16200 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16201 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16202 {}
16203};
16204
16205static struct alc_config_preset alc861_presets[] = {
16206 [ALC861_3ST] = {
16207 .mixers = { alc861_3ST_mixer },
16208 .init_verbs = { alc861_threestack_init_verbs },
16209 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16210 .dac_nids = alc861_dac_nids,
16211 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16212 .channel_mode = alc861_threestack_modes,
4e195a7b 16213 .need_dac_fix = 1,
df694daa
KY
16214 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16215 .adc_nids = alc861_adc_nids,
16216 .input_mux = &alc861_capture_source,
16217 },
16218 [ALC861_3ST_DIG] = {
16219 .mixers = { alc861_base_mixer },
16220 .init_verbs = { alc861_threestack_init_verbs },
16221 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16222 .dac_nids = alc861_dac_nids,
16223 .dig_out_nid = ALC861_DIGOUT_NID,
16224 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16225 .channel_mode = alc861_threestack_modes,
4e195a7b 16226 .need_dac_fix = 1,
df694daa
KY
16227 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16228 .adc_nids = alc861_adc_nids,
16229 .input_mux = &alc861_capture_source,
16230 },
16231 [ALC861_6ST_DIG] = {
16232 .mixers = { alc861_base_mixer },
16233 .init_verbs = { alc861_base_init_verbs },
16234 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16235 .dac_nids = alc861_dac_nids,
16236 .dig_out_nid = ALC861_DIGOUT_NID,
16237 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16238 .channel_mode = alc861_8ch_modes,
16239 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16240 .adc_nids = alc861_adc_nids,
16241 .input_mux = &alc861_capture_source,
16242 },
9c7f852e
TI
16243 [ALC660_3ST] = {
16244 .mixers = { alc861_3ST_mixer },
16245 .init_verbs = { alc861_threestack_init_verbs },
16246 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16247 .dac_nids = alc660_dac_nids,
16248 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16249 .channel_mode = alc861_threestack_modes,
4e195a7b 16250 .need_dac_fix = 1,
9c7f852e
TI
16251 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16252 .adc_nids = alc861_adc_nids,
16253 .input_mux = &alc861_capture_source,
16254 },
22309c3e
TI
16255 [ALC861_UNIWILL_M31] = {
16256 .mixers = { alc861_uniwill_m31_mixer },
16257 .init_verbs = { alc861_uniwill_m31_init_verbs },
16258 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16259 .dac_nids = alc861_dac_nids,
16260 .dig_out_nid = ALC861_DIGOUT_NID,
16261 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16262 .channel_mode = alc861_uniwill_m31_modes,
16263 .need_dac_fix = 1,
16264 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16265 .adc_nids = alc861_adc_nids,
16266 .input_mux = &alc861_capture_source,
16267 },
a53d1aec
TD
16268 [ALC861_TOSHIBA] = {
16269 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16270 .init_verbs = { alc861_base_init_verbs,
16271 alc861_toshiba_init_verbs },
a53d1aec
TD
16272 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16273 .dac_nids = alc861_dac_nids,
16274 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16275 .channel_mode = alc883_3ST_2ch_modes,
16276 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16277 .adc_nids = alc861_adc_nids,
16278 .input_mux = &alc861_capture_source,
16279 .unsol_event = alc861_toshiba_unsol_event,
16280 .init_hook = alc861_toshiba_automute,
16281 },
7cdbff94
MD
16282 [ALC861_ASUS] = {
16283 .mixers = { alc861_asus_mixer },
16284 .init_verbs = { alc861_asus_init_verbs },
16285 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16286 .dac_nids = alc861_dac_nids,
16287 .dig_out_nid = ALC861_DIGOUT_NID,
16288 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16289 .channel_mode = alc861_asus_modes,
16290 .need_dac_fix = 1,
16291 .hp_nid = 0x06,
16292 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16293 .adc_nids = alc861_adc_nids,
16294 .input_mux = &alc861_capture_source,
16295 },
56bb0cab
TI
16296 [ALC861_ASUS_LAPTOP] = {
16297 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16298 .init_verbs = { alc861_asus_init_verbs,
16299 alc861_asus_laptop_init_verbs },
16300 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16301 .dac_nids = alc861_dac_nids,
16302 .dig_out_nid = ALC861_DIGOUT_NID,
16303 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16304 .channel_mode = alc883_3ST_2ch_modes,
16305 .need_dac_fix = 1,
16306 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16307 .adc_nids = alc861_adc_nids,
16308 .input_mux = &alc861_capture_source,
16309 },
16310};
df694daa 16311
cfc9b06f
TI
16312/* Pin config fixes */
16313enum {
16314 PINFIX_FSC_AMILO_PI1505,
16315};
16316
cfc9b06f
TI
16317static const struct alc_fixup alc861_fixups[] = {
16318 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16319 .type = ALC_FIXUP_PINS,
16320 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16321 { 0x0b, 0x0221101f }, /* HP */
16322 { 0x0f, 0x90170310 }, /* speaker */
16323 { }
16324 }
cfc9b06f
TI
16325 },
16326};
16327
16328static struct snd_pci_quirk alc861_fixup_tbl[] = {
16329 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16330 {}
16331};
df694daa
KY
16332
16333static int patch_alc861(struct hda_codec *codec)
16334{
16335 struct alc_spec *spec;
16336 int board_config;
16337 int err;
16338
dc041e0b 16339 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16340 if (spec == NULL)
16341 return -ENOMEM;
16342
f12ab1e0 16343 codec->spec = spec;
df694daa 16344
f5fcc13c
TI
16345 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16346 alc861_models,
16347 alc861_cfg_tbl);
9c7f852e 16348
f5fcc13c 16349 if (board_config < 0) {
9a11f1aa
TI
16350 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16351 codec->chip_name);
df694daa
KY
16352 board_config = ALC861_AUTO;
16353 }
16354
b5bfbc67
TI
16355 if (board_config == ALC861_AUTO) {
16356 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16357 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16358 }
cfc9b06f 16359
df694daa
KY
16360 if (board_config == ALC861_AUTO) {
16361 /* automatic parse from the BIOS config */
16362 err = alc861_parse_auto_config(codec);
16363 if (err < 0) {
16364 alc_free(codec);
16365 return err;
f12ab1e0 16366 } else if (!err) {
9c7f852e
TI
16367 printk(KERN_INFO
16368 "hda_codec: Cannot set up configuration "
16369 "from BIOS. Using base mode...\n");
df694daa
KY
16370 board_config = ALC861_3ST_DIG;
16371 }
16372 }
16373
680cd536
KK
16374 err = snd_hda_attach_beep_device(codec, 0x23);
16375 if (err < 0) {
16376 alc_free(codec);
16377 return err;
16378 }
16379
df694daa 16380 if (board_config != ALC861_AUTO)
e9c364c0 16381 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16382
df694daa
KY
16383 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16384 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16385
df694daa
KY
16386 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16387 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16388
c7a8eb10
TI
16389 if (!spec->cap_mixer)
16390 set_capture_mixer(codec);
45bdd1c1
TI
16391 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16392
2134ea4f
TI
16393 spec->vmaster_nid = 0x03;
16394
b5bfbc67 16395 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16396
df694daa 16397 codec->patch_ops = alc_patch_ops;
c97259df 16398 if (board_config == ALC861_AUTO) {
ae6b813a 16399 spec->init_hook = alc861_auto_init;
c97259df
DC
16400#ifdef CONFIG_SND_HDA_POWER_SAVE
16401 spec->power_hook = alc_power_eapd;
16402#endif
16403 }
cb53c626
TI
16404#ifdef CONFIG_SND_HDA_POWER_SAVE
16405 if (!spec->loopback.amplist)
16406 spec->loopback.amplist = alc861_loopbacks;
16407#endif
ea1fb29a 16408
1da177e4
LT
16409 return 0;
16410}
16411
f32610ed
JS
16412/*
16413 * ALC861-VD support
16414 *
16415 * Based on ALC882
16416 *
16417 * In addition, an independent DAC
16418 */
16419#define ALC861VD_DIGOUT_NID 0x06
16420
16421static hda_nid_t alc861vd_dac_nids[4] = {
16422 /* front, surr, clfe, side surr */
16423 0x02, 0x03, 0x04, 0x05
16424};
16425
16426/* dac_nids for ALC660vd are in a different order - according to
16427 * Realtek's driver.
def319f9 16428 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16429 * of ALC660vd codecs, but for now there is only 3stack mixer
16430 * - and it is the same as in 861vd.
16431 * adc_nids in ALC660vd are (is) the same as in 861vd
16432 */
16433static hda_nid_t alc660vd_dac_nids[3] = {
16434 /* front, rear, clfe, rear_surr */
16435 0x02, 0x04, 0x03
16436};
16437
16438static hda_nid_t alc861vd_adc_nids[1] = {
16439 /* ADC0 */
16440 0x09,
16441};
16442
e1406348
TI
16443static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16444
f32610ed
JS
16445/* input MUX */
16446/* FIXME: should be a matrix-type input source selection */
16447static struct hda_input_mux alc861vd_capture_source = {
16448 .num_items = 4,
16449 .items = {
16450 { "Mic", 0x0 },
16451 { "Front Mic", 0x1 },
16452 { "Line", 0x2 },
16453 { "CD", 0x4 },
16454 },
16455};
16456
272a527c 16457static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16458 .num_items = 2,
272a527c 16459 .items = {
8607f7c4 16460 { "Mic", 0x0 },
28c4edb7 16461 { "Internal Mic", 0x1 },
272a527c
KY
16462 },
16463};
16464
d1a991a6
KY
16465static struct hda_input_mux alc861vd_hp_capture_source = {
16466 .num_items = 2,
16467 .items = {
16468 { "Front Mic", 0x0 },
16469 { "ATAPI Mic", 0x1 },
16470 },
16471};
16472
f32610ed
JS
16473/*
16474 * 2ch mode
16475 */
16476static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16477 { 2, NULL }
16478};
16479
16480/*
16481 * 6ch mode
16482 */
16483static struct hda_verb alc861vd_6stack_ch6_init[] = {
16484 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16485 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16486 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16487 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16488 { } /* end */
16489};
16490
16491/*
16492 * 8ch mode
16493 */
16494static struct hda_verb alc861vd_6stack_ch8_init[] = {
16495 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16496 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16497 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16498 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16499 { } /* end */
16500};
16501
16502static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16503 { 6, alc861vd_6stack_ch6_init },
16504 { 8, alc861vd_6stack_ch8_init },
16505};
16506
16507static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16508 {
16509 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16510 .name = "Channel Mode",
16511 .info = alc_ch_mode_info,
16512 .get = alc_ch_mode_get,
16513 .put = alc_ch_mode_put,
16514 },
16515 { } /* end */
16516};
16517
f32610ed
JS
16518/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16519 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16520 */
16521static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16522 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16523 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16524
16525 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16526 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16527
16528 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16529 HDA_OUTPUT),
16530 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16531 HDA_OUTPUT),
16532 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16533 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16534
16535 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16536 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16537
16538 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16539
5f99f86a 16540 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16541 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16542 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16543
5f99f86a 16544 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16545 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16546 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16547
16548 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16549 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16550
16551 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16552 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16553
f32610ed
JS
16554 { } /* end */
16555};
16556
16557static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16558 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16559 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16560
16561 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16562
5f99f86a 16563 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16564 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16565 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16566
5f99f86a 16567 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16568 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16569 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16570
16571 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16572 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16573
16574 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16575 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16576
f32610ed
JS
16577 { } /* end */
16578};
16579
bdd148a3
KY
16580static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16581 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16582 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16583 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16584
16585 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16586
5f99f86a 16587 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16590
5f99f86a 16591 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16592 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16593 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16594
16595 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16596 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16597
16598 { } /* end */
16599};
16600
b419f346 16601/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16602 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16603 */
16604static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16605 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16606 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16607 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16608 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16609 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16610 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16611 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16612 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16613 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16614 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16615 { } /* end */
16616};
16617
d1a991a6
KY
16618/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16619 * Front Mic=0x18, ATAPI Mic = 0x19,
16620 */
16621static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16622 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16623 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16624 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16625 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16626 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16627 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16628 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16629 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16630
d1a991a6
KY
16631 { } /* end */
16632};
16633
f32610ed
JS
16634/*
16635 * generic initialization of ADC, input mixers and output mixers
16636 */
16637static struct hda_verb alc861vd_volume_init_verbs[] = {
16638 /*
16639 * Unmute ADC0 and set the default input to mic-in
16640 */
16641 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16642 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16643
16644 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16645 * the analog-loopback mixer widget
16646 */
16647 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16649 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16650 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16651 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16652 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16653
16654 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16655 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16656 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16657 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16658 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16659
16660 /*
16661 * Set up output mixers (0x02 - 0x05)
16662 */
16663 /* set vol=0 to output mixers */
16664 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16665 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16666 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16667 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16668
16669 /* set up input amps for analog loopback */
16670 /* Amp Indices: DAC = 0, mixer = 1 */
16671 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16672 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16673 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16674 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16675 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16676 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16677 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16678 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16679
16680 { }
16681};
16682
16683/*
16684 * 3-stack pin configuration:
16685 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16686 */
16687static struct hda_verb alc861vd_3stack_init_verbs[] = {
16688 /*
16689 * Set pin mode and muting
16690 */
16691 /* set front pin widgets 0x14 for output */
16692 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16693 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16694 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16695
16696 /* Mic (rear) pin: input vref at 80% */
16697 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16698 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16699 /* Front Mic pin: input vref at 80% */
16700 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16701 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16702 /* Line In pin: input */
16703 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16704 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16705 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16706 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16707 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16708 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16709 /* CD pin widget for input */
16710 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16711
16712 { }
16713};
16714
16715/*
16716 * 6-stack pin configuration:
16717 */
16718static struct hda_verb alc861vd_6stack_init_verbs[] = {
16719 /*
16720 * Set pin mode and muting
16721 */
16722 /* set front pin widgets 0x14 for output */
16723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16724 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16725 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16726
16727 /* Rear Pin: output 1 (0x0d) */
16728 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16729 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16730 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16731 /* CLFE Pin: output 2 (0x0e) */
16732 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16733 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16734 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16735 /* Side Pin: output 3 (0x0f) */
16736 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16737 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16738 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16739
16740 /* Mic (rear) pin: input vref at 80% */
16741 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16742 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16743 /* Front Mic pin: input vref at 80% */
16744 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16745 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16746 /* Line In pin: input */
16747 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16748 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16749 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16750 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16751 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16752 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16753 /* CD pin widget for input */
16754 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16755
16756 { }
16757};
16758
bdd148a3
KY
16759static struct hda_verb alc861vd_eapd_verbs[] = {
16760 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16761 { }
16762};
16763
f9423e7a
KY
16764static struct hda_verb alc660vd_eapd_verbs[] = {
16765 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16766 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16767 { }
16768};
16769
bdd148a3
KY
16770static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16771 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16772 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16773 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16774 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16775 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16776 {}
16777};
16778
4f5d1706 16779static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16780{
a9fd4f3f 16781 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16782 spec->autocfg.hp_pins[0] = 0x1b;
16783 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16784}
16785
16786static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16787{
a9fd4f3f 16788 alc_automute_amp(codec);
eeb43387 16789 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16790}
16791
16792static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16793 unsigned int res)
16794{
16795 switch (res >> 26) {
bdd148a3 16796 case ALC880_MIC_EVENT:
eeb43387 16797 alc88x_simple_mic_automute(codec);
bdd148a3 16798 break;
a9fd4f3f
TI
16799 default:
16800 alc_automute_amp_unsol_event(codec, res);
16801 break;
bdd148a3
KY
16802 }
16803}
16804
272a527c
KY
16805static struct hda_verb alc861vd_dallas_verbs[] = {
16806 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16807 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16808 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16809 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16810
16811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16813 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16814 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16815 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16816 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16817 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16818 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16819
272a527c
KY
16820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16821 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16822 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16824 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16825 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16826 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16827 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16828
16829 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16830 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16831 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16832 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16833 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16834 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16835 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16836 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16837
16838 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16839 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16840 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16842
16843 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16844 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16845 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16846
16847 { } /* end */
16848};
16849
16850/* toggle speaker-output according to the hp-jack state */
4f5d1706 16851static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16852{
a9fd4f3f 16853 struct alc_spec *spec = codec->spec;
272a527c 16854
a9fd4f3f
TI
16855 spec->autocfg.hp_pins[0] = 0x15;
16856 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16857}
16858
cb53c626
TI
16859#ifdef CONFIG_SND_HDA_POWER_SAVE
16860#define alc861vd_loopbacks alc880_loopbacks
16861#endif
16862
def319f9 16863/* pcm configuration: identical with ALC880 */
f32610ed
JS
16864#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16865#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16866#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16867#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16868
16869/*
16870 * configuration and preset
16871 */
ea734963 16872static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16873 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16874 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16875 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16876 [ALC861VD_3ST] = "3stack",
16877 [ALC861VD_3ST_DIG] = "3stack-digout",
16878 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16879 [ALC861VD_LENOVO] = "lenovo",
272a527c 16880 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16881 [ALC861VD_HP] = "hp",
f32610ed
JS
16882 [ALC861VD_AUTO] = "auto",
16883};
16884
16885static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16886 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16887 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16888 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16889 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16890 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16891 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16892 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16893 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16894 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16895 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16896 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16897 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16898 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16899 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16900 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16901 {}
16902};
16903
16904static struct alc_config_preset alc861vd_presets[] = {
16905 [ALC660VD_3ST] = {
16906 .mixers = { alc861vd_3st_mixer },
16907 .init_verbs = { alc861vd_volume_init_verbs,
16908 alc861vd_3stack_init_verbs },
16909 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16910 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16911 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16912 .channel_mode = alc861vd_3stack_2ch_modes,
16913 .input_mux = &alc861vd_capture_source,
16914 },
6963f84c
MC
16915 [ALC660VD_3ST_DIG] = {
16916 .mixers = { alc861vd_3st_mixer },
16917 .init_verbs = { alc861vd_volume_init_verbs,
16918 alc861vd_3stack_init_verbs },
16919 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16920 .dac_nids = alc660vd_dac_nids,
16921 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16922 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16923 .channel_mode = alc861vd_3stack_2ch_modes,
16924 .input_mux = &alc861vd_capture_source,
16925 },
f32610ed
JS
16926 [ALC861VD_3ST] = {
16927 .mixers = { alc861vd_3st_mixer },
16928 .init_verbs = { alc861vd_volume_init_verbs,
16929 alc861vd_3stack_init_verbs },
16930 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16931 .dac_nids = alc861vd_dac_nids,
16932 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16933 .channel_mode = alc861vd_3stack_2ch_modes,
16934 .input_mux = &alc861vd_capture_source,
16935 },
16936 [ALC861VD_3ST_DIG] = {
16937 .mixers = { alc861vd_3st_mixer },
16938 .init_verbs = { alc861vd_volume_init_verbs,
16939 alc861vd_3stack_init_verbs },
16940 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16941 .dac_nids = alc861vd_dac_nids,
16942 .dig_out_nid = ALC861VD_DIGOUT_NID,
16943 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16944 .channel_mode = alc861vd_3stack_2ch_modes,
16945 .input_mux = &alc861vd_capture_source,
16946 },
16947 [ALC861VD_6ST_DIG] = {
16948 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16949 .init_verbs = { alc861vd_volume_init_verbs,
16950 alc861vd_6stack_init_verbs },
16951 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16952 .dac_nids = alc861vd_dac_nids,
16953 .dig_out_nid = ALC861VD_DIGOUT_NID,
16954 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16955 .channel_mode = alc861vd_6stack_modes,
16956 .input_mux = &alc861vd_capture_source,
16957 },
bdd148a3
KY
16958 [ALC861VD_LENOVO] = {
16959 .mixers = { alc861vd_lenovo_mixer },
16960 .init_verbs = { alc861vd_volume_init_verbs,
16961 alc861vd_3stack_init_verbs,
16962 alc861vd_eapd_verbs,
16963 alc861vd_lenovo_unsol_verbs },
16964 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16965 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16966 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16967 .channel_mode = alc861vd_3stack_2ch_modes,
16968 .input_mux = &alc861vd_capture_source,
16969 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16970 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16971 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16972 },
272a527c
KY
16973 [ALC861VD_DALLAS] = {
16974 .mixers = { alc861vd_dallas_mixer },
16975 .init_verbs = { alc861vd_dallas_verbs },
16976 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16977 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16978 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16979 .channel_mode = alc861vd_3stack_2ch_modes,
16980 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16981 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16982 .setup = alc861vd_dallas_setup,
16983 .init_hook = alc_automute_amp,
d1a991a6
KY
16984 },
16985 [ALC861VD_HP] = {
16986 .mixers = { alc861vd_hp_mixer },
16987 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16988 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16989 .dac_nids = alc861vd_dac_nids,
d1a991a6 16990 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16991 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16992 .channel_mode = alc861vd_3stack_2ch_modes,
16993 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16994 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16995 .setup = alc861vd_dallas_setup,
16996 .init_hook = alc_automute_amp,
ea1fb29a 16997 },
13c94744
TI
16998 [ALC660VD_ASUS_V1S] = {
16999 .mixers = { alc861vd_lenovo_mixer },
17000 .init_verbs = { alc861vd_volume_init_verbs,
17001 alc861vd_3stack_init_verbs,
17002 alc861vd_eapd_verbs,
17003 alc861vd_lenovo_unsol_verbs },
17004 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17005 .dac_nids = alc660vd_dac_nids,
17006 .dig_out_nid = ALC861VD_DIGOUT_NID,
17007 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17008 .channel_mode = alc861vd_3stack_2ch_modes,
17009 .input_mux = &alc861vd_capture_source,
17010 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17011 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17012 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17013 },
f32610ed
JS
17014};
17015
17016/*
17017 * BIOS auto configuration
17018 */
05f5f477
TI
17019static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17020 const struct auto_pin_cfg *cfg)
17021{
7167594a 17022 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17023}
17024
17025
f32610ed
JS
17026static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17027 hda_nid_t nid, int pin_type, int dac_idx)
17028{
f6c7e546 17029 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17030}
17031
17032static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17033{
17034 struct alc_spec *spec = codec->spec;
17035 int i;
17036
17037 for (i = 0; i <= HDA_SIDE; i++) {
17038 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17039 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17040 if (nid)
17041 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17042 pin_type, i);
f32610ed
JS
17043 }
17044}
17045
17046
17047static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17048{
17049 struct alc_spec *spec = codec->spec;
17050 hda_nid_t pin;
17051
17052 pin = spec->autocfg.hp_pins[0];
def319f9 17053 if (pin) /* connect to front and use dac 0 */
f32610ed 17054 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17055 pin = spec->autocfg.speaker_pins[0];
17056 if (pin)
17057 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17058}
17059
f32610ed
JS
17060#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17061
17062static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17063{
17064 struct alc_spec *spec = codec->spec;
66ceeb6b 17065 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17066 int i;
17067
66ceeb6b
TI
17068 for (i = 0; i < cfg->num_inputs; i++) {
17069 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17070 if (alc_is_input_pin(codec, nid)) {
30ea098f 17071 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17072 if (nid != ALC861VD_PIN_CD_NID &&
17073 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17074 snd_hda_codec_write(codec, nid, 0,
17075 AC_VERB_SET_AMP_GAIN_MUTE,
17076 AMP_OUT_MUTE);
17077 }
17078 }
17079}
17080
f511b01c
TI
17081#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17082
f32610ed
JS
17083#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17084#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17085
17086/* add playback controls from the parsed DAC table */
569ed348 17087/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17088 * different NIDs for mute/unmute switch and volume control */
17089static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17090 const struct auto_pin_cfg *cfg)
17091{
ea734963
TI
17092 static const char * const chname[4] = {
17093 "Front", "Surround", "CLFE", "Side"
17094 };
bcb2f0f5 17095 const char *pfx = alc_get_line_out_pfx(cfg, true);
f32610ed
JS
17096 hda_nid_t nid_v, nid_s;
17097 int i, err;
17098
17099 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 17100 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17101 continue;
17102 nid_v = alc861vd_idx_to_mixer_vol(
17103 alc880_dac_to_idx(
17104 spec->multiout.dac_nids[i]));
17105 nid_s = alc861vd_idx_to_mixer_switch(
17106 alc880_dac_to_idx(
17107 spec->multiout.dac_nids[i]));
17108
bcb2f0f5 17109 if (!pfx && i == 2) {
f32610ed 17110 /* Center/LFE */
0afe5f89
TI
17111 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17112 "Center",
f12ab1e0
TI
17113 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17114 HDA_OUTPUT));
17115 if (err < 0)
f32610ed 17116 return err;
0afe5f89
TI
17117 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17118 "LFE",
f12ab1e0
TI
17119 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17120 HDA_OUTPUT));
17121 if (err < 0)
f32610ed 17122 return err;
0afe5f89
TI
17123 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17124 "Center",
f12ab1e0
TI
17125 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17126 HDA_INPUT));
17127 if (err < 0)
f32610ed 17128 return err;
0afe5f89
TI
17129 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17130 "LFE",
f12ab1e0
TI
17131 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17132 HDA_INPUT));
17133 if (err < 0)
f32610ed
JS
17134 return err;
17135 } else {
bcb2f0f5
TI
17136 const char *name = pfx;
17137 if (!name)
17138 name = chname[i];
17139 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17140 name, i,
f12ab1e0
TI
17141 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17142 HDA_OUTPUT));
17143 if (err < 0)
f32610ed 17144 return err;
bcb2f0f5
TI
17145 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17146 name, i,
bdd148a3 17147 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17148 HDA_INPUT));
17149 if (err < 0)
f32610ed
JS
17150 return err;
17151 }
17152 }
17153 return 0;
17154}
17155
17156/* add playback controls for speaker and HP outputs */
17157/* Based on ALC880 version. But ALC861VD has separate,
17158 * different NIDs for mute/unmute switch and volume control */
17159static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17160 hda_nid_t pin, const char *pfx)
17161{
17162 hda_nid_t nid_v, nid_s;
17163 int err;
f32610ed 17164
f12ab1e0 17165 if (!pin)
f32610ed
JS
17166 return 0;
17167
17168 if (alc880_is_fixed_pin(pin)) {
17169 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17170 /* specify the DAC as the extra output */
f12ab1e0 17171 if (!spec->multiout.hp_nid)
f32610ed
JS
17172 spec->multiout.hp_nid = nid_v;
17173 else
17174 spec->multiout.extra_out_nid[0] = nid_v;
17175 /* control HP volume/switch on the output mixer amp */
17176 nid_v = alc861vd_idx_to_mixer_vol(
17177 alc880_fixed_pin_idx(pin));
17178 nid_s = alc861vd_idx_to_mixer_switch(
17179 alc880_fixed_pin_idx(pin));
17180
0afe5f89 17181 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17182 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17183 if (err < 0)
f32610ed 17184 return err;
0afe5f89 17185 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17186 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17187 if (err < 0)
f32610ed
JS
17188 return err;
17189 } else if (alc880_is_multi_pin(pin)) {
17190 /* set manual connection */
17191 /* we have only a switch on HP-out PIN */
0afe5f89 17192 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17193 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17194 if (err < 0)
f32610ed
JS
17195 return err;
17196 }
17197 return 0;
17198}
17199
17200/* parse the BIOS configuration and set up the alc_spec
17201 * return 1 if successful, 0 if the proper config is not found,
17202 * or a negative error code
17203 * Based on ALC880 version - had to change it to override
17204 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17205static int alc861vd_parse_auto_config(struct hda_codec *codec)
17206{
17207 struct alc_spec *spec = codec->spec;
17208 int err;
17209 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17210
f12ab1e0
TI
17211 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17212 alc861vd_ignore);
17213 if (err < 0)
f32610ed 17214 return err;
f12ab1e0 17215 if (!spec->autocfg.line_outs)
f32610ed
JS
17216 return 0; /* can't find valid BIOS pin config */
17217
f12ab1e0
TI
17218 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17219 if (err < 0)
17220 return err;
17221 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17222 if (err < 0)
17223 return err;
17224 err = alc861vd_auto_create_extra_out(spec,
17225 spec->autocfg.speaker_pins[0],
17226 "Speaker");
17227 if (err < 0)
17228 return err;
17229 err = alc861vd_auto_create_extra_out(spec,
17230 spec->autocfg.hp_pins[0],
17231 "Headphone");
17232 if (err < 0)
17233 return err;
05f5f477 17234 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17235 if (err < 0)
f32610ed
JS
17236 return err;
17237
17238 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17239
757899ac 17240 alc_auto_parse_digital(codec);
f32610ed 17241
603c4019 17242 if (spec->kctls.list)
d88897ea 17243 add_mixer(spec, spec->kctls.list);
f32610ed 17244
d88897ea 17245 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17246
17247 spec->num_mux_defs = 1;
61b9b9b1 17248 spec->input_mux = &spec->private_imux[0];
f32610ed 17249
776e184e
TI
17250 err = alc_auto_add_mic_boost(codec);
17251 if (err < 0)
17252 return err;
17253
6227cdce 17254 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17255
f32610ed
JS
17256 return 1;
17257}
17258
17259/* additional initialization for auto-configuration model */
17260static void alc861vd_auto_init(struct hda_codec *codec)
17261{
f6c7e546 17262 struct alc_spec *spec = codec->spec;
f32610ed
JS
17263 alc861vd_auto_init_multi_out(codec);
17264 alc861vd_auto_init_hp_out(codec);
17265 alc861vd_auto_init_analog_input(codec);
f511b01c 17266 alc861vd_auto_init_input_src(codec);
757899ac 17267 alc_auto_init_digital(codec);
f6c7e546 17268 if (spec->unsol_event)
7fb0d78f 17269 alc_inithook(codec);
f32610ed
JS
17270}
17271
f8f25ba3
TI
17272enum {
17273 ALC660VD_FIX_ASUS_GPIO1
17274};
17275
17276/* reset GPIO1 */
f8f25ba3
TI
17277static const struct alc_fixup alc861vd_fixups[] = {
17278 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17279 .type = ALC_FIXUP_VERBS,
17280 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17281 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17282 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17283 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17284 { }
17285 }
f8f25ba3
TI
17286 },
17287};
17288
17289static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17290 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17291 {}
17292};
17293
f32610ed
JS
17294static int patch_alc861vd(struct hda_codec *codec)
17295{
17296 struct alc_spec *spec;
17297 int err, board_config;
17298
17299 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17300 if (spec == NULL)
17301 return -ENOMEM;
17302
17303 codec->spec = spec;
17304
17305 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17306 alc861vd_models,
17307 alc861vd_cfg_tbl);
17308
17309 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17310 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17311 codec->chip_name);
f32610ed
JS
17312 board_config = ALC861VD_AUTO;
17313 }
17314
b5bfbc67
TI
17315 if (board_config == ALC861VD_AUTO) {
17316 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17317 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17318 }
f8f25ba3 17319
f32610ed
JS
17320 if (board_config == ALC861VD_AUTO) {
17321 /* automatic parse from the BIOS config */
17322 err = alc861vd_parse_auto_config(codec);
17323 if (err < 0) {
17324 alc_free(codec);
17325 return err;
f12ab1e0 17326 } else if (!err) {
f32610ed
JS
17327 printk(KERN_INFO
17328 "hda_codec: Cannot set up configuration "
17329 "from BIOS. Using base mode...\n");
17330 board_config = ALC861VD_3ST;
17331 }
17332 }
17333
680cd536
KK
17334 err = snd_hda_attach_beep_device(codec, 0x23);
17335 if (err < 0) {
17336 alc_free(codec);
17337 return err;
17338 }
17339
f32610ed 17340 if (board_config != ALC861VD_AUTO)
e9c364c0 17341 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17342
2f893286 17343 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17344 /* always turn on EAPD */
d88897ea 17345 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17346 }
17347
f32610ed
JS
17348 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17349 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17350
f32610ed
JS
17351 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17352 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17353
dd704698
TI
17354 if (!spec->adc_nids) {
17355 spec->adc_nids = alc861vd_adc_nids;
17356 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17357 }
17358 if (!spec->capsrc_nids)
17359 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17360
b59bdf3b 17361 set_capture_mixer(codec);
45bdd1c1 17362 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17363
2134ea4f
TI
17364 spec->vmaster_nid = 0x02;
17365
b5bfbc67 17366 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17367
f32610ed
JS
17368 codec->patch_ops = alc_patch_ops;
17369
17370 if (board_config == ALC861VD_AUTO)
17371 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17372#ifdef CONFIG_SND_HDA_POWER_SAVE
17373 if (!spec->loopback.amplist)
17374 spec->loopback.amplist = alc861vd_loopbacks;
17375#endif
f32610ed
JS
17376
17377 return 0;
17378}
17379
bc9f98a9
KY
17380/*
17381 * ALC662 support
17382 *
17383 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17384 * configuration. Each pin widget can choose any input DACs and a mixer.
17385 * Each ADC is connected from a mixer of all inputs. This makes possible
17386 * 6-channel independent captures.
17387 *
17388 * In addition, an independent DAC for the multi-playback (not used in this
17389 * driver yet).
17390 */
17391#define ALC662_DIGOUT_NID 0x06
17392#define ALC662_DIGIN_NID 0x0a
17393
17394static hda_nid_t alc662_dac_nids[4] = {
17395 /* front, rear, clfe, rear_surr */
17396 0x02, 0x03, 0x04
17397};
17398
622e84cd
KY
17399static hda_nid_t alc272_dac_nids[2] = {
17400 0x02, 0x03
17401};
17402
b59bdf3b 17403static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17404 /* ADC1-2 */
b59bdf3b 17405 0x09, 0x08
bc9f98a9 17406};
e1406348 17407
622e84cd
KY
17408static hda_nid_t alc272_adc_nids[1] = {
17409 /* ADC1-2 */
17410 0x08,
17411};
17412
b59bdf3b 17413static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17414static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17415
e1406348 17416
bc9f98a9
KY
17417/* input MUX */
17418/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17419static struct hda_input_mux alc662_capture_source = {
17420 .num_items = 4,
17421 .items = {
17422 { "Mic", 0x0 },
17423 { "Front Mic", 0x1 },
17424 { "Line", 0x2 },
17425 { "CD", 0x4 },
17426 },
17427};
17428
17429static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17430 .num_items = 2,
17431 .items = {
17432 { "Mic", 0x1 },
17433 { "Line", 0x2 },
17434 },
17435};
291702f0 17436
6dda9f4a
KY
17437static struct hda_input_mux alc663_capture_source = {
17438 .num_items = 3,
17439 .items = {
17440 { "Mic", 0x0 },
17441 { "Front Mic", 0x1 },
17442 { "Line", 0x2 },
17443 },
17444};
17445
4f5d1706 17446#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17447static struct hda_input_mux alc272_nc10_capture_source = {
17448 .num_items = 16,
17449 .items = {
17450 { "Autoselect Mic", 0x0 },
17451 { "Internal Mic", 0x1 },
17452 { "In-0x02", 0x2 },
17453 { "In-0x03", 0x3 },
17454 { "In-0x04", 0x4 },
17455 { "In-0x05", 0x5 },
17456 { "In-0x06", 0x6 },
17457 { "In-0x07", 0x7 },
17458 { "In-0x08", 0x8 },
17459 { "In-0x09", 0x9 },
17460 { "In-0x0a", 0x0a },
17461 { "In-0x0b", 0x0b },
17462 { "In-0x0c", 0x0c },
17463 { "In-0x0d", 0x0d },
17464 { "In-0x0e", 0x0e },
17465 { "In-0x0f", 0x0f },
17466 },
17467};
17468#endif
17469
bc9f98a9
KY
17470/*
17471 * 2ch mode
17472 */
17473static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17474 { 2, NULL }
17475};
17476
17477/*
17478 * 2ch mode
17479 */
17480static struct hda_verb alc662_3ST_ch2_init[] = {
17481 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17482 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17483 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17484 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17485 { } /* end */
17486};
17487
17488/*
17489 * 6ch mode
17490 */
17491static struct hda_verb alc662_3ST_ch6_init[] = {
17492 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17493 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17494 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17495 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17496 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17497 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17498 { } /* end */
17499};
17500
17501static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17502 { 2, alc662_3ST_ch2_init },
17503 { 6, alc662_3ST_ch6_init },
17504};
17505
17506/*
17507 * 2ch mode
17508 */
17509static struct hda_verb alc662_sixstack_ch6_init[] = {
17510 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17511 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17512 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17513 { } /* end */
17514};
17515
17516/*
17517 * 6ch mode
17518 */
17519static struct hda_verb alc662_sixstack_ch8_init[] = {
17520 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17521 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17522 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17523 { } /* end */
17524};
17525
17526static struct hda_channel_mode alc662_5stack_modes[2] = {
17527 { 2, alc662_sixstack_ch6_init },
17528 { 6, alc662_sixstack_ch8_init },
17529};
17530
17531/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17532 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17533 */
17534
17535static struct snd_kcontrol_new alc662_base_mixer[] = {
17536 /* output mixer control */
17537 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17538 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17539 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17540 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17541 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17542 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17543 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17544 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17545 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17546
17547 /*Input mixer control */
17548 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17549 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17550 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17551 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17552 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17553 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17554 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17555 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17556 { } /* end */
17557};
17558
17559static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17560 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17561 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17562 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17563 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17564 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17565 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17566 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17567 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17568 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17569 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17570 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17571 { } /* end */
17572};
17573
17574static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17575 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17576 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17577 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17578 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17579 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17580 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17581 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17582 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17583 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17584 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17585 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17590 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17591 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17592 { } /* end */
17593};
17594
17595static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17596 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17597 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17598 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17599 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17600 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17601 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17602 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17603 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17604 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17605 { } /* end */
17606};
17607
291702f0 17608static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17609 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17610 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17611
5f99f86a 17612 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17615
5f99f86a 17616 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17617 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17618 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17619 { } /* end */
17620};
17621
8c427226 17622static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17623 ALC262_HIPPO_MASTER_SWITCH,
17624 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17625 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17626 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17627 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17628 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17629 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17630 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17632 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17633 { } /* end */
17634};
17635
f1d4e28b
KY
17636static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17637 .ops = &snd_hda_bind_vol,
17638 .values = {
17639 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17640 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17641 0
17642 },
17643};
17644
17645static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17646 .ops = &snd_hda_bind_sw,
17647 .values = {
17648 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17649 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17650 0
17651 },
17652};
17653
6dda9f4a 17654static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17655 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17656 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17657 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17658 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17659 { } /* end */
17660};
17661
17662static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17663 .ops = &snd_hda_bind_sw,
17664 .values = {
17665 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17666 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17667 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17668 0
17669 },
17670};
17671
17672static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17673 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17674 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17675 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17676 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17677 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17678 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17679
17680 { } /* end */
17681};
17682
17683static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17684 .ops = &snd_hda_bind_sw,
17685 .values = {
17686 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17687 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17688 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17689 0
17690 },
17691};
17692
17693static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17694 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17695 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17696 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17697 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17698 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17699 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17700 { } /* end */
17701};
17702
17703static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17704 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17705 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17706 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17709 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17710 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17711 { } /* end */
17712};
17713
17714static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17715 .ops = &snd_hda_bind_vol,
17716 .values = {
17717 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17718 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17719 0
17720 },
17721};
17722
17723static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17724 .ops = &snd_hda_bind_sw,
17725 .values = {
17726 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17727 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17728 0
17729 },
17730};
17731
17732static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17733 HDA_BIND_VOL("Master Playback Volume",
17734 &alc663_asus_two_bind_master_vol),
17735 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17736 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17737 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17738 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17740 { } /* end */
17741};
17742
17743static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17744 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17745 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17746 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17747 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17748 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17749 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17750 { } /* end */
17751};
17752
17753static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17754 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17755 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17756 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17757 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17758 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17759
17760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17761 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17762 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17763 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17764 { } /* end */
17765};
17766
17767static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17768 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17769 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17770 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17771
17772 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17773 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17774 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17775 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17776 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17777 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17778 { } /* end */
17779};
17780
ebb83eeb
KY
17781static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17782 .ops = &snd_hda_bind_sw,
17783 .values = {
17784 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17785 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17786 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17787 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17788 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17789 0
17790 },
17791};
17792
17793static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17794 .ops = &snd_hda_bind_sw,
17795 .values = {
17796 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17797 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17798 0
17799 },
17800};
17801
17802static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17803 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17804 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17805 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17806 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17807 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17808 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17809 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17810 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17811 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17812 { } /* end */
17813};
17814
17815static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17816 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17817 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17818 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17819 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17820 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17821 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17822 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17823 { } /* end */
17824};
17825
17826
bc9f98a9
KY
17827static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17828 {
17829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17830 .name = "Channel Mode",
17831 .info = alc_ch_mode_info,
17832 .get = alc_ch_mode_get,
17833 .put = alc_ch_mode_put,
17834 },
17835 { } /* end */
17836};
17837
17838static struct hda_verb alc662_init_verbs[] = {
17839 /* ADC: mute amp left and right */
17840 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17841 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17842
b60dd394
KY
17843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17845 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17846 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17847 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17848 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17849
17850 /* Front Pin: output 0 (0x0c) */
17851 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17853
17854 /* Rear Pin: output 1 (0x0d) */
17855 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17857
17858 /* CLFE Pin: output 2 (0x0e) */
17859 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17860 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17861
17862 /* Mic (rear) pin: input vref at 80% */
17863 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17864 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17865 /* Front Mic pin: input vref at 80% */
17866 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17867 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17868 /* Line In pin: input */
17869 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17870 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17871 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17872 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17873 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17874 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17875 /* CD pin widget for input */
17876 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17877
17878 /* FIXME: use matrix-type input source selection */
17879 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17880 /* Input mixer */
17881 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17882 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17883
17884 /* always trun on EAPD */
17885 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17886 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17887
bc9f98a9
KY
17888 { }
17889};
17890
cec27c89
KY
17891static struct hda_verb alc663_init_verbs[] = {
17892 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17893 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17894 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17895 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17896 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17897 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17898 { }
17899};
17900
17901static struct hda_verb alc272_init_verbs[] = {
17902 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17903 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17904 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17905 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17906 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17907 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17908 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17909 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17910 { }
17911};
17912
bc9f98a9
KY
17913static struct hda_verb alc662_sue_init_verbs[] = {
17914 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17915 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17916 {}
17917};
17918
17919static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17920 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17921 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17922 {}
bc9f98a9
KY
17923};
17924
8c427226
KY
17925/* Set Unsolicited Event*/
17926static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17927 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17928 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17929 {}
17930};
17931
6dda9f4a 17932static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17933 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17934 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17935 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17936 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17937 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17939 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17940 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17941 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17942 {}
17943};
17944
17945static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17946 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17947 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17948 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17949 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17950 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17951 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17952 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17953 {}
17954};
17955
17956static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17957 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17958 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17959 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17960 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17963 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17964 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17965 {}
17966};
6dda9f4a 17967
f1d4e28b
KY
17968static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17969 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17970 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17971 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17972 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17973 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17974 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17975 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17976 {}
17977};
6dda9f4a 17978
f1d4e28b
KY
17979static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17980 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17981 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17982 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17983 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17984 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17985 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17986 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17989 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17990 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17991 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17992 {}
17993};
17994
17995static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17996 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17997 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17998 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17999 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18000 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18001 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18002 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18003 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18004 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18005 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18006 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18007 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18008 {}
18009};
18010
18011static struct hda_verb alc663_g71v_init_verbs[] = {
18012 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18013 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18014 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18015
18016 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18017 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18018 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18019
18020 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18021 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18022 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18023 {}
18024};
18025
18026static struct hda_verb alc663_g50v_init_verbs[] = {
18027 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18028 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18029 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18030
18031 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18032 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18033 {}
18034};
18035
f1d4e28b
KY
18036static struct hda_verb alc662_ecs_init_verbs[] = {
18037 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18038 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18039 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18040 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18041 {}
18042};
18043
622e84cd
KY
18044static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18045 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18046 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18047 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18049 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18050 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18051 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18054 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18055 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18056 {}
18057};
18058
18059static struct hda_verb alc272_dell_init_verbs[] = {
18060 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18061 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18063 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18064 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18065 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18066 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18067 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18069 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18070 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18071 {}
18072};
18073
ebb83eeb
KY
18074static struct hda_verb alc663_mode7_init_verbs[] = {
18075 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18076 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18077 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18078 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18079 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18080 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18081 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18082 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18083 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18084 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18087 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18088 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18089 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18090 {}
18091};
18092
18093static struct hda_verb alc663_mode8_init_verbs[] = {
18094 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18095 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18096 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18097 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18098 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18099 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18100 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18101 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
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 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18108 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18109 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18110 {}
18111};
18112
f1d4e28b
KY
18113static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18114 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18115 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18116 { } /* end */
18117};
18118
622e84cd
KY
18119static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18120 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18121 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18122 { } /* end */
18123};
18124
bc9f98a9
KY
18125static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18126{
18127 unsigned int present;
f12ab1e0 18128 unsigned char bits;
bc9f98a9 18129
864f92be 18130 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 18131 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18132
47fd830a
TI
18133 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18134 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18135}
18136
18137static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18138{
18139 unsigned int present;
f12ab1e0 18140 unsigned char bits;
bc9f98a9 18141
864f92be 18142 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 18143 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18144
47fd830a
TI
18145 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18146 HDA_AMP_MUTE, bits);
18147 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18148 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18149}
18150
18151static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18152 unsigned int res)
18153{
18154 if ((res >> 26) == ALC880_HP_EVENT)
18155 alc662_lenovo_101e_all_automute(codec);
18156 if ((res >> 26) == ALC880_FRONT_EVENT)
18157 alc662_lenovo_101e_ispeaker_automute(codec);
18158}
18159
291702f0
KY
18160/* unsolicited event for HP jack sensing */
18161static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18162 unsigned int res)
18163{
291702f0 18164 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18165 alc_mic_automute(codec);
42171c17
TI
18166 else
18167 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18168}
18169
4f5d1706
TI
18170static void alc662_eeepc_setup(struct hda_codec *codec)
18171{
18172 struct alc_spec *spec = codec->spec;
18173
18174 alc262_hippo1_setup(codec);
18175 spec->ext_mic.pin = 0x18;
18176 spec->ext_mic.mux_idx = 0;
18177 spec->int_mic.pin = 0x19;
18178 spec->int_mic.mux_idx = 1;
18179 spec->auto_mic = 1;
18180}
18181
291702f0
KY
18182static void alc662_eeepc_inithook(struct hda_codec *codec)
18183{
4f5d1706
TI
18184 alc262_hippo_automute(codec);
18185 alc_mic_automute(codec);
291702f0
KY
18186}
18187
4f5d1706 18188static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18189{
42171c17
TI
18190 struct alc_spec *spec = codec->spec;
18191
18192 spec->autocfg.hp_pins[0] = 0x14;
18193 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18194}
18195
4f5d1706
TI
18196#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18197
6dda9f4a
KY
18198static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18199{
18200 unsigned int present;
18201 unsigned char bits;
18202
864f92be 18203 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18204 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18205 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18206 HDA_AMP_MUTE, bits);
f1d4e28b 18207 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18208 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18209}
18210
18211static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18212{
18213 unsigned int present;
18214 unsigned char bits;
18215
864f92be 18216 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18217 bits = present ? HDA_AMP_MUTE : 0;
18218 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18219 HDA_AMP_MUTE, bits);
f1d4e28b 18220 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18221 HDA_AMP_MUTE, bits);
f1d4e28b 18222 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18223 HDA_AMP_MUTE, bits);
f1d4e28b 18224 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18225 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18226}
18227
18228static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18229{
18230 unsigned int present;
18231 unsigned char bits;
18232
864f92be 18233 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18234 bits = present ? HDA_AMP_MUTE : 0;
18235 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18236 HDA_AMP_MUTE, bits);
f1d4e28b 18237 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18238 HDA_AMP_MUTE, bits);
f1d4e28b 18239 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18240 HDA_AMP_MUTE, bits);
f1d4e28b 18241 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18242 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18243}
18244
18245static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18246{
18247 unsigned int present;
18248 unsigned char bits;
18249
864f92be 18250 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18251 bits = present ? 0 : PIN_OUT;
18252 snd_hda_codec_write(codec, 0x14, 0,
18253 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18254}
18255
18256static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18257{
18258 unsigned int present1, present2;
18259
864f92be
WF
18260 present1 = snd_hda_jack_detect(codec, 0x21);
18261 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18262
18263 if (present1 || present2) {
18264 snd_hda_codec_write_cache(codec, 0x14, 0,
18265 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18266 } else {
18267 snd_hda_codec_write_cache(codec, 0x14, 0,
18268 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18269 }
18270}
18271
18272static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18273{
18274 unsigned int present1, present2;
18275
864f92be
WF
18276 present1 = snd_hda_jack_detect(codec, 0x1b);
18277 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18278
18279 if (present1 || present2) {
18280 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18281 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18282 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18283 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18284 } else {
18285 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18286 HDA_AMP_MUTE, 0);
f1d4e28b 18287 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18288 HDA_AMP_MUTE, 0);
f1d4e28b 18289 }
6dda9f4a
KY
18290}
18291
ebb83eeb
KY
18292static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18293{
18294 unsigned int present1, present2;
18295
18296 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18297 AC_VERB_GET_PIN_SENSE, 0)
18298 & AC_PINSENSE_PRESENCE;
18299 present2 = snd_hda_codec_read(codec, 0x21, 0,
18300 AC_VERB_GET_PIN_SENSE, 0)
18301 & AC_PINSENSE_PRESENCE;
18302
18303 if (present1 || present2) {
18304 snd_hda_codec_write_cache(codec, 0x14, 0,
18305 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18306 snd_hda_codec_write_cache(codec, 0x17, 0,
18307 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18308 } else {
18309 snd_hda_codec_write_cache(codec, 0x14, 0,
18310 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18311 snd_hda_codec_write_cache(codec, 0x17, 0,
18312 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18313 }
18314}
18315
18316static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18317{
18318 unsigned int present1, present2;
18319
18320 present1 = snd_hda_codec_read(codec, 0x21, 0,
18321 AC_VERB_GET_PIN_SENSE, 0)
18322 & AC_PINSENSE_PRESENCE;
18323 present2 = snd_hda_codec_read(codec, 0x15, 0,
18324 AC_VERB_GET_PIN_SENSE, 0)
18325 & AC_PINSENSE_PRESENCE;
18326
18327 if (present1 || present2) {
18328 snd_hda_codec_write_cache(codec, 0x14, 0,
18329 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18330 snd_hda_codec_write_cache(codec, 0x17, 0,
18331 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18332 } else {
18333 snd_hda_codec_write_cache(codec, 0x14, 0,
18334 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18335 snd_hda_codec_write_cache(codec, 0x17, 0,
18336 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18337 }
18338}
18339
6dda9f4a
KY
18340static void alc663_m51va_unsol_event(struct hda_codec *codec,
18341 unsigned int res)
18342{
18343 switch (res >> 26) {
18344 case ALC880_HP_EVENT:
18345 alc663_m51va_speaker_automute(codec);
18346 break;
18347 case ALC880_MIC_EVENT:
4f5d1706 18348 alc_mic_automute(codec);
6dda9f4a
KY
18349 break;
18350 }
18351}
18352
4f5d1706
TI
18353static void alc663_m51va_setup(struct hda_codec *codec)
18354{
18355 struct alc_spec *spec = codec->spec;
18356 spec->ext_mic.pin = 0x18;
18357 spec->ext_mic.mux_idx = 0;
18358 spec->int_mic.pin = 0x12;
ebb83eeb 18359 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18360 spec->auto_mic = 1;
18361}
18362
6dda9f4a
KY
18363static void alc663_m51va_inithook(struct hda_codec *codec)
18364{
18365 alc663_m51va_speaker_automute(codec);
4f5d1706 18366 alc_mic_automute(codec);
6dda9f4a
KY
18367}
18368
f1d4e28b 18369/* ***************** Mode1 ******************************/
4f5d1706 18370#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18371
18372static void alc663_mode1_setup(struct hda_codec *codec)
18373{
18374 struct alc_spec *spec = codec->spec;
18375 spec->ext_mic.pin = 0x18;
18376 spec->ext_mic.mux_idx = 0;
18377 spec->int_mic.pin = 0x19;
18378 spec->int_mic.mux_idx = 1;
18379 spec->auto_mic = 1;
18380}
18381
4f5d1706 18382#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18383
f1d4e28b
KY
18384/* ***************** Mode2 ******************************/
18385static void alc662_mode2_unsol_event(struct hda_codec *codec,
18386 unsigned int res)
18387{
18388 switch (res >> 26) {
18389 case ALC880_HP_EVENT:
18390 alc662_f5z_speaker_automute(codec);
18391 break;
18392 case ALC880_MIC_EVENT:
4f5d1706 18393 alc_mic_automute(codec);
f1d4e28b
KY
18394 break;
18395 }
18396}
18397
ebb83eeb 18398#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18399
f1d4e28b
KY
18400static void alc662_mode2_inithook(struct hda_codec *codec)
18401{
18402 alc662_f5z_speaker_automute(codec);
4f5d1706 18403 alc_mic_automute(codec);
f1d4e28b
KY
18404}
18405/* ***************** Mode3 ******************************/
18406static void alc663_mode3_unsol_event(struct hda_codec *codec,
18407 unsigned int res)
18408{
18409 switch (res >> 26) {
18410 case ALC880_HP_EVENT:
18411 alc663_two_hp_m1_speaker_automute(codec);
18412 break;
18413 case ALC880_MIC_EVENT:
4f5d1706 18414 alc_mic_automute(codec);
f1d4e28b
KY
18415 break;
18416 }
18417}
18418
ebb83eeb 18419#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18420
f1d4e28b
KY
18421static void alc663_mode3_inithook(struct hda_codec *codec)
18422{
18423 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18424 alc_mic_automute(codec);
f1d4e28b
KY
18425}
18426/* ***************** Mode4 ******************************/
18427static void alc663_mode4_unsol_event(struct hda_codec *codec,
18428 unsigned int res)
18429{
18430 switch (res >> 26) {
18431 case ALC880_HP_EVENT:
18432 alc663_21jd_two_speaker_automute(codec);
18433 break;
18434 case ALC880_MIC_EVENT:
4f5d1706 18435 alc_mic_automute(codec);
f1d4e28b
KY
18436 break;
18437 }
18438}
18439
ebb83eeb 18440#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18441
f1d4e28b
KY
18442static void alc663_mode4_inithook(struct hda_codec *codec)
18443{
18444 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18445 alc_mic_automute(codec);
f1d4e28b
KY
18446}
18447/* ***************** Mode5 ******************************/
18448static void alc663_mode5_unsol_event(struct hda_codec *codec,
18449 unsigned int res)
18450{
18451 switch (res >> 26) {
18452 case ALC880_HP_EVENT:
18453 alc663_15jd_two_speaker_automute(codec);
18454 break;
18455 case ALC880_MIC_EVENT:
4f5d1706 18456 alc_mic_automute(codec);
f1d4e28b
KY
18457 break;
18458 }
18459}
18460
ebb83eeb 18461#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18462
f1d4e28b
KY
18463static void alc663_mode5_inithook(struct hda_codec *codec)
18464{
18465 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18466 alc_mic_automute(codec);
f1d4e28b
KY
18467}
18468/* ***************** Mode6 ******************************/
18469static void alc663_mode6_unsol_event(struct hda_codec *codec,
18470 unsigned int res)
18471{
18472 switch (res >> 26) {
18473 case ALC880_HP_EVENT:
18474 alc663_two_hp_m2_speaker_automute(codec);
18475 break;
18476 case ALC880_MIC_EVENT:
4f5d1706 18477 alc_mic_automute(codec);
f1d4e28b
KY
18478 break;
18479 }
18480}
18481
ebb83eeb 18482#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18483
f1d4e28b
KY
18484static void alc663_mode6_inithook(struct hda_codec *codec)
18485{
18486 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18487 alc_mic_automute(codec);
f1d4e28b
KY
18488}
18489
ebb83eeb
KY
18490/* ***************** Mode7 ******************************/
18491static void alc663_mode7_unsol_event(struct hda_codec *codec,
18492 unsigned int res)
18493{
18494 switch (res >> 26) {
18495 case ALC880_HP_EVENT:
18496 alc663_two_hp_m7_speaker_automute(codec);
18497 break;
18498 case ALC880_MIC_EVENT:
18499 alc_mic_automute(codec);
18500 break;
18501 }
18502}
18503
18504#define alc663_mode7_setup alc663_mode1_setup
18505
18506static void alc663_mode7_inithook(struct hda_codec *codec)
18507{
18508 alc663_two_hp_m7_speaker_automute(codec);
18509 alc_mic_automute(codec);
18510}
18511
18512/* ***************** Mode8 ******************************/
18513static void alc663_mode8_unsol_event(struct hda_codec *codec,
18514 unsigned int res)
18515{
18516 switch (res >> 26) {
18517 case ALC880_HP_EVENT:
18518 alc663_two_hp_m8_speaker_automute(codec);
18519 break;
18520 case ALC880_MIC_EVENT:
18521 alc_mic_automute(codec);
18522 break;
18523 }
18524}
18525
18526#define alc663_mode8_setup alc663_m51va_setup
18527
18528static void alc663_mode8_inithook(struct hda_codec *codec)
18529{
18530 alc663_two_hp_m8_speaker_automute(codec);
18531 alc_mic_automute(codec);
18532}
18533
6dda9f4a
KY
18534static void alc663_g71v_hp_automute(struct hda_codec *codec)
18535{
18536 unsigned int present;
18537 unsigned char bits;
18538
864f92be 18539 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18540 bits = present ? HDA_AMP_MUTE : 0;
18541 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18542 HDA_AMP_MUTE, bits);
18543 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18544 HDA_AMP_MUTE, bits);
18545}
18546
18547static void alc663_g71v_front_automute(struct hda_codec *codec)
18548{
18549 unsigned int present;
18550 unsigned char bits;
18551
864f92be 18552 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18553 bits = present ? HDA_AMP_MUTE : 0;
18554 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18555 HDA_AMP_MUTE, bits);
18556}
18557
18558static void alc663_g71v_unsol_event(struct hda_codec *codec,
18559 unsigned int res)
18560{
18561 switch (res >> 26) {
18562 case ALC880_HP_EVENT:
18563 alc663_g71v_hp_automute(codec);
18564 break;
18565 case ALC880_FRONT_EVENT:
18566 alc663_g71v_front_automute(codec);
18567 break;
18568 case ALC880_MIC_EVENT:
4f5d1706 18569 alc_mic_automute(codec);
6dda9f4a
KY
18570 break;
18571 }
18572}
18573
4f5d1706
TI
18574#define alc663_g71v_setup alc663_m51va_setup
18575
6dda9f4a
KY
18576static void alc663_g71v_inithook(struct hda_codec *codec)
18577{
18578 alc663_g71v_front_automute(codec);
18579 alc663_g71v_hp_automute(codec);
4f5d1706 18580 alc_mic_automute(codec);
6dda9f4a
KY
18581}
18582
18583static void alc663_g50v_unsol_event(struct hda_codec *codec,
18584 unsigned int res)
18585{
18586 switch (res >> 26) {
18587 case ALC880_HP_EVENT:
18588 alc663_m51va_speaker_automute(codec);
18589 break;
18590 case ALC880_MIC_EVENT:
4f5d1706 18591 alc_mic_automute(codec);
6dda9f4a
KY
18592 break;
18593 }
18594}
18595
4f5d1706
TI
18596#define alc663_g50v_setup alc663_m51va_setup
18597
6dda9f4a
KY
18598static void alc663_g50v_inithook(struct hda_codec *codec)
18599{
18600 alc663_m51va_speaker_automute(codec);
4f5d1706 18601 alc_mic_automute(codec);
6dda9f4a
KY
18602}
18603
f1d4e28b
KY
18604static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18605 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18606 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18607
5f99f86a 18608 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18609 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18610 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18611
5f99f86a 18612 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18613 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18614 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18615 { } /* end */
18616};
18617
9541ba1d
CP
18618static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18619 /* Master Playback automatically created from Speaker and Headphone */
18620 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18621 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18622 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18624
8607f7c4
DH
18625 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18626 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18627 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18628
28c4edb7
DH
18629 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18630 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18631 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18632 { } /* end */
18633};
18634
cb53c626
TI
18635#ifdef CONFIG_SND_HDA_POWER_SAVE
18636#define alc662_loopbacks alc880_loopbacks
18637#endif
18638
bc9f98a9 18639
def319f9 18640/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18641#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18642#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18643#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18644#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18645
18646/*
18647 * configuration and preset
18648 */
ea734963 18649static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18650 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18651 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18652 [ALC662_3ST_6ch] = "3stack-6ch",
18653 [ALC662_5ST_DIG] = "6stack-dig",
18654 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18655 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18656 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18657 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18658 [ALC663_ASUS_M51VA] = "m51va",
18659 [ALC663_ASUS_G71V] = "g71v",
18660 [ALC663_ASUS_H13] = "h13",
18661 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18662 [ALC663_ASUS_MODE1] = "asus-mode1",
18663 [ALC662_ASUS_MODE2] = "asus-mode2",
18664 [ALC663_ASUS_MODE3] = "asus-mode3",
18665 [ALC663_ASUS_MODE4] = "asus-mode4",
18666 [ALC663_ASUS_MODE5] = "asus-mode5",
18667 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18668 [ALC663_ASUS_MODE7] = "asus-mode7",
18669 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18670 [ALC272_DELL] = "dell",
18671 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18672 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18673 [ALC662_AUTO] = "auto",
18674};
18675
18676static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18677 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18678 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18679 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18680 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18681 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18682 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18683 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18684 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18685 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18686 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18687 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18688 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18689 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18690 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18691 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18692 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18693 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18694 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18695 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18696 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18697 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18698 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18699 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18700 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18701 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18702 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18703 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18704 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18705 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18706 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18707 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18708 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18709 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18710 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18711 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18712 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18713 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18714 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18715 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18716 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18717 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18718 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18719 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18720 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18721 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18722 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18723 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18724 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18725 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18726 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18727 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18728 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18729 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18730 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18731 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18732 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18733 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18734 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18735 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18736 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18737 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18738 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18739 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18740 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18741 ALC662_3ST_6ch_DIG),
4dee8baa 18742 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18743 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18744 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18745 ALC662_3ST_6ch_DIG),
6227cdce 18746 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18747 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18748 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18749 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18750 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18751 ALC662_3ST_6ch_DIG),
dea0a509
TI
18752 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18753 ALC663_ASUS_H13),
965b76d2 18754 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18755 {}
18756};
18757
18758static struct alc_config_preset alc662_presets[] = {
18759 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18760 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18761 .init_verbs = { alc662_init_verbs },
18762 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18763 .dac_nids = alc662_dac_nids,
18764 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18765 .dig_in_nid = ALC662_DIGIN_NID,
18766 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18767 .channel_mode = alc662_3ST_2ch_modes,
18768 .input_mux = &alc662_capture_source,
18769 },
18770 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18771 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18772 .init_verbs = { alc662_init_verbs },
18773 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18774 .dac_nids = alc662_dac_nids,
18775 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18776 .dig_in_nid = ALC662_DIGIN_NID,
18777 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18778 .channel_mode = alc662_3ST_6ch_modes,
18779 .need_dac_fix = 1,
18780 .input_mux = &alc662_capture_source,
f12ab1e0 18781 },
bc9f98a9 18782 [ALC662_3ST_6ch] = {
f9e336f6 18783 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18784 .init_verbs = { alc662_init_verbs },
18785 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18786 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18787 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18788 .channel_mode = alc662_3ST_6ch_modes,
18789 .need_dac_fix = 1,
18790 .input_mux = &alc662_capture_source,
f12ab1e0 18791 },
bc9f98a9 18792 [ALC662_5ST_DIG] = {
f9e336f6 18793 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18794 .init_verbs = { alc662_init_verbs },
18795 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18796 .dac_nids = alc662_dac_nids,
18797 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18798 .dig_in_nid = ALC662_DIGIN_NID,
18799 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18800 .channel_mode = alc662_5stack_modes,
18801 .input_mux = &alc662_capture_source,
18802 },
18803 [ALC662_LENOVO_101E] = {
f9e336f6 18804 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18805 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18806 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18807 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18808 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18809 .channel_mode = alc662_3ST_2ch_modes,
18810 .input_mux = &alc662_lenovo_101e_capture_source,
18811 .unsol_event = alc662_lenovo_101e_unsol_event,
18812 .init_hook = alc662_lenovo_101e_all_automute,
18813 },
291702f0 18814 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18815 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18816 .init_verbs = { alc662_init_verbs,
18817 alc662_eeepc_sue_init_verbs },
18818 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18819 .dac_nids = alc662_dac_nids,
291702f0
KY
18820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18821 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18822 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18823 .setup = alc662_eeepc_setup,
291702f0
KY
18824 .init_hook = alc662_eeepc_inithook,
18825 },
8c427226 18826 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18827 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18828 alc662_chmode_mixer },
18829 .init_verbs = { alc662_init_verbs,
18830 alc662_eeepc_ep20_sue_init_verbs },
18831 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18832 .dac_nids = alc662_dac_nids,
8c427226
KY
18833 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18834 .channel_mode = alc662_3ST_6ch_modes,
18835 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18836 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18837 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18838 .init_hook = alc662_eeepc_ep20_inithook,
18839 },
f1d4e28b 18840 [ALC662_ECS] = {
f9e336f6 18841 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18842 .init_verbs = { alc662_init_verbs,
18843 alc662_ecs_init_verbs },
18844 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18845 .dac_nids = alc662_dac_nids,
18846 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18847 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18848 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18849 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18850 .init_hook = alc662_eeepc_inithook,
18851 },
6dda9f4a 18852 [ALC663_ASUS_M51VA] = {
f9e336f6 18853 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18854 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18855 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18856 .dac_nids = alc662_dac_nids,
18857 .dig_out_nid = ALC662_DIGOUT_NID,
18858 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18859 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18860 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18861 .setup = alc663_m51va_setup,
6dda9f4a
KY
18862 .init_hook = alc663_m51va_inithook,
18863 },
18864 [ALC663_ASUS_G71V] = {
f9e336f6 18865 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18866 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18867 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18868 .dac_nids = alc662_dac_nids,
18869 .dig_out_nid = ALC662_DIGOUT_NID,
18870 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18871 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18872 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18873 .setup = alc663_g71v_setup,
6dda9f4a
KY
18874 .init_hook = alc663_g71v_inithook,
18875 },
18876 [ALC663_ASUS_H13] = {
f9e336f6 18877 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18878 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18879 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18880 .dac_nids = alc662_dac_nids,
18881 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18882 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18883 .unsol_event = alc663_m51va_unsol_event,
18884 .init_hook = alc663_m51va_inithook,
18885 },
18886 [ALC663_ASUS_G50V] = {
f9e336f6 18887 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18888 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18889 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18890 .dac_nids = alc662_dac_nids,
18891 .dig_out_nid = ALC662_DIGOUT_NID,
18892 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18893 .channel_mode = alc662_3ST_6ch_modes,
18894 .input_mux = &alc663_capture_source,
18895 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18896 .setup = alc663_g50v_setup,
6dda9f4a
KY
18897 .init_hook = alc663_g50v_inithook,
18898 },
f1d4e28b 18899 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18900 .mixers = { alc663_m51va_mixer },
18901 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18902 .init_verbs = { alc662_init_verbs,
18903 alc663_21jd_amic_init_verbs },
18904 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18905 .hp_nid = 0x03,
18906 .dac_nids = alc662_dac_nids,
18907 .dig_out_nid = ALC662_DIGOUT_NID,
18908 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18909 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18910 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18911 .setup = alc663_mode1_setup,
f1d4e28b
KY
18912 .init_hook = alc663_mode1_inithook,
18913 },
18914 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18915 .mixers = { alc662_1bjd_mixer },
18916 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18917 .init_verbs = { alc662_init_verbs,
18918 alc662_1bjd_amic_init_verbs },
18919 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18920 .dac_nids = alc662_dac_nids,
18921 .dig_out_nid = ALC662_DIGOUT_NID,
18922 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18923 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18924 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18925 .setup = alc662_mode2_setup,
f1d4e28b
KY
18926 .init_hook = alc662_mode2_inithook,
18927 },
18928 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18929 .mixers = { alc663_two_hp_m1_mixer },
18930 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18931 .init_verbs = { alc662_init_verbs,
18932 alc663_two_hp_amic_m1_init_verbs },
18933 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18934 .hp_nid = 0x03,
18935 .dac_nids = alc662_dac_nids,
18936 .dig_out_nid = ALC662_DIGOUT_NID,
18937 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18938 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18939 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18940 .setup = alc663_mode3_setup,
f1d4e28b
KY
18941 .init_hook = alc663_mode3_inithook,
18942 },
18943 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18944 .mixers = { alc663_asus_21jd_clfe_mixer },
18945 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18946 .init_verbs = { alc662_init_verbs,
18947 alc663_21jd_amic_init_verbs},
18948 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18949 .hp_nid = 0x03,
18950 .dac_nids = alc662_dac_nids,
18951 .dig_out_nid = ALC662_DIGOUT_NID,
18952 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18953 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18954 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18955 .setup = alc663_mode4_setup,
f1d4e28b
KY
18956 .init_hook = alc663_mode4_inithook,
18957 },
18958 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18959 .mixers = { alc663_asus_15jd_clfe_mixer },
18960 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18961 .init_verbs = { alc662_init_verbs,
18962 alc663_15jd_amic_init_verbs },
18963 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18964 .hp_nid = 0x03,
18965 .dac_nids = alc662_dac_nids,
18966 .dig_out_nid = ALC662_DIGOUT_NID,
18967 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18968 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18969 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18970 .setup = alc663_mode5_setup,
f1d4e28b
KY
18971 .init_hook = alc663_mode5_inithook,
18972 },
18973 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18974 .mixers = { alc663_two_hp_m2_mixer },
18975 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18976 .init_verbs = { alc662_init_verbs,
18977 alc663_two_hp_amic_m2_init_verbs },
18978 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18979 .hp_nid = 0x03,
18980 .dac_nids = alc662_dac_nids,
18981 .dig_out_nid = ALC662_DIGOUT_NID,
18982 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18983 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18984 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18985 .setup = alc663_mode6_setup,
f1d4e28b
KY
18986 .init_hook = alc663_mode6_inithook,
18987 },
ebb83eeb
KY
18988 [ALC663_ASUS_MODE7] = {
18989 .mixers = { alc663_mode7_mixer },
18990 .cap_mixer = alc662_auto_capture_mixer,
18991 .init_verbs = { alc662_init_verbs,
18992 alc663_mode7_init_verbs },
18993 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18994 .hp_nid = 0x03,
18995 .dac_nids = alc662_dac_nids,
18996 .dig_out_nid = ALC662_DIGOUT_NID,
18997 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18998 .channel_mode = alc662_3ST_2ch_modes,
18999 .unsol_event = alc663_mode7_unsol_event,
19000 .setup = alc663_mode7_setup,
19001 .init_hook = alc663_mode7_inithook,
19002 },
19003 [ALC663_ASUS_MODE8] = {
19004 .mixers = { alc663_mode8_mixer },
19005 .cap_mixer = alc662_auto_capture_mixer,
19006 .init_verbs = { alc662_init_verbs,
19007 alc663_mode8_init_verbs },
19008 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19009 .hp_nid = 0x03,
19010 .dac_nids = alc662_dac_nids,
19011 .dig_out_nid = ALC662_DIGOUT_NID,
19012 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19013 .channel_mode = alc662_3ST_2ch_modes,
19014 .unsol_event = alc663_mode8_unsol_event,
19015 .setup = alc663_mode8_setup,
19016 .init_hook = alc663_mode8_inithook,
19017 },
622e84cd
KY
19018 [ALC272_DELL] = {
19019 .mixers = { alc663_m51va_mixer },
19020 .cap_mixer = alc272_auto_capture_mixer,
19021 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
19022 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19023 .dac_nids = alc662_dac_nids,
19024 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19025 .adc_nids = alc272_adc_nids,
19026 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19027 .capsrc_nids = alc272_capsrc_nids,
19028 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19029 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19030 .setup = alc663_m51va_setup,
622e84cd
KY
19031 .init_hook = alc663_m51va_inithook,
19032 },
19033 [ALC272_DELL_ZM1] = {
19034 .mixers = { alc663_m51va_mixer },
19035 .cap_mixer = alc662_auto_capture_mixer,
19036 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19037 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19038 .dac_nids = alc662_dac_nids,
19039 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19040 .adc_nids = alc662_adc_nids,
b59bdf3b 19041 .num_adc_nids = 1,
622e84cd
KY
19042 .capsrc_nids = alc662_capsrc_nids,
19043 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19044 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19045 .setup = alc663_m51va_setup,
622e84cd
KY
19046 .init_hook = alc663_m51va_inithook,
19047 },
9541ba1d
CP
19048 [ALC272_SAMSUNG_NC10] = {
19049 .mixers = { alc272_nc10_mixer },
19050 .init_verbs = { alc662_init_verbs,
19051 alc663_21jd_amic_init_verbs },
19052 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19053 .dac_nids = alc272_dac_nids,
19054 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19055 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 19056 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 19057 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19058 .setup = alc663_mode4_setup,
9541ba1d
CP
19059 .init_hook = alc663_mode4_inithook,
19060 },
bc9f98a9
KY
19061};
19062
19063
19064/*
19065 * BIOS auto configuration
19066 */
19067
7085ec12
TI
19068/* convert from MIX nid to DAC */
19069static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19070{
19071 if (nid == 0x0f)
19072 return 0x02;
19073 else if (nid >= 0x0c && nid <= 0x0e)
19074 return nid - 0x0c + 0x02;
cc1c452e
DH
19075 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19076 return 0x25;
7085ec12
TI
19077 else
19078 return 0;
19079}
19080
19081/* get MIX nid connected to the given pin targeted to DAC */
19082static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19083 hda_nid_t dac)
19084{
cc1c452e 19085 hda_nid_t mix[5];
7085ec12
TI
19086 int i, num;
19087
19088 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19089 for (i = 0; i < num; i++) {
19090 if (alc662_mix_to_dac(mix[i]) == dac)
19091 return mix[i];
19092 }
19093 return 0;
19094}
19095
19096/* look for an empty DAC slot */
19097static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19098{
19099 struct alc_spec *spec = codec->spec;
19100 hda_nid_t srcs[5];
19101 int i, j, num;
19102
19103 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19104 if (num < 0)
19105 return 0;
19106 for (i = 0; i < num; i++) {
19107 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19108 if (!nid)
19109 continue;
19110 for (j = 0; j < spec->multiout.num_dacs; j++)
19111 if (spec->multiout.dac_nids[j] == nid)
19112 break;
19113 if (j >= spec->multiout.num_dacs)
19114 return nid;
19115 }
19116 return 0;
19117}
19118
19119/* fill in the dac_nids table from the parsed pin configuration */
19120static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19121 const struct auto_pin_cfg *cfg)
19122{
19123 struct alc_spec *spec = codec->spec;
19124 int i;
19125 hda_nid_t dac;
19126
19127 spec->multiout.dac_nids = spec->private_dac_nids;
19128 for (i = 0; i < cfg->line_outs; i++) {
19129 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19130 if (!dac)
19131 continue;
19132 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19133 }
19134 return 0;
19135}
19136
bcb2f0f5
TI
19137static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19138 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19139{
bcb2f0f5 19140 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
19141 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19142}
19143
bcb2f0f5
TI
19144static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19145 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19146{
bcb2f0f5 19147 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19148 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19149}
19150
bcb2f0f5
TI
19151#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19152 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19153#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19154 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19155#define alc662_add_stereo_vol(spec, pfx, nid) \
19156 alc662_add_vol_ctl(spec, pfx, nid, 3)
19157#define alc662_add_stereo_sw(spec, pfx, nid) \
19158 alc662_add_sw_ctl(spec, pfx, nid, 3)
19159
bc9f98a9 19160/* add playback controls from the parsed DAC table */
7085ec12 19161static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19162 const struct auto_pin_cfg *cfg)
19163{
7085ec12 19164 struct alc_spec *spec = codec->spec;
ea734963 19165 static const char * const chname[4] = {
bc9f98a9
KY
19166 "Front", "Surround", NULL /*CLFE*/, "Side"
19167 };
bcb2f0f5 19168 const char *pfx = alc_get_line_out_pfx(cfg, true);
7085ec12 19169 hda_nid_t nid, mix;
bc9f98a9
KY
19170 int i, err;
19171
19172 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19173 nid = spec->multiout.dac_nids[i];
19174 if (!nid)
19175 continue;
19176 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19177 if (!mix)
bc9f98a9 19178 continue;
bcb2f0f5 19179 if (!pfx && i == 2) {
bc9f98a9 19180 /* Center/LFE */
7085ec12 19181 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19182 if (err < 0)
19183 return err;
7085ec12 19184 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19185 if (err < 0)
19186 return err;
7085ec12 19187 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19188 if (err < 0)
19189 return err;
7085ec12 19190 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19191 if (err < 0)
19192 return err;
19193 } else {
bcb2f0f5
TI
19194 const char *name = pfx;
19195 if (!name)
19196 name = chname[i];
19197 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
bc9f98a9
KY
19198 if (err < 0)
19199 return err;
bcb2f0f5 19200 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
bc9f98a9
KY
19201 if (err < 0)
19202 return err;
19203 }
19204 }
19205 return 0;
19206}
19207
19208/* add playback controls for speaker and HP outputs */
7085ec12
TI
19209/* return DAC nid if any new DAC is assigned */
19210static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19211 const char *pfx)
19212{
7085ec12
TI
19213 struct alc_spec *spec = codec->spec;
19214 hda_nid_t nid, mix;
bc9f98a9 19215 int err;
bc9f98a9
KY
19216
19217 if (!pin)
19218 return 0;
7085ec12
TI
19219 nid = alc662_look_for_dac(codec, pin);
19220 if (!nid) {
7085ec12
TI
19221 /* the corresponding DAC is already occupied */
19222 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19223 return 0; /* no way */
19224 /* create a switch only */
0afe5f89 19225 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19226 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19227 }
19228
7085ec12
TI
19229 mix = alc662_dac_to_mix(codec, pin, nid);
19230 if (!mix)
19231 return 0;
19232 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19233 if (err < 0)
19234 return err;
19235 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19236 if (err < 0)
19237 return err;
19238 return nid;
bc9f98a9
KY
19239}
19240
19241/* create playback/capture controls for input pins */
05f5f477 19242#define alc662_auto_create_input_ctls \
4b7348a1 19243 alc882_auto_create_input_ctls
bc9f98a9
KY
19244
19245static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19246 hda_nid_t nid, int pin_type,
7085ec12 19247 hda_nid_t dac)
bc9f98a9 19248{
7085ec12 19249 int i, num;
ce503f38 19250 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19251
f6c7e546 19252 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19253 /* need the manual connection? */
7085ec12
TI
19254 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19255 if (num <= 1)
19256 return;
19257 for (i = 0; i < num; i++) {
19258 if (alc662_mix_to_dac(srcs[i]) != dac)
19259 continue;
19260 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19261 return;
bc9f98a9
KY
19262 }
19263}
19264
19265static void alc662_auto_init_multi_out(struct hda_codec *codec)
19266{
19267 struct alc_spec *spec = codec->spec;
7085ec12 19268 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19269 int i;
19270
19271 for (i = 0; i <= HDA_SIDE; i++) {
19272 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19273 if (nid)
baba8ee9 19274 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19275 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19276 }
19277}
19278
19279static void alc662_auto_init_hp_out(struct hda_codec *codec)
19280{
19281 struct alc_spec *spec = codec->spec;
19282 hda_nid_t pin;
19283
19284 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19285 if (pin)
19286 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19287 spec->multiout.hp_nid);
f6c7e546
TI
19288 pin = spec->autocfg.speaker_pins[0];
19289 if (pin)
7085ec12
TI
19290 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19291 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19292}
19293
bc9f98a9
KY
19294#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19295
19296static void alc662_auto_init_analog_input(struct hda_codec *codec)
19297{
19298 struct alc_spec *spec = codec->spec;
66ceeb6b 19299 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19300 int i;
19301
66ceeb6b
TI
19302 for (i = 0; i < cfg->num_inputs; i++) {
19303 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19304 if (alc_is_input_pin(codec, nid)) {
30ea098f 19305 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19306 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19307 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19308 snd_hda_codec_write(codec, nid, 0,
19309 AC_VERB_SET_AMP_GAIN_MUTE,
19310 AMP_OUT_MUTE);
19311 }
19312 }
19313}
19314
f511b01c
TI
19315#define alc662_auto_init_input_src alc882_auto_init_input_src
19316
bc9f98a9
KY
19317static int alc662_parse_auto_config(struct hda_codec *codec)
19318{
19319 struct alc_spec *spec = codec->spec;
19320 int err;
19321 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19322
19323 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19324 alc662_ignore);
19325 if (err < 0)
19326 return err;
19327 if (!spec->autocfg.line_outs)
19328 return 0; /* can't find valid BIOS pin config */
19329
7085ec12 19330 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19331 if (err < 0)
19332 return err;
7085ec12 19333 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19334 if (err < 0)
19335 return err;
7085ec12 19336 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19337 spec->autocfg.speaker_pins[0],
19338 "Speaker");
19339 if (err < 0)
19340 return err;
7085ec12
TI
19341 if (err)
19342 spec->multiout.extra_out_nid[0] = err;
19343 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19344 "Headphone");
19345 if (err < 0)
19346 return err;
7085ec12
TI
19347 if (err)
19348 spec->multiout.hp_nid = err;
05f5f477 19349 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19350 if (err < 0)
bc9f98a9
KY
19351 return err;
19352
19353 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19354
757899ac 19355 alc_auto_parse_digital(codec);
bc9f98a9 19356
603c4019 19357 if (spec->kctls.list)
d88897ea 19358 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19359
19360 spec->num_mux_defs = 1;
61b9b9b1 19361 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19362
cec27c89
KY
19363 add_verb(spec, alc662_init_verbs);
19364 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19365 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19366 add_verb(spec, alc663_init_verbs);
19367
19368 if (codec->vendor_id == 0x10ec0272)
19369 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19370
19371 err = alc_auto_add_mic_boost(codec);
19372 if (err < 0)
19373 return err;
19374
6227cdce
KY
19375 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19376 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19377 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19378 else
19379 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19380
8c87286f 19381 return 1;
bc9f98a9
KY
19382}
19383
19384/* additional initialization for auto-configuration model */
19385static void alc662_auto_init(struct hda_codec *codec)
19386{
f6c7e546 19387 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19388 alc662_auto_init_multi_out(codec);
19389 alc662_auto_init_hp_out(codec);
19390 alc662_auto_init_analog_input(codec);
f511b01c 19391 alc662_auto_init_input_src(codec);
757899ac 19392 alc_auto_init_digital(codec);
f6c7e546 19393 if (spec->unsol_event)
7fb0d78f 19394 alc_inithook(codec);
bc9f98a9
KY
19395}
19396
6be7948f 19397static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19398 const struct alc_fixup *fix, int action)
6fc398cb 19399{
b5bfbc67 19400 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19401 return;
6be7948f
TB
19402 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19403 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19404 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19405 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19406 (0 << AC_AMPCAP_MUTE_SHIFT)))
19407 printk(KERN_WARNING
19408 "hda_codec: failed to override amp caps for NID 0x2\n");
19409}
19410
6cb3b707 19411enum {
2df03514 19412 ALC662_FIXUP_ASPIRE,
6cb3b707 19413 ALC662_FIXUP_IDEAPAD,
6be7948f 19414 ALC272_FIXUP_MARIO,
d2ebd479 19415 ALC662_FIXUP_CZC_P10T,
6cb3b707
DH
19416};
19417
19418static const struct alc_fixup alc662_fixups[] = {
2df03514 19419 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19420 .type = ALC_FIXUP_PINS,
19421 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19422 { 0x15, 0x99130112 }, /* subwoofer */
19423 { }
19424 }
19425 },
6cb3b707 19426 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19427 .type = ALC_FIXUP_PINS,
19428 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19429 { 0x17, 0x99130112 }, /* subwoofer */
19430 { }
19431 }
19432 },
6be7948f 19433 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19434 .type = ALC_FIXUP_FUNC,
19435 .v.func = alc272_fixup_mario,
d2ebd479
AA
19436 },
19437 [ALC662_FIXUP_CZC_P10T] = {
19438 .type = ALC_FIXUP_VERBS,
19439 .v.verbs = (const struct hda_verb[]) {
19440 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19441 {}
19442 }
19443 },
6cb3b707
DH
19444};
19445
19446static struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19447 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
2df03514 19448 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19449 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19450 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19451 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19452 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19453 {}
19454};
19455
6be7948f
TB
19456static const struct alc_model_fixup alc662_fixup_models[] = {
19457 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19458 {}
19459};
6cb3b707
DH
19460
19461
bc9f98a9
KY
19462static int patch_alc662(struct hda_codec *codec)
19463{
19464 struct alc_spec *spec;
19465 int err, board_config;
693194f3 19466 int coef;
bc9f98a9
KY
19467
19468 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19469 if (!spec)
19470 return -ENOMEM;
19471
19472 codec->spec = spec;
19473
da00c244
KY
19474 alc_auto_parse_customize_define(codec);
19475
2c3bf9ab
TI
19476 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19477
693194f3
KY
19478 coef = alc_read_coef_idx(codec, 0);
19479 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19480 alc_codec_rename(codec, "ALC661");
693194f3
KY
19481 else if (coef & (1 << 14) &&
19482 codec->bus->pci->subsystem_vendor == 0x1025 &&
19483 spec->cdefine.platform_type == 1)
c027ddcd 19484 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19485 else if (coef == 0x4011)
19486 alc_codec_rename(codec, "ALC656");
274693f3 19487
bc9f98a9
KY
19488 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19489 alc662_models,
19490 alc662_cfg_tbl);
19491 if (board_config < 0) {
9a11f1aa
TI
19492 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19493 codec->chip_name);
bc9f98a9
KY
19494 board_config = ALC662_AUTO;
19495 }
19496
19497 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19498 alc_pick_fixup(codec, alc662_fixup_models,
19499 alc662_fixup_tbl, alc662_fixups);
19500 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19501 /* automatic parse from the BIOS config */
19502 err = alc662_parse_auto_config(codec);
19503 if (err < 0) {
19504 alc_free(codec);
19505 return err;
8c87286f 19506 } else if (!err) {
bc9f98a9
KY
19507 printk(KERN_INFO
19508 "hda_codec: Cannot set up configuration "
19509 "from BIOS. Using base mode...\n");
19510 board_config = ALC662_3ST_2ch_DIG;
19511 }
19512 }
19513
dc1eae25 19514 if (has_cdefine_beep(codec)) {
8af2591d
TI
19515 err = snd_hda_attach_beep_device(codec, 0x1);
19516 if (err < 0) {
19517 alc_free(codec);
19518 return err;
19519 }
680cd536
KK
19520 }
19521
bc9f98a9 19522 if (board_config != ALC662_AUTO)
e9c364c0 19523 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19524
bc9f98a9
KY
19525 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19526 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19527
bc9f98a9
KY
19528 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19529 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19530
dd704698
TI
19531 if (!spec->adc_nids) {
19532 spec->adc_nids = alc662_adc_nids;
19533 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19534 }
19535 if (!spec->capsrc_nids)
19536 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19537
f9e336f6 19538 if (!spec->cap_mixer)
b59bdf3b 19539 set_capture_mixer(codec);
cec27c89 19540
dc1eae25 19541 if (has_cdefine_beep(codec)) {
da00c244
KY
19542 switch (codec->vendor_id) {
19543 case 0x10ec0662:
19544 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19545 break;
19546 case 0x10ec0272:
19547 case 0x10ec0663:
19548 case 0x10ec0665:
19549 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19550 break;
19551 case 0x10ec0273:
19552 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19553 break;
19554 }
cec27c89 19555 }
2134ea4f
TI
19556 spec->vmaster_nid = 0x02;
19557
b5bfbc67
TI
19558 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19559
bc9f98a9 19560 codec->patch_ops = alc_patch_ops;
b5bfbc67 19561 if (board_config == ALC662_AUTO)
bc9f98a9 19562 spec->init_hook = alc662_auto_init;
6cb3b707 19563
bf1b0225
KY
19564 alc_init_jacks(codec);
19565
cb53c626
TI
19566#ifdef CONFIG_SND_HDA_POWER_SAVE
19567 if (!spec->loopback.amplist)
19568 spec->loopback.amplist = alc662_loopbacks;
19569#endif
bc9f98a9
KY
19570
19571 return 0;
19572}
19573
274693f3
KY
19574static int patch_alc888(struct hda_codec *codec)
19575{
19576 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19577 kfree(codec->chip_name);
01e0f137
KY
19578 if (codec->vendor_id == 0x10ec0887)
19579 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19580 else
19581 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19582 if (!codec->chip_name) {
19583 alc_free(codec);
274693f3 19584 return -ENOMEM;
ac2c92e0
TI
19585 }
19586 return patch_alc662(codec);
274693f3 19587 }
ac2c92e0 19588 return patch_alc882(codec);
274693f3
KY
19589}
19590
d1eb57f4
KY
19591/*
19592 * ALC680 support
19593 */
c69aefab 19594#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19595#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19596#define alc680_modes alc260_modes
19597
19598static hda_nid_t alc680_dac_nids[3] = {
19599 /* Lout1, Lout2, hp */
19600 0x02, 0x03, 0x04
19601};
19602
19603static hda_nid_t alc680_adc_nids[3] = {
19604 /* ADC0-2 */
19605 /* DMIC, MIC, Line-in*/
19606 0x07, 0x08, 0x09
19607};
19608
c69aefab
KY
19609/*
19610 * Analog capture ADC cgange
19611 */
66ceeb6b
TI
19612static void alc680_rec_autoswitch(struct hda_codec *codec)
19613{
19614 struct alc_spec *spec = codec->spec;
19615 struct auto_pin_cfg *cfg = &spec->autocfg;
19616 int pin_found = 0;
19617 int type_found = AUTO_PIN_LAST;
19618 hda_nid_t nid;
19619 int i;
19620
19621 for (i = 0; i < cfg->num_inputs; i++) {
19622 nid = cfg->inputs[i].pin;
19623 if (!(snd_hda_query_pin_caps(codec, nid) &
19624 AC_PINCAP_PRES_DETECT))
19625 continue;
19626 if (snd_hda_jack_detect(codec, nid)) {
19627 if (cfg->inputs[i].type < type_found) {
19628 type_found = cfg->inputs[i].type;
19629 pin_found = nid;
19630 }
19631 }
19632 }
19633
19634 nid = 0x07;
19635 if (pin_found)
19636 snd_hda_get_connections(codec, pin_found, &nid, 1);
19637
19638 if (nid != spec->cur_adc)
19639 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19640 spec->cur_adc = nid;
19641 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19642 spec->cur_adc_format);
19643}
19644
c69aefab
KY
19645static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19646 struct hda_codec *codec,
19647 unsigned int stream_tag,
19648 unsigned int format,
19649 struct snd_pcm_substream *substream)
19650{
19651 struct alc_spec *spec = codec->spec;
c69aefab 19652
66ceeb6b 19653 spec->cur_adc = 0x07;
c69aefab
KY
19654 spec->cur_adc_stream_tag = stream_tag;
19655 spec->cur_adc_format = format;
19656
66ceeb6b 19657 alc680_rec_autoswitch(codec);
c69aefab
KY
19658 return 0;
19659}
19660
19661static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19662 struct hda_codec *codec,
19663 struct snd_pcm_substream *substream)
19664{
19665 snd_hda_codec_cleanup_stream(codec, 0x07);
19666 snd_hda_codec_cleanup_stream(codec, 0x08);
19667 snd_hda_codec_cleanup_stream(codec, 0x09);
19668 return 0;
19669}
19670
19671static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19672 .substreams = 1, /* can be overridden */
19673 .channels_min = 2,
19674 .channels_max = 2,
19675 /* NID is set in alc_build_pcms */
19676 .ops = {
19677 .prepare = alc680_capture_pcm_prepare,
19678 .cleanup = alc680_capture_pcm_cleanup
19679 },
19680};
19681
d1eb57f4
KY
19682static struct snd_kcontrol_new alc680_base_mixer[] = {
19683 /* output mixer control */
19684 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19685 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19686 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19687 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19688 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19689 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19690 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19691 { }
19692};
19693
c69aefab
KY
19694static struct hda_bind_ctls alc680_bind_cap_vol = {
19695 .ops = &snd_hda_bind_vol,
19696 .values = {
19697 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19698 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19699 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19700 0
19701 },
19702};
19703
19704static struct hda_bind_ctls alc680_bind_cap_switch = {
19705 .ops = &snd_hda_bind_sw,
19706 .values = {
19707 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19708 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19709 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19710 0
19711 },
19712};
19713
19714static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19715 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19716 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19717 { } /* end */
19718};
19719
19720/*
19721 * generic initialization of ADC, input mixers and output mixers
19722 */
19723static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19724 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19725 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19726 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19727
c69aefab
KY
19728 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19730 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19731 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19732 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19733 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19734
19735 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19737 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19738 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19739 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19740
19741 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19742 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19743 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19744
d1eb57f4
KY
19745 { }
19746};
19747
c69aefab
KY
19748/* toggle speaker-output according to the hp-jack state */
19749static void alc680_base_setup(struct hda_codec *codec)
19750{
19751 struct alc_spec *spec = codec->spec;
19752
19753 spec->autocfg.hp_pins[0] = 0x16;
19754 spec->autocfg.speaker_pins[0] = 0x14;
19755 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19756 spec->autocfg.num_inputs = 2;
19757 spec->autocfg.inputs[0].pin = 0x18;
19758 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19759 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19760 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19761}
19762
19763static void alc680_unsol_event(struct hda_codec *codec,
19764 unsigned int res)
19765{
19766 if ((res >> 26) == ALC880_HP_EVENT)
19767 alc_automute_amp(codec);
19768 if ((res >> 26) == ALC880_MIC_EVENT)
19769 alc680_rec_autoswitch(codec);
19770}
19771
19772static void alc680_inithook(struct hda_codec *codec)
19773{
19774 alc_automute_amp(codec);
19775 alc680_rec_autoswitch(codec);
19776}
19777
d1eb57f4
KY
19778/* create input playback/capture controls for the given pin */
19779static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19780 const char *ctlname, int idx)
19781{
19782 hda_nid_t dac;
19783 int err;
19784
19785 switch (nid) {
19786 case 0x14:
19787 dac = 0x02;
19788 break;
19789 case 0x15:
19790 dac = 0x03;
19791 break;
19792 case 0x16:
19793 dac = 0x04;
19794 break;
19795 default:
19796 return 0;
19797 }
19798 if (spec->multiout.dac_nids[0] != dac &&
19799 spec->multiout.dac_nids[1] != dac) {
19800 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19801 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19802 HDA_OUTPUT));
19803 if (err < 0)
19804 return err;
19805
19806 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19807 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19808
19809 if (err < 0)
19810 return err;
19811 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19812 }
19813
19814 return 0;
19815}
19816
19817/* add playback controls from the parsed DAC table */
19818static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19819 const struct auto_pin_cfg *cfg)
19820{
19821 hda_nid_t nid;
19822 int err;
19823
19824 spec->multiout.dac_nids = spec->private_dac_nids;
19825
19826 nid = cfg->line_out_pins[0];
19827 if (nid) {
19828 const char *name;
19829 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19830 name = "Speaker";
19831 else
19832 name = "Front";
19833 err = alc680_new_analog_output(spec, nid, name, 0);
19834 if (err < 0)
19835 return err;
19836 }
19837
19838 nid = cfg->speaker_pins[0];
19839 if (nid) {
19840 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19841 if (err < 0)
19842 return err;
19843 }
19844 nid = cfg->hp_pins[0];
19845 if (nid) {
19846 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19847 if (err < 0)
19848 return err;
19849 }
19850
19851 return 0;
19852}
19853
19854static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19855 hda_nid_t nid, int pin_type)
19856{
19857 alc_set_pin_output(codec, nid, pin_type);
19858}
19859
19860static void alc680_auto_init_multi_out(struct hda_codec *codec)
19861{
19862 struct alc_spec *spec = codec->spec;
19863 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19864 if (nid) {
19865 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19866 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19867 }
19868}
19869
19870static void alc680_auto_init_hp_out(struct hda_codec *codec)
19871{
19872 struct alc_spec *spec = codec->spec;
19873 hda_nid_t pin;
19874
19875 pin = spec->autocfg.hp_pins[0];
19876 if (pin)
19877 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19878 pin = spec->autocfg.speaker_pins[0];
19879 if (pin)
19880 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19881}
19882
19883/* pcm configuration: identical with ALC880 */
19884#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19885#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19886#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19887#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19888#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19889
19890/*
19891 * BIOS auto configuration
19892 */
19893static int alc680_parse_auto_config(struct hda_codec *codec)
19894{
19895 struct alc_spec *spec = codec->spec;
19896 int err;
19897 static hda_nid_t alc680_ignore[] = { 0 };
19898
19899 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19900 alc680_ignore);
19901 if (err < 0)
19902 return err;
c69aefab 19903
d1eb57f4
KY
19904 if (!spec->autocfg.line_outs) {
19905 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19906 spec->multiout.max_channels = 2;
19907 spec->no_analog = 1;
19908 goto dig_only;
19909 }
19910 return 0; /* can't find valid BIOS pin config */
19911 }
19912 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19913 if (err < 0)
19914 return err;
19915
19916 spec->multiout.max_channels = 2;
19917
19918 dig_only:
19919 /* digital only support output */
757899ac 19920 alc_auto_parse_digital(codec);
d1eb57f4
KY
19921 if (spec->kctls.list)
19922 add_mixer(spec, spec->kctls.list);
19923
19924 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19925
19926 err = alc_auto_add_mic_boost(codec);
19927 if (err < 0)
19928 return err;
19929
19930 return 1;
19931}
19932
19933#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19934
19935/* init callback for auto-configuration model -- overriding the default init */
19936static void alc680_auto_init(struct hda_codec *codec)
19937{
19938 struct alc_spec *spec = codec->spec;
19939 alc680_auto_init_multi_out(codec);
19940 alc680_auto_init_hp_out(codec);
19941 alc680_auto_init_analog_input(codec);
757899ac 19942 alc_auto_init_digital(codec);
d1eb57f4
KY
19943 if (spec->unsol_event)
19944 alc_inithook(codec);
19945}
19946
19947/*
19948 * configuration and preset
19949 */
ea734963 19950static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19951 [ALC680_BASE] = "base",
19952 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19953};
19954
19955static struct snd_pci_quirk alc680_cfg_tbl[] = {
19956 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19957 {}
19958};
19959
19960static struct alc_config_preset alc680_presets[] = {
19961 [ALC680_BASE] = {
19962 .mixers = { alc680_base_mixer },
c69aefab 19963 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19964 .init_verbs = { alc680_init_verbs },
19965 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19966 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19967 .dig_out_nid = ALC680_DIGOUT_NID,
19968 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19969 .channel_mode = alc680_modes,
c69aefab
KY
19970 .unsol_event = alc680_unsol_event,
19971 .setup = alc680_base_setup,
19972 .init_hook = alc680_inithook,
19973
d1eb57f4
KY
19974 },
19975};
19976
19977static int patch_alc680(struct hda_codec *codec)
19978{
19979 struct alc_spec *spec;
19980 int board_config;
19981 int err;
19982
19983 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19984 if (spec == NULL)
19985 return -ENOMEM;
19986
19987 codec->spec = spec;
19988
19989 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19990 alc680_models,
19991 alc680_cfg_tbl);
19992
19993 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19994 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19995 codec->chip_name);
19996 board_config = ALC680_AUTO;
19997 }
19998
19999 if (board_config == ALC680_AUTO) {
20000 /* automatic parse from the BIOS config */
20001 err = alc680_parse_auto_config(codec);
20002 if (err < 0) {
20003 alc_free(codec);
20004 return err;
20005 } else if (!err) {
20006 printk(KERN_INFO
20007 "hda_codec: Cannot set up configuration "
20008 "from BIOS. Using base mode...\n");
20009 board_config = ALC680_BASE;
20010 }
20011 }
20012
20013 if (board_config != ALC680_AUTO)
20014 setup_preset(codec, &alc680_presets[board_config]);
20015
20016 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 20017 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 20018 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 20019 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
20020
20021 if (!spec->adc_nids) {
20022 spec->adc_nids = alc680_adc_nids;
20023 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20024 }
20025
20026 if (!spec->cap_mixer)
20027 set_capture_mixer(codec);
20028
20029 spec->vmaster_nid = 0x02;
20030
20031 codec->patch_ops = alc_patch_ops;
20032 if (board_config == ALC680_AUTO)
20033 spec->init_hook = alc680_auto_init;
20034
20035 return 0;
20036}
20037
1da177e4
LT
20038/*
20039 * patch entries
20040 */
1289e9e8 20041static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 20042 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20043 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20044 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20045 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20046 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20047 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20048 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20049 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20050 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20051 .patch = patch_alc861 },
f32610ed
JS
20052 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20053 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20054 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20055 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20056 .patch = patch_alc882 },
bc9f98a9
KY
20057 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20058 .patch = patch_alc662 },
6dda9f4a 20059 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20060 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20061 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20062 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20063 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20064 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20065 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20066 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20067 .patch = patch_alc882 },
cb308f97 20068 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20069 .patch = patch_alc882 },
df694daa 20070 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20071 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20072 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20073 .patch = patch_alc882 },
274693f3 20074 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20075 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20076 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20077 {} /* terminator */
20078};
1289e9e8
TI
20079
20080MODULE_ALIAS("snd-hda-codec-id:10ec*");
20081
20082MODULE_LICENSE("GPL");
20083MODULE_DESCRIPTION("Realtek HD-audio codec");
20084
20085static struct hda_codec_preset_list realtek_list = {
20086 .preset = snd_hda_preset_realtek,
20087 .owner = THIS_MODULE,
20088};
20089
20090static int __init patch_realtek_init(void)
20091{
20092 return snd_hda_add_codec_preset(&realtek_list);
20093}
20094
20095static void __exit patch_realtek_exit(void)
20096{
20097 snd_hda_delete_codec_preset(&realtek_list);
20098}
20099
20100module_init(patch_realtek_init)
20101module_exit(patch_realtek_exit)