]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Initialize special cases for input src in init phase
[mirror_ubuntu-eoan-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) */
584c0c4c 388 unsigned int single_input_src:1;
4a79ba34 389 int init_amp;
d433a678 390 int codec_variant; /* flag for other variants */
e64f14f4 391
2134ea4f
TI
392 /* for virtual master */
393 hda_nid_t vmaster_nid;
cb53c626
TI
394#ifdef CONFIG_SND_HDA_POWER_SAVE
395 struct hda_loopback_check loopback;
396#endif
2c3bf9ab
TI
397
398 /* for PLL fix */
399 hda_nid_t pll_nid;
400 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
401
402 /* fix-up list */
403 int fixup_id;
404 const struct alc_fixup *fixup_list;
405 const char *fixup_name;
df694daa
KY
406};
407
408/*
409 * configuration template - to be copied to the spec instance
410 */
411struct alc_config_preset {
9c7f852e
TI
412 struct snd_kcontrol_new *mixers[5]; /* should be identical size
413 * with spec
414 */
f9e336f6 415 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
416 const struct hda_verb *init_verbs[5];
417 unsigned int num_dacs;
418 hda_nid_t *dac_nids;
419 hda_nid_t dig_out_nid; /* optional */
420 hda_nid_t hp_nid; /* optional */
b25c9da1 421 hda_nid_t *slave_dig_outs;
df694daa
KY
422 unsigned int num_adc_nids;
423 hda_nid_t *adc_nids;
e1406348 424 hda_nid_t *capsrc_nids;
df694daa
KY
425 hda_nid_t dig_in_nid;
426 unsigned int num_channel_mode;
427 const struct hda_channel_mode *channel_mode;
4e195a7b 428 int need_dac_fix;
3b315d70 429 int const_channel_count;
a1e8d2da 430 unsigned int num_mux_defs;
df694daa 431 const struct hda_input_mux *input_mux;
ae6b813a 432 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 433 void (*setup)(struct hda_codec *);
ae6b813a 434 void (*init_hook)(struct hda_codec *);
cb53c626
TI
435#ifdef CONFIG_SND_HDA_POWER_SAVE
436 struct hda_amp_list *loopbacks;
c97259df 437 void (*power_hook)(struct hda_codec *codec);
cb53c626 438#endif
1da177e4
LT
439};
440
1da177e4
LT
441
442/*
443 * input MUX handling
444 */
9c7f852e
TI
445static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
447{
448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
449 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
450 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
451 if (mux_idx >= spec->num_mux_defs)
452 mux_idx = 0;
5311114d
TI
453 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
454 mux_idx = 0;
a1e8d2da 455 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
456}
457
9c7f852e
TI
458static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
460{
461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct alc_spec *spec = codec->spec;
463 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
464
465 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
466 return 0;
467}
468
9c7f852e
TI
469static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
471{
472 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
473 struct alc_spec *spec = codec->spec;
cd896c33 474 const struct hda_input_mux *imux;
1da177e4 475 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 476 unsigned int mux_idx;
e1406348
TI
477 hda_nid_t nid = spec->capsrc_nids ?
478 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 479 unsigned int type;
1da177e4 480
cd896c33
TI
481 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
482 imux = &spec->input_mux[mux_idx];
5311114d
TI
483 if (!imux->num_items && mux_idx > 0)
484 imux = &spec->input_mux[0];
cd896c33 485
a22d543a 486 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 487 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
488 /* Matrix-mixer style (e.g. ALC882) */
489 unsigned int *cur_val = &spec->cur_mux[adc_idx];
490 unsigned int i, idx;
491
492 idx = ucontrol->value.enumerated.item[0];
493 if (idx >= imux->num_items)
494 idx = imux->num_items - 1;
495 if (*cur_val == idx)
496 return 0;
497 for (i = 0; i < imux->num_items; i++) {
498 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
499 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
500 imux->items[i].index,
501 HDA_AMP_MUTE, v);
502 }
503 *cur_val = idx;
504 return 1;
505 } else {
506 /* MUX style (e.g. ALC880) */
cd896c33 507 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
508 &spec->cur_mux[adc_idx]);
509 }
510}
e9edcee0 511
1da177e4
LT
512/*
513 * channel mode setting
514 */
9c7f852e
TI
515static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
516 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
517{
518 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
519 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
520 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
521 spec->num_channel_mode);
1da177e4
LT
522}
523
9c7f852e
TI
524static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
525 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
526{
527 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
528 struct alc_spec *spec = codec->spec;
d2a6d7dc 529 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 530 spec->num_channel_mode,
3b315d70 531 spec->ext_channel_count);
1da177e4
LT
532}
533
9c7f852e
TI
534static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
535 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
536{
537 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
538 struct alc_spec *spec = codec->spec;
4e195a7b
TI
539 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
540 spec->num_channel_mode,
3b315d70
HM
541 &spec->ext_channel_count);
542 if (err >= 0 && !spec->const_channel_count) {
543 spec->multiout.max_channels = spec->ext_channel_count;
544 if (spec->need_dac_fix)
545 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
546 }
4e195a7b 547 return err;
1da177e4
LT
548}
549
a9430dd8 550/*
4c5186ed 551 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 552 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
553 * being part of a format specifier. Maximum allowed length of a value is
554 * 63 characters plus NULL terminator.
7cf51e48
JW
555 *
556 * Note: some retasking pin complexes seem to ignore requests for input
557 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
558 * are requested. Therefore order this list so that this behaviour will not
559 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
560 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
561 * March 2006.
4c5186ed
JW
562 */
563static char *alc_pin_mode_names[] = {
7cf51e48
JW
564 "Mic 50pc bias", "Mic 80pc bias",
565 "Line in", "Line out", "Headphone out",
4c5186ed
JW
566};
567static unsigned char alc_pin_mode_values[] = {
7cf51e48 568 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
569};
570/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
571 * in the pin being assumed to be exclusively an input or an output pin. In
572 * addition, "input" pins may or may not process the mic bias option
573 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
574 * accept requests for bias as of chip versions up to March 2006) and/or
575 * wiring in the computer.
a9430dd8 576 */
a1e8d2da
JW
577#define ALC_PIN_DIR_IN 0x00
578#define ALC_PIN_DIR_OUT 0x01
579#define ALC_PIN_DIR_INOUT 0x02
580#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
581#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 582
ea1fb29a 583/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
584 * For each direction the minimum and maximum values are given.
585 */
a1e8d2da 586static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
587 { 0, 2 }, /* ALC_PIN_DIR_IN */
588 { 3, 4 }, /* ALC_PIN_DIR_OUT */
589 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
590 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
591 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
592};
593#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
594#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
595#define alc_pin_mode_n_items(_dir) \
596 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
597
9c7f852e
TI
598static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
599 struct snd_ctl_elem_info *uinfo)
a9430dd8 600{
4c5186ed
JW
601 unsigned int item_num = uinfo->value.enumerated.item;
602 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
603
604 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 605 uinfo->count = 1;
4c5186ed
JW
606 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
607
608 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
609 item_num = alc_pin_mode_min(dir);
610 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
611 return 0;
612}
613
9c7f852e
TI
614static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_value *ucontrol)
a9430dd8 616{
4c5186ed 617 unsigned int i;
a9430dd8
JW
618 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
619 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 620 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 621 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
622 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
623 AC_VERB_GET_PIN_WIDGET_CONTROL,
624 0x00);
a9430dd8 625
4c5186ed
JW
626 /* Find enumerated value for current pinctl setting */
627 i = alc_pin_mode_min(dir);
4b35d2ca 628 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 629 i++;
9c7f852e 630 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
631 return 0;
632}
633
9c7f852e
TI
634static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
a9430dd8 636{
4c5186ed 637 signed int change;
a9430dd8
JW
638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
639 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
640 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
641 long val = *ucontrol->value.integer.value;
9c7f852e
TI
642 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
643 AC_VERB_GET_PIN_WIDGET_CONTROL,
644 0x00);
a9430dd8 645
f12ab1e0 646 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
647 val = alc_pin_mode_min(dir);
648
649 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
650 if (change) {
651 /* Set pin mode to that requested */
82beb8fd
TI
652 snd_hda_codec_write_cache(codec, nid, 0,
653 AC_VERB_SET_PIN_WIDGET_CONTROL,
654 alc_pin_mode_values[val]);
cdcd9268 655
ea1fb29a 656 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
657 * for the requested pin mode. Enum values of 2 or less are
658 * input modes.
659 *
660 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
661 * reduces noise slightly (particularly on input) so we'll
662 * do it. However, having both input and output buffers
663 * enabled simultaneously doesn't seem to be problematic if
664 * this turns out to be necessary in the future.
cdcd9268
JW
665 */
666 if (val <= 2) {
47fd830a
TI
667 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
668 HDA_AMP_MUTE, HDA_AMP_MUTE);
669 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
670 HDA_AMP_MUTE, 0);
cdcd9268 671 } else {
47fd830a
TI
672 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
673 HDA_AMP_MUTE, HDA_AMP_MUTE);
674 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
675 HDA_AMP_MUTE, 0);
cdcd9268
JW
676 }
677 }
a9430dd8
JW
678 return change;
679}
680
4c5186ed 681#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 682 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 683 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
684 .info = alc_pin_mode_info, \
685 .get = alc_pin_mode_get, \
686 .put = alc_pin_mode_put, \
687 .private_value = nid | (dir<<16) }
df694daa 688
5c8f858d
JW
689/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
690 * together using a mask with more than one bit set. This control is
691 * currently used only by the ALC260 test model. At this stage they are not
692 * needed for any "production" models.
693 */
694#ifdef CONFIG_SND_DEBUG
a5ce8890 695#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 696
9c7f852e
TI
697static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
698 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
699{
700 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
701 hda_nid_t nid = kcontrol->private_value & 0xffff;
702 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
703 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
704 unsigned int val = snd_hda_codec_read(codec, nid, 0,
705 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
706
707 *valp = (val & mask) != 0;
708 return 0;
709}
9c7f852e
TI
710static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
711 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
712{
713 signed int change;
714 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
715 hda_nid_t nid = kcontrol->private_value & 0xffff;
716 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
717 long val = *ucontrol->value.integer.value;
9c7f852e
TI
718 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
719 AC_VERB_GET_GPIO_DATA,
720 0x00);
5c8f858d
JW
721
722 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
723 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
724 if (val == 0)
5c8f858d
JW
725 gpio_data &= ~mask;
726 else
727 gpio_data |= mask;
82beb8fd
TI
728 snd_hda_codec_write_cache(codec, nid, 0,
729 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
730
731 return change;
732}
733#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
734 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 735 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
736 .info = alc_gpio_data_info, \
737 .get = alc_gpio_data_get, \
738 .put = alc_gpio_data_put, \
739 .private_value = nid | (mask<<16) }
740#endif /* CONFIG_SND_DEBUG */
741
92621f13
JW
742/* A switch control to allow the enabling of the digital IO pins on the
743 * ALC260. This is incredibly simplistic; the intention of this control is
744 * to provide something in the test model allowing digital outputs to be
745 * identified if present. If models are found which can utilise these
746 * outputs a more complete mixer control can be devised for those models if
747 * necessary.
748 */
749#ifdef CONFIG_SND_DEBUG
a5ce8890 750#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 751
9c7f852e
TI
752static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
753 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
754{
755 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
756 hda_nid_t nid = kcontrol->private_value & 0xffff;
757 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
758 long *valp = ucontrol->value.integer.value;
9c7f852e 759 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 760 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
761
762 *valp = (val & mask) != 0;
763 return 0;
764}
9c7f852e
TI
765static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
766 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
767{
768 signed int change;
769 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
770 hda_nid_t nid = kcontrol->private_value & 0xffff;
771 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
772 long val = *ucontrol->value.integer.value;
9c7f852e 773 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 774 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 775 0x00);
92621f13
JW
776
777 /* Set/unset the masked control bit(s) as needed */
9c7f852e 778 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
779 if (val==0)
780 ctrl_data &= ~mask;
781 else
782 ctrl_data |= mask;
82beb8fd
TI
783 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
784 ctrl_data);
92621f13
JW
785
786 return change;
787}
788#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
789 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 790 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
791 .info = alc_spdif_ctrl_info, \
792 .get = alc_spdif_ctrl_get, \
793 .put = alc_spdif_ctrl_put, \
794 .private_value = nid | (mask<<16) }
795#endif /* CONFIG_SND_DEBUG */
796
f8225f6d
JW
797/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
798 * Again, this is only used in the ALC26x test models to help identify when
799 * the EAPD line must be asserted for features to work.
800 */
801#ifdef CONFIG_SND_DEBUG
802#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
803
804static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
805 struct snd_ctl_elem_value *ucontrol)
806{
807 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
808 hda_nid_t nid = kcontrol->private_value & 0xffff;
809 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
810 long *valp = ucontrol->value.integer.value;
811 unsigned int val = snd_hda_codec_read(codec, nid, 0,
812 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
813
814 *valp = (val & mask) != 0;
815 return 0;
816}
817
818static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
819 struct snd_ctl_elem_value *ucontrol)
820{
821 int change;
822 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
823 hda_nid_t nid = kcontrol->private_value & 0xffff;
824 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
825 long val = *ucontrol->value.integer.value;
826 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
827 AC_VERB_GET_EAPD_BTLENABLE,
828 0x00);
829
830 /* Set/unset the masked control bit(s) as needed */
831 change = (!val ? 0 : mask) != (ctrl_data & mask);
832 if (!val)
833 ctrl_data &= ~mask;
834 else
835 ctrl_data |= mask;
836 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
837 ctrl_data);
838
839 return change;
840}
841
842#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
843 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 844 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
845 .info = alc_eapd_ctrl_info, \
846 .get = alc_eapd_ctrl_get, \
847 .put = alc_eapd_ctrl_put, \
848 .private_value = nid | (mask<<16) }
849#endif /* CONFIG_SND_DEBUG */
850
23f0c048
TI
851/*
852 * set up the input pin config (depending on the given auto-pin type)
853 */
854static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
855 int auto_pin_type)
856{
857 unsigned int val = PIN_IN;
858
86e2959a 859 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 860 unsigned int pincap;
954a29c8
TI
861 unsigned int oldval;
862 oldval = snd_hda_codec_read(codec, nid, 0,
863 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 864 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 865 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
866 /* if the default pin setup is vref50, we give it priority */
867 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 868 val = PIN_VREF80;
461c6c3a
TI
869 else if (pincap & AC_PINCAP_VREF_50)
870 val = PIN_VREF50;
871 else if (pincap & AC_PINCAP_VREF_100)
872 val = PIN_VREF100;
873 else if (pincap & AC_PINCAP_VREF_GRD)
874 val = PIN_VREFGRD;
23f0c048
TI
875 }
876 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
877}
878
f6837bbd
TI
879static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
880{
881 struct alc_spec *spec = codec->spec;
882 struct auto_pin_cfg *cfg = &spec->autocfg;
883
884 if (!cfg->line_outs) {
885 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
886 cfg->line_out_pins[cfg->line_outs])
887 cfg->line_outs++;
888 }
889 if (!cfg->speaker_outs) {
890 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
891 cfg->speaker_pins[cfg->speaker_outs])
892 cfg->speaker_outs++;
893 }
894 if (!cfg->hp_outs) {
895 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
896 cfg->hp_pins[cfg->hp_outs])
897 cfg->hp_outs++;
898 }
899}
900
d88897ea
TI
901/*
902 */
903static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
904{
905 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
906 return;
907 spec->mixers[spec->num_mixers++] = mix;
908}
909
910static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
911{
912 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
913 return;
914 spec->init_verbs[spec->num_init_verbs++] = verb;
915}
916
df694daa
KY
917/*
918 * set up from the preset table
919 */
e9c364c0 920static void setup_preset(struct hda_codec *codec,
9c7f852e 921 const struct alc_config_preset *preset)
df694daa 922{
e9c364c0 923 struct alc_spec *spec = codec->spec;
df694daa
KY
924 int i;
925
926 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 927 add_mixer(spec, preset->mixers[i]);
f9e336f6 928 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
929 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
930 i++)
d88897ea 931 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 932
df694daa
KY
933 spec->channel_mode = preset->channel_mode;
934 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 935 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 936 spec->const_channel_count = preset->const_channel_count;
df694daa 937
3b315d70
HM
938 if (preset->const_channel_count)
939 spec->multiout.max_channels = preset->const_channel_count;
940 else
941 spec->multiout.max_channels = spec->channel_mode[0].channels;
942 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
943
944 spec->multiout.num_dacs = preset->num_dacs;
945 spec->multiout.dac_nids = preset->dac_nids;
946 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 947 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 948 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 949
a1e8d2da 950 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 951 if (!spec->num_mux_defs)
a1e8d2da 952 spec->num_mux_defs = 1;
df694daa
KY
953 spec->input_mux = preset->input_mux;
954
955 spec->num_adc_nids = preset->num_adc_nids;
956 spec->adc_nids = preset->adc_nids;
e1406348 957 spec->capsrc_nids = preset->capsrc_nids;
df694daa 958 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
959
960 spec->unsol_event = preset->unsol_event;
961 spec->init_hook = preset->init_hook;
cb53c626 962#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 963 spec->power_hook = preset->power_hook;
cb53c626
TI
964 spec->loopback.amplist = preset->loopbacks;
965#endif
e9c364c0
TI
966
967 if (preset->setup)
968 preset->setup(codec);
f6837bbd
TI
969
970 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
971}
972
bc9f98a9
KY
973/* Enable GPIO mask and set output */
974static struct hda_verb alc_gpio1_init_verbs[] = {
975 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
976 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
977 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
978 { }
979};
980
981static struct hda_verb alc_gpio2_init_verbs[] = {
982 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
983 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
984 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
985 { }
986};
987
bdd148a3
KY
988static struct hda_verb alc_gpio3_init_verbs[] = {
989 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
990 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
991 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
992 { }
993};
994
2c3bf9ab
TI
995/*
996 * Fix hardware PLL issue
997 * On some codecs, the analog PLL gating control must be off while
998 * the default value is 1.
999 */
1000static void alc_fix_pll(struct hda_codec *codec)
1001{
1002 struct alc_spec *spec = codec->spec;
1003 unsigned int val;
1004
1005 if (!spec->pll_nid)
1006 return;
1007 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1008 spec->pll_coef_idx);
1009 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1010 AC_VERB_GET_PROC_COEF, 0);
1011 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1012 spec->pll_coef_idx);
1013 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1014 val & ~(1 << spec->pll_coef_bit));
1015}
1016
1017static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1018 unsigned int coef_idx, unsigned int coef_bit)
1019{
1020 struct alc_spec *spec = codec->spec;
1021 spec->pll_nid = nid;
1022 spec->pll_coef_idx = coef_idx;
1023 spec->pll_coef_bit = coef_bit;
1024 alc_fix_pll(codec);
1025}
1026
9ad0e496
KY
1027static int alc_init_jacks(struct hda_codec *codec)
1028{
cd372fb3 1029#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1030 struct alc_spec *spec = codec->spec;
1031 int err;
1032 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1033 unsigned int mic_nid = spec->ext_mic.pin;
1034
265a0247 1035 if (hp_nid) {
cd372fb3
TI
1036 err = snd_hda_input_jack_add(codec, hp_nid,
1037 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1038 if (err < 0)
1039 return err;
cd372fb3 1040 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1041 }
9ad0e496 1042
265a0247 1043 if (mic_nid) {
cd372fb3
TI
1044 err = snd_hda_input_jack_add(codec, mic_nid,
1045 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1046 if (err < 0)
1047 return err;
cd372fb3 1048 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1049 }
cd372fb3 1050#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1051 return 0;
1052}
9ad0e496 1053
bb35febd 1054static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
c9b58006
KY
1055{
1056 struct alc_spec *spec = codec->spec;
bb35febd
TI
1057 unsigned int mute;
1058 hda_nid_t nid;
a9fd4f3f 1059 int i;
c9b58006 1060
bb35febd
TI
1061 spec->jack_present = 0;
1062 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1063 nid = spec->autocfg.hp_pins[i];
1064 if (!nid)
1065 break;
cd372fb3 1066 snd_hda_input_jack_report(codec, nid);
f0ce2799 1067 spec->jack_present |= snd_hda_jack_detect(codec, nid);
bb35febd
TI
1068 }
1069
1070 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1071 /* Toggle internal speakers muting */
a9fd4f3f
TI
1072 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1073 nid = spec->autocfg.speaker_pins[i];
1074 if (!nid)
1075 break;
bb35febd
TI
1076 if (pinctl) {
1077 snd_hda_codec_write(codec, nid, 0,
a9fd4f3f
TI
1078 AC_VERB_SET_PIN_WIDGET_CONTROL,
1079 spec->jack_present ? 0 : PIN_OUT);
bb35febd
TI
1080 } else {
1081 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1082 HDA_AMP_MUTE, mute);
1083 }
a9fd4f3f 1084 }
c9b58006
KY
1085}
1086
bb35febd
TI
1087static void alc_automute_pin(struct hda_codec *codec)
1088{
1089 alc_automute_speaker(codec, 1);
1090}
1091
6c819492
TI
1092static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1093 hda_nid_t nid)
1094{
1095 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1096 int i, nums;
1097
1098 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1099 for (i = 0; i < nums; i++)
1100 if (conn[i] == nid)
1101 return i;
1102 return -1;
1103}
1104
840b64c0
TI
1105/* switch the current ADC according to the jack state */
1106static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1107{
1108 struct alc_spec *spec = codec->spec;
1109 unsigned int present;
1110 hda_nid_t new_adc;
1111
1112 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1113 if (present)
1114 spec->cur_adc_idx = 1;
1115 else
1116 spec->cur_adc_idx = 0;
1117 new_adc = spec->adc_nids[spec->cur_adc_idx];
1118 if (spec->cur_adc && spec->cur_adc != new_adc) {
1119 /* stream is running, let's swap the current ADC */
f0cea797 1120 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1121 spec->cur_adc = new_adc;
1122 snd_hda_codec_setup_stream(codec, new_adc,
1123 spec->cur_adc_stream_tag, 0,
1124 spec->cur_adc_format);
1125 }
1126}
1127
7fb0d78f
KY
1128static void alc_mic_automute(struct hda_codec *codec)
1129{
1130 struct alc_spec *spec = codec->spec;
6c819492
TI
1131 struct alc_mic_route *dead, *alive;
1132 unsigned int present, type;
1133 hda_nid_t cap_nid;
1134
b59bdf3b
TI
1135 if (!spec->auto_mic)
1136 return;
6c819492
TI
1137 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1138 return;
1139 if (snd_BUG_ON(!spec->adc_nids))
1140 return;
1141
840b64c0
TI
1142 if (spec->dual_adc_switch) {
1143 alc_dual_mic_adc_auto_switch(codec);
1144 return;
1145 }
1146
6c819492
TI
1147 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1148
864f92be 1149 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1150 if (present) {
1151 alive = &spec->ext_mic;
1152 dead = &spec->int_mic;
1153 } else {
1154 alive = &spec->int_mic;
1155 dead = &spec->ext_mic;
1156 }
1157
6c819492
TI
1158 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1159 if (type == AC_WID_AUD_MIX) {
1160 /* Matrix-mixer style (e.g. ALC882) */
1161 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1162 alive->mux_idx,
1163 HDA_AMP_MUTE, 0);
1164 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1165 dead->mux_idx,
1166 HDA_AMP_MUTE, HDA_AMP_MUTE);
1167 } else {
1168 /* MUX style (e.g. ALC880) */
1169 snd_hda_codec_write_cache(codec, cap_nid, 0,
1170 AC_VERB_SET_CONNECT_SEL,
1171 alive->mux_idx);
1172 }
cd372fb3 1173 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1174
1175 /* FIXME: analog mixer */
7fb0d78f
KY
1176}
1177
c9b58006
KY
1178/* unsolicited event for HP jack sensing */
1179static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1180{
1181 if (codec->vendor_id == 0x10ec0880)
1182 res >>= 28;
1183 else
1184 res >>= 26;
a9fd4f3f
TI
1185 switch (res) {
1186 case ALC880_HP_EVENT:
1187 alc_automute_pin(codec);
1188 break;
1189 case ALC880_MIC_EVENT:
7fb0d78f 1190 alc_mic_automute(codec);
a9fd4f3f
TI
1191 break;
1192 }
7fb0d78f
KY
1193}
1194
1195static void alc_inithook(struct hda_codec *codec)
1196{
a9fd4f3f 1197 alc_automute_pin(codec);
7fb0d78f 1198 alc_mic_automute(codec);
c9b58006
KY
1199}
1200
f9423e7a
KY
1201/* additional initialization for ALC888 variants */
1202static void alc888_coef_init(struct hda_codec *codec)
1203{
1204 unsigned int tmp;
1205
1206 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1207 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1208 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1209 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1210 /* alc888S-VC */
1211 snd_hda_codec_read(codec, 0x20, 0,
1212 AC_VERB_SET_PROC_COEF, 0x830);
1213 else
1214 /* alc888-VB */
1215 snd_hda_codec_read(codec, 0x20, 0,
1216 AC_VERB_SET_PROC_COEF, 0x3030);
1217}
1218
87a8c370
JK
1219static void alc889_coef_init(struct hda_codec *codec)
1220{
1221 unsigned int tmp;
1222
1223 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1224 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1225 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1226 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1227}
1228
3fb4a508
TI
1229/* turn on/off EAPD control (only if available) */
1230static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1231{
1232 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1233 return;
1234 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1235 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1236 on ? 2 : 0);
1237}
1238
4a79ba34 1239static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1240{
4a79ba34 1241 unsigned int tmp;
bc9f98a9 1242
4a79ba34
TI
1243 switch (type) {
1244 case ALC_INIT_GPIO1:
bc9f98a9
KY
1245 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1246 break;
4a79ba34 1247 case ALC_INIT_GPIO2:
bc9f98a9
KY
1248 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1249 break;
4a79ba34 1250 case ALC_INIT_GPIO3:
bdd148a3
KY
1251 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1252 break;
4a79ba34 1253 case ALC_INIT_DEFAULT:
bdd148a3 1254 switch (codec->vendor_id) {
c9b58006 1255 case 0x10ec0260:
3fb4a508
TI
1256 set_eapd(codec, 0x0f, 1);
1257 set_eapd(codec, 0x10, 1);
c9b58006
KY
1258 break;
1259 case 0x10ec0262:
bdd148a3
KY
1260 case 0x10ec0267:
1261 case 0x10ec0268:
c9b58006 1262 case 0x10ec0269:
3fb4a508 1263 case 0x10ec0270:
c6e8f2da 1264 case 0x10ec0272:
f9423e7a
KY
1265 case 0x10ec0660:
1266 case 0x10ec0662:
1267 case 0x10ec0663:
c9b58006 1268 case 0x10ec0862:
20a3a05d 1269 case 0x10ec0889:
3fb4a508
TI
1270 set_eapd(codec, 0x14, 1);
1271 set_eapd(codec, 0x15, 1);
c9b58006 1272 break;
bdd148a3 1273 }
c9b58006
KY
1274 switch (codec->vendor_id) {
1275 case 0x10ec0260:
1276 snd_hda_codec_write(codec, 0x1a, 0,
1277 AC_VERB_SET_COEF_INDEX, 7);
1278 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1279 AC_VERB_GET_PROC_COEF, 0);
1280 snd_hda_codec_write(codec, 0x1a, 0,
1281 AC_VERB_SET_COEF_INDEX, 7);
1282 snd_hda_codec_write(codec, 0x1a, 0,
1283 AC_VERB_SET_PROC_COEF,
1284 tmp | 0x2010);
1285 break;
1286 case 0x10ec0262:
1287 case 0x10ec0880:
1288 case 0x10ec0882:
1289 case 0x10ec0883:
1290 case 0x10ec0885:
4a5a4c56 1291 case 0x10ec0887:
20a3a05d 1292 case 0x10ec0889:
87a8c370 1293 alc889_coef_init(codec);
c9b58006 1294 break;
f9423e7a 1295 case 0x10ec0888:
4a79ba34 1296 alc888_coef_init(codec);
f9423e7a 1297 break;
0aea778e 1298#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1299 case 0x10ec0267:
1300 case 0x10ec0268:
1301 snd_hda_codec_write(codec, 0x20, 0,
1302 AC_VERB_SET_COEF_INDEX, 7);
1303 tmp = snd_hda_codec_read(codec, 0x20, 0,
1304 AC_VERB_GET_PROC_COEF, 0);
1305 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1306 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1307 snd_hda_codec_write(codec, 0x20, 0,
1308 AC_VERB_SET_PROC_COEF,
1309 tmp | 0x3000);
1310 break;
0aea778e 1311#endif /* XXX */
bc9f98a9 1312 }
4a79ba34
TI
1313 break;
1314 }
1315}
1316
1317static void alc_init_auto_hp(struct hda_codec *codec)
1318{
1319 struct alc_spec *spec = codec->spec;
bb35febd
TI
1320 struct auto_pin_cfg *cfg = &spec->autocfg;
1321 int i;
4a79ba34 1322
bb35febd
TI
1323 if (!cfg->hp_pins[0]) {
1324 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1325 return;
1326 }
4a79ba34 1327
bb35febd
TI
1328 if (!cfg->speaker_pins[0]) {
1329 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4a79ba34 1330 return;
bb35febd
TI
1331 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1332 sizeof(cfg->speaker_pins));
1333 cfg->speaker_outs = cfg->line_outs;
1334 }
1335
1336 if (!cfg->hp_pins[0]) {
1337 memcpy(cfg->hp_pins, cfg->line_out_pins,
1338 sizeof(cfg->hp_pins));
1339 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1340 }
1341
bb35febd
TI
1342 for (i = 0; i < cfg->hp_outs; i++) {
1343 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1344 cfg->hp_pins[i]);
1345 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
4a79ba34
TI
1346 AC_VERB_SET_UNSOLICITED_ENABLE,
1347 AC_USRSP_EN | ALC880_HP_EVENT);
bb35febd 1348 }
4a79ba34
TI
1349 spec->unsol_event = alc_sku_unsol_event;
1350}
1351
6c819492
TI
1352static void alc_init_auto_mic(struct hda_codec *codec)
1353{
1354 struct alc_spec *spec = codec->spec;
1355 struct auto_pin_cfg *cfg = &spec->autocfg;
1356 hda_nid_t fixed, ext;
1357 int i;
1358
1359 /* there must be only two mic inputs exclusively */
66ceeb6b 1360 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1361 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1362 return;
1363
1364 fixed = ext = 0;
66ceeb6b
TI
1365 for (i = 0; i < cfg->num_inputs; i++) {
1366 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1367 unsigned int defcfg;
6c819492 1368 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1369 switch (snd_hda_get_input_pin_attr(defcfg)) {
1370 case INPUT_PIN_ATTR_INT:
6c819492
TI
1371 if (fixed)
1372 return; /* already occupied */
1373 fixed = nid;
1374 break;
99ae28be
TI
1375 case INPUT_PIN_ATTR_UNUSED:
1376 return; /* invalid entry */
1377 default:
6c819492
TI
1378 if (ext)
1379 return; /* already occupied */
1380 ext = nid;
1381 break;
6c819492
TI
1382 }
1383 }
eaa9b3a7
TI
1384 if (!ext || !fixed)
1385 return;
6c819492
TI
1386 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1387 return; /* no unsol support */
1388 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1389 ext, fixed);
1390 spec->ext_mic.pin = ext;
1391 spec->int_mic.pin = fixed;
1392 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1393 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1394 spec->auto_mic = 1;
1395 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1396 AC_VERB_SET_UNSOLICITED_ENABLE,
1397 AC_USRSP_EN | ALC880_MIC_EVENT);
1398 spec->unsol_event = alc_sku_unsol_event;
1399}
1400
90622917
DH
1401/* Could be any non-zero and even value. When used as fixup, tells
1402 * the driver to ignore any present sku defines.
1403 */
1404#define ALC_FIXUP_SKU_IGNORE (2)
1405
da00c244
KY
1406static int alc_auto_parse_customize_define(struct hda_codec *codec)
1407{
1408 unsigned int ass, tmp, i;
7fb56223 1409 unsigned nid = 0;
da00c244
KY
1410 struct alc_spec *spec = codec->spec;
1411
b6cbe517
TI
1412 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1413
90622917
DH
1414 if (spec->cdefine.fixup) {
1415 ass = spec->cdefine.sku_cfg;
1416 if (ass == ALC_FIXUP_SKU_IGNORE)
1417 return -1;
1418 goto do_sku;
1419 }
1420
da00c244 1421 ass = codec->subsystem_id & 0xffff;
b6cbe517 1422 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1423 goto do_sku;
1424
1425 nid = 0x1d;
1426 if (codec->vendor_id == 0x10ec0260)
1427 nid = 0x17;
1428 ass = snd_hda_codec_get_pincfg(codec, nid);
1429
1430 if (!(ass & 1)) {
1431 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1432 codec->chip_name, ass);
1433 return -1;
1434 }
1435
1436 /* check sum */
1437 tmp = 0;
1438 for (i = 1; i < 16; i++) {
1439 if ((ass >> i) & 1)
1440 tmp++;
1441 }
1442 if (((ass >> 16) & 0xf) != tmp)
1443 return -1;
1444
1445 spec->cdefine.port_connectivity = ass >> 30;
1446 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1447 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1448 spec->cdefine.customization = ass >> 8;
1449do_sku:
1450 spec->cdefine.sku_cfg = ass;
1451 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1452 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1453 spec->cdefine.swap = (ass & 0x2) >> 1;
1454 spec->cdefine.override = ass & 0x1;
1455
1456 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1457 nid, spec->cdefine.sku_cfg);
1458 snd_printd("SKU: port_connectivity=0x%x\n",
1459 spec->cdefine.port_connectivity);
1460 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1461 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1462 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1463 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1464 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1465 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1466 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1467
1468 return 0;
1469}
1470
4a79ba34
TI
1471/* check subsystem ID and set up device-specific initialization;
1472 * return 1 if initialized, 0 if invalid SSID
1473 */
1474/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1475 * 31 ~ 16 : Manufacture ID
1476 * 15 ~ 8 : SKU ID
1477 * 7 ~ 0 : Assembly ID
1478 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1479 */
1480static int alc_subsystem_id(struct hda_codec *codec,
1481 hda_nid_t porta, hda_nid_t porte,
6227cdce 1482 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1483{
1484 unsigned int ass, tmp, i;
1485 unsigned nid;
1486 struct alc_spec *spec = codec->spec;
1487
90622917
DH
1488 if (spec->cdefine.fixup) {
1489 ass = spec->cdefine.sku_cfg;
1490 if (ass == ALC_FIXUP_SKU_IGNORE)
1491 return 0;
1492 goto do_sku;
1493 }
1494
4a79ba34
TI
1495 ass = codec->subsystem_id & 0xffff;
1496 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1497 goto do_sku;
1498
1499 /* invalid SSID, check the special NID pin defcfg instead */
1500 /*
def319f9 1501 * 31~30 : port connectivity
4a79ba34
TI
1502 * 29~21 : reserve
1503 * 20 : PCBEEP input
1504 * 19~16 : Check sum (15:1)
1505 * 15~1 : Custom
1506 * 0 : override
1507 */
1508 nid = 0x1d;
1509 if (codec->vendor_id == 0x10ec0260)
1510 nid = 0x17;
1511 ass = snd_hda_codec_get_pincfg(codec, nid);
1512 snd_printd("realtek: No valid SSID, "
1513 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1514 ass, nid);
6227cdce 1515 if (!(ass & 1))
4a79ba34
TI
1516 return 0;
1517 if ((ass >> 30) != 1) /* no physical connection */
1518 return 0;
1519
1520 /* check sum */
1521 tmp = 0;
1522 for (i = 1; i < 16; i++) {
1523 if ((ass >> i) & 1)
1524 tmp++;
1525 }
1526 if (((ass >> 16) & 0xf) != tmp)
1527 return 0;
1528do_sku:
1529 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1530 ass & 0xffff, codec->vendor_id);
1531 /*
1532 * 0 : override
1533 * 1 : Swap Jack
1534 * 2 : 0 --> Desktop, 1 --> Laptop
1535 * 3~5 : External Amplifier control
1536 * 7~6 : Reserved
1537 */
1538 tmp = (ass & 0x38) >> 3; /* external Amp control */
1539 switch (tmp) {
1540 case 1:
1541 spec->init_amp = ALC_INIT_GPIO1;
1542 break;
1543 case 3:
1544 spec->init_amp = ALC_INIT_GPIO2;
1545 break;
1546 case 7:
1547 spec->init_amp = ALC_INIT_GPIO3;
1548 break;
1549 case 5:
5a8cfb4e 1550 default:
4a79ba34 1551 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1552 break;
1553 }
ea1fb29a 1554
8c427226 1555 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1556 * when the external headphone out jack is plugged"
1557 */
8c427226 1558 if (!(ass & 0x8000))
4a79ba34 1559 return 1;
c9b58006
KY
1560 /*
1561 * 10~8 : Jack location
1562 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1563 * 14~13: Resvered
1564 * 15 : 1 --> enable the function "Mute internal speaker
1565 * when the external headphone out jack is plugged"
1566 */
c9b58006 1567 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1568 hda_nid_t nid;
c9b58006
KY
1569 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1570 if (tmp == 0)
01d4825d 1571 nid = porta;
c9b58006 1572 else if (tmp == 1)
01d4825d 1573 nid = porte;
c9b58006 1574 else if (tmp == 2)
01d4825d 1575 nid = portd;
6227cdce
KY
1576 else if (tmp == 3)
1577 nid = porti;
c9b58006 1578 else
4a79ba34 1579 return 1;
01d4825d
TI
1580 for (i = 0; i < spec->autocfg.line_outs; i++)
1581 if (spec->autocfg.line_out_pins[i] == nid)
1582 return 1;
1583 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1584 }
1585
4a79ba34 1586 alc_init_auto_hp(codec);
6c819492 1587 alc_init_auto_mic(codec);
4a79ba34
TI
1588 return 1;
1589}
ea1fb29a 1590
4a79ba34 1591static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1592 hda_nid_t porta, hda_nid_t porte,
1593 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1594{
6227cdce 1595 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1596 struct alc_spec *spec = codec->spec;
1597 snd_printd("realtek: "
1598 "Enable default setup for auto mode as fallback\n");
1599 spec->init_amp = ALC_INIT_DEFAULT;
1600 alc_init_auto_hp(codec);
6c819492 1601 alc_init_auto_mic(codec);
4a79ba34 1602 }
bc9f98a9
KY
1603}
1604
f95474ec 1605/*
f8f25ba3 1606 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1607 */
1608
1609struct alc_pincfg {
1610 hda_nid_t nid;
1611 u32 val;
1612};
1613
e1eb5f10
TB
1614struct alc_model_fixup {
1615 const int id;
1616 const char *name;
1617};
1618
f8f25ba3 1619struct alc_fixup {
b5bfbc67 1620 int type;
361fe6e9
TI
1621 bool chained;
1622 int chain_id;
b5bfbc67
TI
1623 union {
1624 unsigned int sku;
1625 const struct alc_pincfg *pins;
1626 const struct hda_verb *verbs;
1627 void (*func)(struct hda_codec *codec,
1628 const struct alc_fixup *fix,
1629 int action);
1630 } v;
f8f25ba3
TI
1631};
1632
b5bfbc67
TI
1633enum {
1634 ALC_FIXUP_INVALID,
1635 ALC_FIXUP_SKU,
1636 ALC_FIXUP_PINS,
1637 ALC_FIXUP_VERBS,
1638 ALC_FIXUP_FUNC,
1639};
1640
1641enum {
1642 ALC_FIXUP_ACT_PRE_PROBE,
1643 ALC_FIXUP_ACT_PROBE,
58701120 1644 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1645};
1646
1647static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1648{
b5bfbc67
TI
1649 struct alc_spec *spec = codec->spec;
1650 int id = spec->fixup_id;
aa1d0c52 1651#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1652 const char *modelname = spec->fixup_name;
aa1d0c52 1653#endif
b5bfbc67 1654 int depth = 0;
f95474ec 1655
b5bfbc67
TI
1656 if (!spec->fixup_list)
1657 return;
1658
1659 while (id >= 0) {
1660 const struct alc_fixup *fix = spec->fixup_list + id;
1661 const struct alc_pincfg *cfg;
1662
1663 switch (fix->type) {
1664 case ALC_FIXUP_SKU:
1665 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1666 break;;
1667 snd_printdd(KERN_INFO "hda_codec: %s: "
1668 "Apply sku override for %s\n",
1669 codec->chip_name, modelname);
1670 spec->cdefine.sku_cfg = fix->v.sku;
1671 spec->cdefine.fixup = 1;
1672 break;
1673 case ALC_FIXUP_PINS:
1674 cfg = fix->v.pins;
1675 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1676 break;
1677 snd_printdd(KERN_INFO "hda_codec: %s: "
1678 "Apply pincfg for %s\n",
1679 codec->chip_name, modelname);
1680 for (; cfg->nid; cfg++)
1681 snd_hda_codec_set_pincfg(codec, cfg->nid,
1682 cfg->val);
1683 break;
1684 case ALC_FIXUP_VERBS:
1685 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1686 break;
1687 snd_printdd(KERN_INFO "hda_codec: %s: "
1688 "Apply fix-verbs for %s\n",
1689 codec->chip_name, modelname);
1690 add_verb(codec->spec, fix->v.verbs);
1691 break;
1692 case ALC_FIXUP_FUNC:
1693 if (!fix->v.func)
1694 break;
1695 snd_printdd(KERN_INFO "hda_codec: %s: "
1696 "Apply fix-func for %s\n",
1697 codec->chip_name, modelname);
1698 fix->v.func(codec, fix, action);
1699 break;
1700 default:
1701 snd_printk(KERN_ERR "hda_codec: %s: "
1702 "Invalid fixup type %d\n",
1703 codec->chip_name, fix->type);
1704 break;
1705 }
1706 if (!fix[id].chained)
1707 break;
1708 if (++depth > 10)
1709 break;
1710 id = fix[id].chain_id;
9d57883f 1711 }
f95474ec
TI
1712}
1713
e1eb5f10 1714static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1715 const struct alc_model_fixup *models,
1716 const struct snd_pci_quirk *quirk,
1717 const struct alc_fixup *fixlist)
e1eb5f10 1718{
b5bfbc67
TI
1719 struct alc_spec *spec = codec->spec;
1720 int id = -1;
1721 const char *name = NULL;
e1eb5f10 1722
e1eb5f10
TB
1723 if (codec->modelname && models) {
1724 while (models->name) {
1725 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
1726 id = models->id;
1727 name = models->name;
e1eb5f10
TB
1728 break;
1729 }
1730 models++;
1731 }
b5bfbc67
TI
1732 }
1733 if (id < 0) {
1734 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1735 if (quirk) {
1736 id = quirk->value;
1737#ifdef CONFIG_SND_DEBUG_VERBOSE
1738 name = quirk->name;
1739#endif
1740 }
1741 }
1742
1743 spec->fixup_id = id;
1744 if (id >= 0) {
1745 spec->fixup_list = fixlist;
1746 spec->fixup_name = name;
e1eb5f10 1747 }
f95474ec
TI
1748}
1749
274693f3
KY
1750static int alc_read_coef_idx(struct hda_codec *codec,
1751 unsigned int coef_idx)
1752{
1753 unsigned int val;
1754 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1755 coef_idx);
1756 val = snd_hda_codec_read(codec, 0x20, 0,
1757 AC_VERB_GET_PROC_COEF, 0);
1758 return val;
1759}
1760
977ddd6b
KY
1761static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1762 unsigned int coef_val)
1763{
1764 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1765 coef_idx);
1766 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1767 coef_val);
1768}
1769
757899ac
TI
1770/* set right pin controls for digital I/O */
1771static void alc_auto_init_digital(struct hda_codec *codec)
1772{
1773 struct alc_spec *spec = codec->spec;
1774 int i;
1775 hda_nid_t pin;
1776
1777 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1778 pin = spec->autocfg.dig_out_pins[i];
1779 if (pin) {
1780 snd_hda_codec_write(codec, pin, 0,
1781 AC_VERB_SET_PIN_WIDGET_CONTROL,
1782 PIN_OUT);
1783 }
1784 }
1785 pin = spec->autocfg.dig_in_pin;
1786 if (pin)
1787 snd_hda_codec_write(codec, pin, 0,
1788 AC_VERB_SET_PIN_WIDGET_CONTROL,
1789 PIN_IN);
1790}
1791
1792/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1793static void alc_auto_parse_digital(struct hda_codec *codec)
1794{
1795 struct alc_spec *spec = codec->spec;
1796 int i, err;
1797 hda_nid_t dig_nid;
1798
1799 /* support multiple SPDIFs; the secondary is set up as a slave */
1800 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1801 err = snd_hda_get_connections(codec,
1802 spec->autocfg.dig_out_pins[i],
1803 &dig_nid, 1);
1804 if (err < 0)
1805 continue;
1806 if (!i) {
1807 spec->multiout.dig_out_nid = dig_nid;
1808 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1809 } else {
1810 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1811 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1812 break;
1813 spec->slave_dig_outs[i - 1] = dig_nid;
1814 }
1815 }
1816
1817 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
1818 dig_nid = codec->start_nid;
1819 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1820 unsigned int wcaps = get_wcaps(codec, dig_nid);
1821 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1822 continue;
1823 if (!(wcaps & AC_WCAP_DIGITAL))
1824 continue;
1825 if (!(wcaps & AC_WCAP_CONN_LIST))
1826 continue;
1827 err = get_connection_index(codec, dig_nid,
1828 spec->autocfg.dig_in_pin);
1829 if (err >= 0) {
1830 spec->dig_in_nid = dig_nid;
1831 break;
1832 }
1833 }
757899ac
TI
1834 }
1835}
1836
ef8ef5fb
VP
1837/*
1838 * ALC888
1839 */
1840
1841/*
1842 * 2ch mode
1843 */
1844static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1845/* Mic-in jack as mic in */
1846 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1847 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1848/* Line-in jack as Line in */
1849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1850 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1851/* Line-Out as Front */
1852 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1853 { } /* end */
1854};
1855
1856/*
1857 * 4ch mode
1858 */
1859static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1860/* Mic-in jack as mic in */
1861 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1862 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1863/* Line-in jack as Surround */
1864 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1865 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1866/* Line-Out as Front */
1867 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1868 { } /* end */
1869};
1870
1871/*
1872 * 6ch mode
1873 */
1874static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1875/* Mic-in jack as CLFE */
1876 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1877 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1878/* Line-in jack as Surround */
1879 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1880 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1881/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1882 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1883 { } /* end */
1884};
1885
1886/*
1887 * 8ch mode
1888 */
1889static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1890/* Mic-in jack as CLFE */
1891 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1892 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1893/* Line-in jack as Surround */
1894 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1895 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1896/* Line-Out as Side */
1897 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1898 { } /* end */
1899};
1900
1901static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1902 { 2, alc888_4ST_ch2_intel_init },
1903 { 4, alc888_4ST_ch4_intel_init },
1904 { 6, alc888_4ST_ch6_intel_init },
1905 { 8, alc888_4ST_ch8_intel_init },
1906};
1907
1908/*
1909 * ALC888 Fujitsu Siemens Amillo xa3530
1910 */
1911
1912static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1913/* Front Mic: set to PIN_IN (empty by default) */
1914 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1915/* Connect Internal HP to Front */
1916 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1917 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1918 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1919/* Connect Bass HP to Front */
1920 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1921 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1922 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1923/* Connect Line-Out side jack (SPDIF) to Side */
1924 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1925 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1926 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1927/* Connect Mic jack to CLFE */
1928 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1929 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1930 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1931/* Connect Line-in jack to Surround */
1932 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1933 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1934 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1935/* Connect HP out jack to Front */
1936 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1937 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1938 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1939/* Enable unsolicited event for HP jack and Line-out jack */
1940 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1941 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1942 {}
1943};
1944
a9fd4f3f 1945static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1946{
bb35febd 1947 alc_automute_speaker(codec, 0);
ef8ef5fb
VP
1948}
1949
a9fd4f3f
TI
1950static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1951 unsigned int res)
ef8ef5fb 1952{
a9fd4f3f
TI
1953 if (codec->vendor_id == 0x10ec0880)
1954 res >>= 28;
1955 else
1956 res >>= 26;
1957 if (res == ALC880_HP_EVENT)
1958 alc_automute_amp(codec);
ef8ef5fb
VP
1959}
1960
4f5d1706 1961static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1962{
1963 struct alc_spec *spec = codec->spec;
1964
1965 spec->autocfg.hp_pins[0] = 0x15;
1966 spec->autocfg.speaker_pins[0] = 0x14;
1967 spec->autocfg.speaker_pins[1] = 0x16;
1968 spec->autocfg.speaker_pins[2] = 0x17;
1969 spec->autocfg.speaker_pins[3] = 0x19;
1970 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1971}
1972
1973static void alc889_intel_init_hook(struct hda_codec *codec)
1974{
1975 alc889_coef_init(codec);
4f5d1706 1976 alc_automute_amp(codec);
6732bd0d
WF
1977}
1978
4f5d1706 1979static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1980{
1981 struct alc_spec *spec = codec->spec;
1982
1983 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1984 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1985 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1986 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1987}
ef8ef5fb 1988
5b2d1eca
VP
1989/*
1990 * ALC888 Acer Aspire 4930G model
1991 */
1992
1993static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1994/* Front Mic: set to PIN_IN (empty by default) */
1995 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1996/* Unselect Front Mic by default in input mixer 3 */
1997 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1998/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1999 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2000/* Connect Internal HP to front */
2001 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2002 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2003 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2004/* Connect HP out to front */
2005 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2007 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2008 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2009 { }
2010};
2011
d2fd4b09
TV
2012/*
2013 * ALC888 Acer Aspire 6530G model
2014 */
2015
2016static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2017/* Route to built-in subwoofer as well as speakers */
2018 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2019 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2021 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2022/* Bias voltage on for external mic port */
2023 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2024/* Front Mic: set to PIN_IN (empty by default) */
2025 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2026/* Unselect Front Mic by default in input mixer 3 */
2027 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2028/* Enable unsolicited event for HP jack */
2029 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2030/* Enable speaker output */
2031 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2032 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2033 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2034/* Enable headphone output */
2035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2036 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2037 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2038 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2039 { }
2040};
2041
d9477207
DK
2042/*
2043 *ALC888 Acer Aspire 7730G model
2044 */
2045
2046static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2047/* Bias voltage on for external mic port */
2048 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2049/* Front Mic: set to PIN_IN (empty by default) */
2050 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2051/* Unselect Front Mic by default in input mixer 3 */
2052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2053/* Enable unsolicited event for HP jack */
2054 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2055/* Enable speaker output */
2056 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2057 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2058 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2059/* Enable headphone output */
2060 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2061 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2062 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2063 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2064/*Enable internal subwoofer */
2065 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2066 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2067 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2068 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2069 { }
2070};
2071
3b315d70 2072/*
018df418 2073 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2074 */
2075
018df418 2076static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2077/* Front Mic: set to PIN_IN (empty by default) */
2078 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2079/* Unselect Front Mic by default in input mixer 3 */
2080 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2081/* Enable unsolicited event for HP jack */
2082 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2083/* Connect Internal Front to Front */
2084 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2085 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2086 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2087/* Connect Internal Rear to Rear */
2088 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2089 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2090 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2091/* Connect Internal CLFE to CLFE */
2092 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2093 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2094 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2095/* Connect HP out to Front */
018df418 2096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2097 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2098 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2099/* Enable all DACs */
2100/* DAC DISABLE/MUTE 1? */
2101/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2102 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2103 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2104/* DAC DISABLE/MUTE 2? */
2105/* some bit here disables the other DACs. Init=0x4900 */
2106 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2107 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2108/* DMIC fix
2109 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2110 * which makes the stereo useless. However, either the mic or the ALC889
2111 * makes the signal become a difference/sum signal instead of standard
2112 * stereo, which is annoying. So instead we flip this bit which makes the
2113 * codec replicate the sum signal to both channels, turning it into a
2114 * normal mono mic.
2115 */
2116/* DMIC_CONTROL? Init value = 0x0001 */
2117 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2118 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2119 { }
2120};
2121
ef8ef5fb 2122static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2123 /* Front mic only available on one ADC */
2124 {
2125 .num_items = 4,
2126 .items = {
2127 { "Mic", 0x0 },
2128 { "Line", 0x2 },
2129 { "CD", 0x4 },
2130 { "Front Mic", 0xb },
2131 },
2132 },
2133 {
2134 .num_items = 3,
2135 .items = {
2136 { "Mic", 0x0 },
2137 { "Line", 0x2 },
2138 { "CD", 0x4 },
2139 },
2140 }
2141};
2142
d2fd4b09
TV
2143static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2144 /* Interal mic only available on one ADC */
2145 {
684a8842 2146 .num_items = 5,
d2fd4b09 2147 .items = {
8607f7c4 2148 { "Mic", 0x0 },
684a8842 2149 { "Line In", 0x2 },
d2fd4b09 2150 { "CD", 0x4 },
684a8842 2151 { "Input Mix", 0xa },
28c4edb7 2152 { "Internal Mic", 0xb },
d2fd4b09
TV
2153 },
2154 },
2155 {
684a8842 2156 .num_items = 4,
d2fd4b09 2157 .items = {
8607f7c4 2158 { "Mic", 0x0 },
684a8842 2159 { "Line In", 0x2 },
d2fd4b09 2160 { "CD", 0x4 },
684a8842 2161 { "Input Mix", 0xa },
d2fd4b09
TV
2162 },
2163 }
2164};
2165
018df418
HM
2166static struct hda_input_mux alc889_capture_sources[3] = {
2167 /* Digital mic only available on first "ADC" */
2168 {
2169 .num_items = 5,
2170 .items = {
2171 { "Mic", 0x0 },
2172 { "Line", 0x2 },
2173 { "CD", 0x4 },
2174 { "Front Mic", 0xb },
2175 { "Input Mix", 0xa },
2176 },
2177 },
2178 {
2179 .num_items = 4,
2180 .items = {
2181 { "Mic", 0x0 },
2182 { "Line", 0x2 },
2183 { "CD", 0x4 },
2184 { "Input Mix", 0xa },
2185 },
2186 },
2187 {
2188 .num_items = 4,
2189 .items = {
2190 { "Mic", 0x0 },
2191 { "Line", 0x2 },
2192 { "CD", 0x4 },
2193 { "Input Mix", 0xa },
2194 },
2195 }
2196};
2197
ef8ef5fb 2198static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2199 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2200 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2201 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2202 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2203 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2204 HDA_OUTPUT),
2205 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2206 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2207 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2208 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2209 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2210 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2211 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2212 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2213 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2214 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2215 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2216 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2217 { } /* end */
2218};
2219
460c92fa
ŁW
2220static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2221 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2222 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2223 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2224 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2225 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2226 HDA_OUTPUT),
786c51f9
ŁW
2227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2228 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2229 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2230 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2231 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2232 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2233 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2234 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2235 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2236 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2237 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2238 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2239 { } /* end */
2240};
2241
556eea9a
HM
2242static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2243 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2245 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2246 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2247 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2248 HDA_OUTPUT),
2249 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2250 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2251 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2252 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2253 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2254 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2255 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2256 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2257 { } /* end */
2258};
2259
2260
4f5d1706 2261static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2262{
a9fd4f3f 2263 struct alc_spec *spec = codec->spec;
5b2d1eca 2264
a9fd4f3f
TI
2265 spec->autocfg.hp_pins[0] = 0x15;
2266 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2267 spec->autocfg.speaker_pins[1] = 0x16;
2268 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2269}
2270
4f5d1706 2271static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2272{
2273 struct alc_spec *spec = codec->spec;
2274
2275 spec->autocfg.hp_pins[0] = 0x15;
2276 spec->autocfg.speaker_pins[0] = 0x14;
2277 spec->autocfg.speaker_pins[1] = 0x16;
2278 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2279}
2280
d9477207
DK
2281static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2282{
2283 struct alc_spec *spec = codec->spec;
2284
2285 spec->autocfg.hp_pins[0] = 0x15;
2286 spec->autocfg.speaker_pins[0] = 0x14;
2287 spec->autocfg.speaker_pins[1] = 0x16;
2288 spec->autocfg.speaker_pins[2] = 0x17;
2289}
2290
4f5d1706 2291static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2292{
2293 struct alc_spec *spec = codec->spec;
2294
2295 spec->autocfg.hp_pins[0] = 0x15;
2296 spec->autocfg.speaker_pins[0] = 0x14;
2297 spec->autocfg.speaker_pins[1] = 0x16;
2298 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2299}
2300
1da177e4 2301/*
e9edcee0
TI
2302 * ALC880 3-stack model
2303 *
2304 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2305 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2306 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2307 */
2308
e9edcee0
TI
2309static hda_nid_t alc880_dac_nids[4] = {
2310 /* front, rear, clfe, rear_surr */
2311 0x02, 0x05, 0x04, 0x03
2312};
2313
2314static hda_nid_t alc880_adc_nids[3] = {
2315 /* ADC0-2 */
2316 0x07, 0x08, 0x09,
2317};
2318
2319/* The datasheet says the node 0x07 is connected from inputs,
2320 * but it shows zero connection in the real implementation on some devices.
df694daa 2321 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2322 */
e9edcee0
TI
2323static hda_nid_t alc880_adc_nids_alt[2] = {
2324 /* ADC1-2 */
2325 0x08, 0x09,
2326};
2327
2328#define ALC880_DIGOUT_NID 0x06
2329#define ALC880_DIGIN_NID 0x0a
2330
2331static struct hda_input_mux alc880_capture_source = {
2332 .num_items = 4,
2333 .items = {
2334 { "Mic", 0x0 },
2335 { "Front Mic", 0x3 },
2336 { "Line", 0x2 },
2337 { "CD", 0x4 },
2338 },
2339};
2340
2341/* channel source setting (2/6 channel selection for 3-stack) */
2342/* 2ch mode */
2343static struct hda_verb alc880_threestack_ch2_init[] = {
2344 /* set line-in to input, mute it */
2345 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2346 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2347 /* set mic-in to input vref 80%, mute it */
2348 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2349 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2350 { } /* end */
2351};
2352
2353/* 6ch mode */
2354static struct hda_verb alc880_threestack_ch6_init[] = {
2355 /* set line-in to output, unmute it */
2356 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2357 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2358 /* set mic-in to output, unmute it */
2359 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2360 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2361 { } /* end */
2362};
2363
d2a6d7dc 2364static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2365 { 2, alc880_threestack_ch2_init },
2366 { 6, alc880_threestack_ch6_init },
2367};
2368
c8b6bf9b 2369static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2370 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2371 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2372 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2373 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2374 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2375 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2376 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2377 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2378 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2379 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2383 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2384 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2385 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2386 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2387 {
2388 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2389 .name = "Channel Mode",
df694daa
KY
2390 .info = alc_ch_mode_info,
2391 .get = alc_ch_mode_get,
2392 .put = alc_ch_mode_put,
e9edcee0
TI
2393 },
2394 { } /* end */
2395};
2396
2397/* capture mixer elements */
f9e336f6
TI
2398static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2399 struct snd_ctl_elem_info *uinfo)
2400{
2401 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2402 struct alc_spec *spec = codec->spec;
2403 int err;
1da177e4 2404
5a9e02e9 2405 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2406 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2407 HDA_INPUT);
2408 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2409 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2410 return err;
2411}
2412
2413static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2414 unsigned int size, unsigned int __user *tlv)
2415{
2416 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2417 struct alc_spec *spec = codec->spec;
2418 int err;
1da177e4 2419
5a9e02e9 2420 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2421 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2422 HDA_INPUT);
2423 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2424 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2425 return err;
2426}
2427
2428typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2429 struct snd_ctl_elem_value *ucontrol);
2430
2431static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2432 struct snd_ctl_elem_value *ucontrol,
2433 getput_call_t func)
2434{
2435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2436 struct alc_spec *spec = codec->spec;
2437 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2438 int err;
2439
5a9e02e9 2440 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2441 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2442 3, 0, HDA_INPUT);
2443 err = func(kcontrol, ucontrol);
5a9e02e9 2444 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2445 return err;
2446}
2447
2448static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2449 struct snd_ctl_elem_value *ucontrol)
2450{
2451 return alc_cap_getput_caller(kcontrol, ucontrol,
2452 snd_hda_mixer_amp_volume_get);
2453}
2454
2455static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2456 struct snd_ctl_elem_value *ucontrol)
2457{
2458 return alc_cap_getput_caller(kcontrol, ucontrol,
2459 snd_hda_mixer_amp_volume_put);
2460}
2461
2462/* capture mixer elements */
2463#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2464
2465static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2466 struct snd_ctl_elem_value *ucontrol)
2467{
2468 return alc_cap_getput_caller(kcontrol, ucontrol,
2469 snd_hda_mixer_amp_switch_get);
2470}
2471
2472static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2473 struct snd_ctl_elem_value *ucontrol)
2474{
2475 return alc_cap_getput_caller(kcontrol, ucontrol,
2476 snd_hda_mixer_amp_switch_put);
2477}
2478
a23b688f 2479#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2480 { \
2481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2482 .name = "Capture Switch", \
2483 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2484 .count = num, \
2485 .info = alc_cap_sw_info, \
2486 .get = alc_cap_sw_get, \
2487 .put = alc_cap_sw_put, \
2488 }, \
2489 { \
2490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2491 .name = "Capture Volume", \
2492 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2493 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2494 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2495 .count = num, \
2496 .info = alc_cap_vol_info, \
2497 .get = alc_cap_vol_get, \
2498 .put = alc_cap_vol_put, \
2499 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2500 }
2501
2502#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2503 { \
2504 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2505 /* .name = "Capture Source", */ \
2506 .name = "Input Source", \
2507 .count = num, \
2508 .info = alc_mux_enum_info, \
2509 .get = alc_mux_enum_get, \
2510 .put = alc_mux_enum_put, \
a23b688f
TI
2511 }
2512
2513#define DEFINE_CAPMIX(num) \
2514static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2515 _DEFINE_CAPMIX(num), \
2516 _DEFINE_CAPSRC(num), \
2517 { } /* end */ \
2518}
2519
2520#define DEFINE_CAPMIX_NOSRC(num) \
2521static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2522 _DEFINE_CAPMIX(num), \
2523 { } /* end */ \
f9e336f6
TI
2524}
2525
2526/* up to three ADCs */
2527DEFINE_CAPMIX(1);
2528DEFINE_CAPMIX(2);
2529DEFINE_CAPMIX(3);
a23b688f
TI
2530DEFINE_CAPMIX_NOSRC(1);
2531DEFINE_CAPMIX_NOSRC(2);
2532DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2533
2534/*
2535 * ALC880 5-stack model
2536 *
9c7f852e
TI
2537 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2538 * Side = 0x02 (0xd)
e9edcee0
TI
2539 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2540 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2541 */
2542
2543/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2544static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2545 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2546 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2547 { } /* end */
2548};
2549
e9edcee0
TI
2550/* channel source setting (6/8 channel selection for 5-stack) */
2551/* 6ch mode */
2552static struct hda_verb alc880_fivestack_ch6_init[] = {
2553 /* set line-in to input, mute it */
2554 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2555 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2556 { } /* end */
2557};
2558
e9edcee0
TI
2559/* 8ch mode */
2560static struct hda_verb alc880_fivestack_ch8_init[] = {
2561 /* set line-in to output, unmute it */
2562 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2563 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2564 { } /* end */
2565};
2566
d2a6d7dc 2567static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2568 { 6, alc880_fivestack_ch6_init },
2569 { 8, alc880_fivestack_ch8_init },
2570};
2571
2572
2573/*
2574 * ALC880 6-stack model
2575 *
9c7f852e
TI
2576 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2577 * Side = 0x05 (0x0f)
e9edcee0
TI
2578 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2579 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2580 */
2581
2582static hda_nid_t alc880_6st_dac_nids[4] = {
2583 /* front, rear, clfe, rear_surr */
2584 0x02, 0x03, 0x04, 0x05
f12ab1e0 2585};
e9edcee0
TI
2586
2587static struct hda_input_mux alc880_6stack_capture_source = {
2588 .num_items = 4,
2589 .items = {
2590 { "Mic", 0x0 },
2591 { "Front Mic", 0x1 },
2592 { "Line", 0x2 },
2593 { "CD", 0x4 },
2594 },
2595};
2596
2597/* fixed 8-channels */
d2a6d7dc 2598static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2599 { 8, NULL },
2600};
2601
c8b6bf9b 2602static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2603 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2604 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2605 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2606 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2607 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2608 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2609 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2610 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2611 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2612 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2613 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2614 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2615 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2616 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2618 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2619 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2620 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2621 {
2622 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2623 .name = "Channel Mode",
df694daa
KY
2624 .info = alc_ch_mode_info,
2625 .get = alc_ch_mode_get,
2626 .put = alc_ch_mode_put,
16ded525
TI
2627 },
2628 { } /* end */
2629};
2630
e9edcee0
TI
2631
2632/*
2633 * ALC880 W810 model
2634 *
2635 * W810 has rear IO for:
2636 * Front (DAC 02)
2637 * Surround (DAC 03)
2638 * Center/LFE (DAC 04)
2639 * Digital out (06)
2640 *
2641 * The system also has a pair of internal speakers, and a headphone jack.
2642 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2643 *
e9edcee0
TI
2644 * There is a variable resistor to control the speaker or headphone
2645 * volume. This is a hardware-only device without a software API.
2646 *
2647 * Plugging headphones in will disable the internal speakers. This is
2648 * implemented in hardware, not via the driver using jack sense. In
2649 * a similar fashion, plugging into the rear socket marked "front" will
2650 * disable both the speakers and headphones.
2651 *
2652 * For input, there's a microphone jack, and an "audio in" jack.
2653 * These may not do anything useful with this driver yet, because I
2654 * haven't setup any initialization verbs for these yet...
2655 */
2656
2657static hda_nid_t alc880_w810_dac_nids[3] = {
2658 /* front, rear/surround, clfe */
2659 0x02, 0x03, 0x04
16ded525
TI
2660};
2661
e9edcee0 2662/* fixed 6 channels */
d2a6d7dc 2663static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2664 { 6, NULL }
2665};
2666
2667/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2668static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2669 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2670 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2671 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2672 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2673 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2674 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2675 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2676 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2677 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2678 { } /* end */
2679};
2680
2681
2682/*
2683 * Z710V model
2684 *
2685 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2686 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2687 * Line = 0x1a
e9edcee0
TI
2688 */
2689
2690static hda_nid_t alc880_z71v_dac_nids[1] = {
2691 0x02
2692};
2693#define ALC880_Z71V_HP_DAC 0x03
2694
2695/* fixed 2 channels */
d2a6d7dc 2696static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2697 { 2, NULL }
2698};
2699
c8b6bf9b 2700static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2701 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2702 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2703 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2704 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2705 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2706 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2709 { } /* end */
2710};
2711
e9edcee0 2712
e9edcee0
TI
2713/*
2714 * ALC880 F1734 model
2715 *
2716 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2717 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2718 */
2719
2720static hda_nid_t alc880_f1734_dac_nids[1] = {
2721 0x03
2722};
2723#define ALC880_F1734_HP_DAC 0x02
2724
c8b6bf9b 2725static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2726 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2727 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2728 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2729 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2730 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2731 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2733 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2734 { } /* end */
2735};
2736
937b4160
TI
2737static struct hda_input_mux alc880_f1734_capture_source = {
2738 .num_items = 2,
2739 .items = {
2740 { "Mic", 0x1 },
2741 { "CD", 0x4 },
2742 },
2743};
2744
e9edcee0 2745
e9edcee0
TI
2746/*
2747 * ALC880 ASUS model
2748 *
2749 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2750 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2751 * Mic = 0x18, Line = 0x1a
2752 */
2753
2754#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2755#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2756
c8b6bf9b 2757static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2758 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2759 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2760 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2761 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2762 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2763 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2764 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2765 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2766 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2767 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2768 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2769 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2770 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2771 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2772 {
2773 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2774 .name = "Channel Mode",
df694daa
KY
2775 .info = alc_ch_mode_info,
2776 .get = alc_ch_mode_get,
2777 .put = alc_ch_mode_put,
16ded525
TI
2778 },
2779 { } /* end */
2780};
e9edcee0 2781
e9edcee0
TI
2782/*
2783 * ALC880 ASUS W1V model
2784 *
2785 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2786 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2787 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2788 */
2789
2790/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2791static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2792 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2793 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2794 { } /* end */
2795};
2796
df694daa
KY
2797/* TCL S700 */
2798static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2799 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2800 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2801 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2802 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2803 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2804 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2805 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2806 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2807 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2808 { } /* end */
2809};
2810
ccc656ce
KY
2811/* Uniwill */
2812static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2813 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2814 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2815 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2816 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2817 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2818 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2819 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2820 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2821 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2822 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2823 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2824 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2825 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2826 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2827 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2828 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2829 {
2830 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2831 .name = "Channel Mode",
2832 .info = alc_ch_mode_info,
2833 .get = alc_ch_mode_get,
2834 .put = alc_ch_mode_put,
2835 },
2836 { } /* end */
2837};
2838
2cf9f0fc
TD
2839static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2840 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2841 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2842 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2843 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2844 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2845 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
2846 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2847 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
2848 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2849 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
2850 { } /* end */
2851};
2852
ccc656ce 2853static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2854 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2855 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2856 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2857 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2858 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2859 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2860 { } /* end */
2861};
2862
2134ea4f
TI
2863/*
2864 * virtual master controls
2865 */
2866
2867/*
2868 * slave controls for virtual master
2869 */
ea734963 2870static const char * const alc_slave_vols[] = {
2134ea4f
TI
2871 "Front Playback Volume",
2872 "Surround Playback Volume",
2873 "Center Playback Volume",
2874 "LFE Playback Volume",
2875 "Side Playback Volume",
2876 "Headphone Playback Volume",
2877 "Speaker Playback Volume",
2878 "Mono Playback Volume",
2134ea4f 2879 "Line-Out Playback Volume",
26f5df26 2880 "PCM Playback Volume",
2134ea4f
TI
2881 NULL,
2882};
2883
ea734963 2884static const char * const alc_slave_sws[] = {
2134ea4f
TI
2885 "Front Playback Switch",
2886 "Surround Playback Switch",
2887 "Center Playback Switch",
2888 "LFE Playback Switch",
2889 "Side Playback Switch",
2890 "Headphone Playback Switch",
2891 "Speaker Playback Switch",
2892 "Mono Playback Switch",
edb54a55 2893 "IEC958 Playback Switch",
23033b2b
TI
2894 "Line-Out Playback Switch",
2895 "PCM Playback Switch",
2134ea4f
TI
2896 NULL,
2897};
2898
1da177e4 2899/*
e9edcee0 2900 * build control elements
1da177e4 2901 */
603c4019 2902
5b0cb1d8
JK
2903#define NID_MAPPING (-1)
2904
2905#define SUBDEV_SPEAKER_ (0 << 6)
2906#define SUBDEV_HP_ (1 << 6)
2907#define SUBDEV_LINE_ (2 << 6)
2908#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2909#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2910#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2911
603c4019
TI
2912static void alc_free_kctls(struct hda_codec *codec);
2913
67d634c0 2914#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2915/* additional beep mixers; the actual parameters are overwritten at build */
2916static struct snd_kcontrol_new alc_beep_mixer[] = {
2917 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2918 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2919 { } /* end */
2920};
67d634c0 2921#endif
45bdd1c1 2922
1da177e4
LT
2923static int alc_build_controls(struct hda_codec *codec)
2924{
2925 struct alc_spec *spec = codec->spec;
2f44f847 2926 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2927 struct snd_kcontrol_new *knew;
2928 int i, j, err;
2929 unsigned int u;
2930 hda_nid_t nid;
1da177e4
LT
2931
2932 for (i = 0; i < spec->num_mixers; i++) {
2933 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2934 if (err < 0)
2935 return err;
2936 }
f9e336f6
TI
2937 if (spec->cap_mixer) {
2938 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2939 if (err < 0)
2940 return err;
2941 }
1da177e4 2942 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2943 err = snd_hda_create_spdif_out_ctls(codec,
2944 spec->multiout.dig_out_nid);
1da177e4
LT
2945 if (err < 0)
2946 return err;
e64f14f4
TI
2947 if (!spec->no_analog) {
2948 err = snd_hda_create_spdif_share_sw(codec,
2949 &spec->multiout);
2950 if (err < 0)
2951 return err;
2952 spec->multiout.share_spdif = 1;
2953 }
1da177e4
LT
2954 }
2955 if (spec->dig_in_nid) {
2956 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2957 if (err < 0)
2958 return err;
2959 }
2134ea4f 2960
67d634c0 2961#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2962 /* create beep controls if needed */
2963 if (spec->beep_amp) {
2964 struct snd_kcontrol_new *knew;
2965 for (knew = alc_beep_mixer; knew->name; knew++) {
2966 struct snd_kcontrol *kctl;
2967 kctl = snd_ctl_new1(knew, codec);
2968 if (!kctl)
2969 return -ENOMEM;
2970 kctl->private_value = spec->beep_amp;
5e26dfd0 2971 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2972 if (err < 0)
2973 return err;
2974 }
2975 }
67d634c0 2976#endif
45bdd1c1 2977
2134ea4f 2978 /* if we have no master control, let's create it */
e64f14f4
TI
2979 if (!spec->no_analog &&
2980 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2981 unsigned int vmaster_tlv[4];
2134ea4f 2982 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2983 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2984 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2985 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2986 if (err < 0)
2987 return err;
2988 }
e64f14f4
TI
2989 if (!spec->no_analog &&
2990 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2991 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2992 NULL, alc_slave_sws);
2993 if (err < 0)
2994 return err;
2995 }
2996
5b0cb1d8 2997 /* assign Capture Source enums to NID */
fbe618f2
TI
2998 if (spec->capsrc_nids || spec->adc_nids) {
2999 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3000 if (!kctl)
3001 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3002 for (i = 0; kctl && i < kctl->count; i++) {
3003 hda_nid_t *nids = spec->capsrc_nids;
3004 if (!nids)
3005 nids = spec->adc_nids;
3006 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3007 if (err < 0)
3008 return err;
3009 }
5b0cb1d8
JK
3010 }
3011 if (spec->cap_mixer) {
3012 const char *kname = kctl ? kctl->id.name : NULL;
3013 for (knew = spec->cap_mixer; knew->name; knew++) {
3014 if (kname && strcmp(knew->name, kname) == 0)
3015 continue;
3016 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3017 for (i = 0; kctl && i < kctl->count; i++) {
3018 err = snd_hda_add_nid(codec, kctl, i,
3019 spec->adc_nids[i]);
3020 if (err < 0)
3021 return err;
3022 }
3023 }
3024 }
3025
3026 /* other nid->control mapping */
3027 for (i = 0; i < spec->num_mixers; i++) {
3028 for (knew = spec->mixers[i]; knew->name; knew++) {
3029 if (knew->iface != NID_MAPPING)
3030 continue;
3031 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3032 if (kctl == NULL)
3033 continue;
3034 u = knew->subdevice;
3035 for (j = 0; j < 4; j++, u >>= 8) {
3036 nid = u & 0x3f;
3037 if (nid == 0)
3038 continue;
3039 switch (u & 0xc0) {
3040 case SUBDEV_SPEAKER_:
3041 nid = spec->autocfg.speaker_pins[nid];
3042 break;
3043 case SUBDEV_LINE_:
3044 nid = spec->autocfg.line_out_pins[nid];
3045 break;
3046 case SUBDEV_HP_:
3047 nid = spec->autocfg.hp_pins[nid];
3048 break;
3049 default:
3050 continue;
3051 }
3052 err = snd_hda_add_nid(codec, kctl, 0, nid);
3053 if (err < 0)
3054 return err;
3055 }
3056 u = knew->private_value;
3057 for (j = 0; j < 4; j++, u >>= 8) {
3058 nid = u & 0xff;
3059 if (nid == 0)
3060 continue;
3061 err = snd_hda_add_nid(codec, kctl, 0, nid);
3062 if (err < 0)
3063 return err;
3064 }
3065 }
3066 }
bae84e70
TI
3067
3068 alc_free_kctls(codec); /* no longer needed */
3069
1da177e4
LT
3070 return 0;
3071}
3072
e9edcee0 3073
1da177e4
LT
3074/*
3075 * initialize the codec volumes, etc
3076 */
3077
e9edcee0
TI
3078/*
3079 * generic initialization of ADC, input mixers and output mixers
3080 */
3081static struct hda_verb alc880_volume_init_verbs[] = {
3082 /*
3083 * Unmute ADC0-2 and set the default input to mic-in
3084 */
71fe7b82 3085 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3086 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3087 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3088 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3089 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3090 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3091
e9edcee0
TI
3092 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3093 * mixer widget
9c7f852e
TI
3094 * Note: PASD motherboards uses the Line In 2 as the input for front
3095 * panel mic (mic 2)
1da177e4 3096 */
e9edcee0 3097 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3105
e9edcee0
TI
3106 /*
3107 * Set up output mixers (0x0c - 0x0f)
1da177e4 3108 */
e9edcee0
TI
3109 /* set vol=0 to output mixers */
3110 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3111 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3112 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3113 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3114 /* set up input amps for analog loopback */
3115 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3118 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3120 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3122 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3123 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3124
3125 { }
3126};
3127
e9edcee0
TI
3128/*
3129 * 3-stack pin configuration:
3130 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3131 */
3132static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3133 /*
3134 * preset connection lists of input pins
3135 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3136 */
3137 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3138 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3139 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3140
3141 /*
3142 * Set pin mode and muting
3143 */
3144 /* set front pin widgets 0x14 for output */
05acb863 3145 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3146 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3147 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3148 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3149 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3150 /* Mic2 (as headphone out) for HP output */
3151 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3152 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3153 /* Line In pin widget for input */
05acb863 3154 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3155 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3156 /* Line2 (as front mic) pin widget for input and vref at 80% */
3157 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3158 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3159 /* CD pin widget for input */
05acb863 3160 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3161
e9edcee0
TI
3162 { }
3163};
1da177e4 3164
e9edcee0
TI
3165/*
3166 * 5-stack pin configuration:
3167 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3168 * line-in/side = 0x1a, f-mic = 0x1b
3169 */
3170static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3171 /*
3172 * preset connection lists of input pins
3173 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3174 */
e9edcee0
TI
3175 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3176 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3177
e9edcee0
TI
3178 /*
3179 * Set pin mode and muting
1da177e4 3180 */
e9edcee0
TI
3181 /* set pin widgets 0x14-0x17 for output */
3182 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3183 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3184 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3185 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3186 /* unmute pins for output (no gain on this amp) */
3187 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3188 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3189 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3190 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3191
3192 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3193 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3194 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3195 /* Mic2 (as headphone out) for HP output */
3196 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3197 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3198 /* Line In pin widget for input */
3199 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3200 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3201 /* Line2 (as front mic) pin widget for input and vref at 80% */
3202 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3203 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3204 /* CD pin widget for input */
3205 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3206
3207 { }
3208};
3209
e9edcee0
TI
3210/*
3211 * W810 pin configuration:
3212 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3213 */
3214static struct hda_verb alc880_pin_w810_init_verbs[] = {
3215 /* hphone/speaker input selector: front DAC */
3216 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3217
05acb863 3218 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3219 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3221 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3222 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3223 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3224
e9edcee0 3225 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3226 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3227
1da177e4
LT
3228 { }
3229};
3230
e9edcee0
TI
3231/*
3232 * Z71V pin configuration:
3233 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3234 */
3235static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3236 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3237 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3238 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3239 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3240
16ded525 3241 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3242 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3243 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3244 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3245
3246 { }
3247};
3248
e9edcee0
TI
3249/*
3250 * 6-stack pin configuration:
9c7f852e
TI
3251 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3252 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3253 */
3254static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3255 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3256
16ded525 3257 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3258 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3260 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3261 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3262 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3263 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3264 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3265
16ded525 3266 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3267 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3268 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3269 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3271 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3272 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3273 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3274 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3275
e9edcee0
TI
3276 { }
3277};
3278
ccc656ce
KY
3279/*
3280 * Uniwill pin configuration:
3281 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3282 * line = 0x1a
3283 */
3284static struct hda_verb alc880_uniwill_init_verbs[] = {
3285 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3286
3287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3288 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3289 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3290 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3291 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3292 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3293 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3294 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3296 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3297 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3298 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3299 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3300 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3301
3302 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3303 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3304 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3305 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3306 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3307 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3308 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3309 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3310 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3311
3312 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3313 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3314
3315 { }
3316};
3317
3318/*
3319* Uniwill P53
ea1fb29a 3320* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3321 */
3322static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3323 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3324
3325 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3328 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3329 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3330 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3333 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3334 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3335 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3336 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3337
3338 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3339 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3340 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3341 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3342 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3343 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3344
3345 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3346 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3347
3348 { }
3349};
3350
2cf9f0fc
TD
3351static struct hda_verb alc880_beep_init_verbs[] = {
3352 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3353 { }
3354};
3355
458a4fab 3356/* auto-toggle front mic */
eeb43387 3357static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3358{
3359 unsigned int present;
3360 unsigned char bits;
ccc656ce 3361
864f92be 3362 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3363 bits = present ? HDA_AMP_MUTE : 0;
3364 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3365}
3366
4f5d1706 3367static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3368{
a9fd4f3f
TI
3369 struct alc_spec *spec = codec->spec;
3370
3371 spec->autocfg.hp_pins[0] = 0x14;
3372 spec->autocfg.speaker_pins[0] = 0x15;
3373 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3374}
3375
3376static void alc880_uniwill_init_hook(struct hda_codec *codec)
3377{
a9fd4f3f 3378 alc_automute_amp(codec);
eeb43387 3379 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3380}
3381
3382static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3383 unsigned int res)
3384{
3385 /* Looks like the unsol event is incompatible with the standard
3386 * definition. 4bit tag is placed at 28 bit!
3387 */
458a4fab 3388 switch (res >> 28) {
458a4fab 3389 case ALC880_MIC_EVENT:
eeb43387 3390 alc88x_simple_mic_automute(codec);
458a4fab 3391 break;
a9fd4f3f
TI
3392 default:
3393 alc_automute_amp_unsol_event(codec, res);
3394 break;
458a4fab 3395 }
ccc656ce
KY
3396}
3397
4f5d1706 3398static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3399{
a9fd4f3f 3400 struct alc_spec *spec = codec->spec;
ccc656ce 3401
a9fd4f3f
TI
3402 spec->autocfg.hp_pins[0] = 0x14;
3403 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3404}
3405
3406static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3407{
3408 unsigned int present;
ea1fb29a 3409
ccc656ce 3410 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3411 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3412 present &= HDA_AMP_VOLMASK;
3413 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3414 HDA_AMP_VOLMASK, present);
3415 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3416 HDA_AMP_VOLMASK, present);
ccc656ce 3417}
47fd830a 3418
ccc656ce
KY
3419static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3420 unsigned int res)
3421{
3422 /* Looks like the unsol event is incompatible with the standard
3423 * definition. 4bit tag is placed at 28 bit!
3424 */
f12ab1e0 3425 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3426 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3427 else
3428 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3429}
3430
e9edcee0
TI
3431/*
3432 * F1734 pin configuration:
3433 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3434 */
3435static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3436 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3437 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3438 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3439 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3440 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3441
e9edcee0 3442 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3443 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3444 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3445 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3446
e9edcee0
TI
3447 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3448 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3449 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3450 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3451 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3452 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3453 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3454 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3455 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3456
937b4160
TI
3457 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3458 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3459
dfc0ff62
TI
3460 { }
3461};
3462
e9edcee0
TI
3463/*
3464 * ASUS pin configuration:
3465 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3466 */
3467static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3468 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3469 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3470 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3471 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3472
3473 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3474 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3475 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3476 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3477 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3478 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3479 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3480 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3481
3482 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3483 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3484 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3485 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3486 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3487 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3488 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3489 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3490 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3491
e9edcee0
TI
3492 { }
3493};
16ded525 3494
e9edcee0 3495/* Enable GPIO mask and set output */
bc9f98a9
KY
3496#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3497#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3498#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3499
3500/* Clevo m520g init */
3501static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3502 /* headphone output */
3503 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3504 /* line-out */
3505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3506 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3507 /* Line-in */
3508 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3509 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3510 /* CD */
3511 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3512 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3513 /* Mic1 (rear panel) */
3514 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3515 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3516 /* Mic2 (front panel) */
3517 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3518 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3519 /* headphone */
3520 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3521 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3522 /* change to EAPD mode */
3523 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3524 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3525
3526 { }
16ded525
TI
3527};
3528
df694daa 3529static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3530 /* change to EAPD mode */
3531 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3532 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3533
df694daa
KY
3534 /* Headphone output */
3535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3536 /* Front output*/
3537 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3538 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3539
3540 /* Line In pin widget for input */
3541 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3542 /* CD pin widget for input */
3543 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3544 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3545 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3546
3547 /* change to EAPD mode */
3548 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3549 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3550
3551 { }
3552};
16ded525 3553
e9edcee0 3554/*
ae6b813a
TI
3555 * LG m1 express dual
3556 *
3557 * Pin assignment:
3558 * Rear Line-In/Out (blue): 0x14
3559 * Build-in Mic-In: 0x15
3560 * Speaker-out: 0x17
3561 * HP-Out (green): 0x1b
3562 * Mic-In/Out (red): 0x19
3563 * SPDIF-Out: 0x1e
3564 */
3565
3566/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3567static hda_nid_t alc880_lg_dac_nids[3] = {
3568 0x05, 0x02, 0x03
3569};
3570
3571/* seems analog CD is not working */
3572static struct hda_input_mux alc880_lg_capture_source = {
3573 .num_items = 3,
3574 .items = {
3575 { "Mic", 0x1 },
3576 { "Line", 0x5 },
3577 { "Internal Mic", 0x6 },
3578 },
3579};
3580
3581/* 2,4,6 channel modes */
3582static struct hda_verb alc880_lg_ch2_init[] = {
3583 /* set line-in and mic-in to input */
3584 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3585 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3586 { }
3587};
3588
3589static struct hda_verb alc880_lg_ch4_init[] = {
3590 /* set line-in to out and mic-in to input */
3591 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3592 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3593 { }
3594};
3595
3596static struct hda_verb alc880_lg_ch6_init[] = {
3597 /* set line-in and mic-in to output */
3598 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3599 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3600 { }
3601};
3602
3603static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3604 { 2, alc880_lg_ch2_init },
3605 { 4, alc880_lg_ch4_init },
3606 { 6, alc880_lg_ch6_init },
3607};
3608
3609static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3610 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3611 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3612 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3613 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3614 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3615 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3616 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3617 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3618 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3619 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3620 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3621 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3622 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3623 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3624 {
3625 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3626 .name = "Channel Mode",
3627 .info = alc_ch_mode_info,
3628 .get = alc_ch_mode_get,
3629 .put = alc_ch_mode_put,
3630 },
3631 { } /* end */
3632};
3633
3634static struct hda_verb alc880_lg_init_verbs[] = {
3635 /* set capture source to mic-in */
3636 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3637 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3638 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3639 /* mute all amp mixer inputs */
3640 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3643 /* line-in to input */
3644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3646 /* built-in mic */
3647 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3648 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3649 /* speaker-out */
3650 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3651 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3652 /* mic-in to input */
3653 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3654 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3655 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3656 /* HP-out */
3657 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3658 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3659 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3660 /* jack sense */
a9fd4f3f 3661 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3662 { }
3663};
3664
3665/* toggle speaker-output according to the hp-jack state */
4f5d1706 3666static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3667{
a9fd4f3f 3668 struct alc_spec *spec = codec->spec;
ae6b813a 3669
a9fd4f3f
TI
3670 spec->autocfg.hp_pins[0] = 0x1b;
3671 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3672}
3673
d681518a
TI
3674/*
3675 * LG LW20
3676 *
3677 * Pin assignment:
3678 * Speaker-out: 0x14
3679 * Mic-In: 0x18
e4f41da9
CM
3680 * Built-in Mic-In: 0x19
3681 * Line-In: 0x1b
3682 * HP-Out: 0x1a
d681518a
TI
3683 * SPDIF-Out: 0x1e
3684 */
3685
d681518a 3686static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3687 .num_items = 3,
d681518a
TI
3688 .items = {
3689 { "Mic", 0x0 },
3690 { "Internal Mic", 0x1 },
e4f41da9 3691 { "Line In", 0x2 },
d681518a
TI
3692 },
3693};
3694
0a8c5da3
CM
3695#define alc880_lg_lw_modes alc880_threestack_modes
3696
d681518a 3697static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3698 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3699 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3700 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3701 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3702 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3703 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3704 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3705 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3706 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3707 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3710 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3711 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3712 {
3713 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3714 .name = "Channel Mode",
3715 .info = alc_ch_mode_info,
3716 .get = alc_ch_mode_get,
3717 .put = alc_ch_mode_put,
3718 },
d681518a
TI
3719 { } /* end */
3720};
3721
3722static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3723 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3724 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3725 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3726
d681518a
TI
3727 /* set capture source to mic-in */
3728 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3729 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3730 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3731 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3732 /* speaker-out */
3733 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3734 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3735 /* HP-out */
d681518a
TI
3736 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3737 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3738 /* mic-in to input */
3739 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3740 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3741 /* built-in mic */
3742 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3743 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3744 /* jack sense */
a9fd4f3f 3745 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3746 { }
3747};
3748
3749/* toggle speaker-output according to the hp-jack state */
4f5d1706 3750static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3751{
a9fd4f3f 3752 struct alc_spec *spec = codec->spec;
d681518a 3753
a9fd4f3f
TI
3754 spec->autocfg.hp_pins[0] = 0x1b;
3755 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3756}
3757
df99cd33
TI
3758static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3759 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3760 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3761 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3762 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3763 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3764 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3765 { } /* end */
3766};
3767
3768static struct hda_input_mux alc880_medion_rim_capture_source = {
3769 .num_items = 2,
3770 .items = {
3771 { "Mic", 0x0 },
3772 { "Internal Mic", 0x1 },
3773 },
3774};
3775
3776static struct hda_verb alc880_medion_rim_init_verbs[] = {
3777 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3778
3779 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3780 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3781
3782 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3783 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3784 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3785 /* Mic2 (as headphone out) for HP output */
3786 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3787 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3788 /* Internal Speaker */
3789 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3790 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3791
3792 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3793 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3794
3795 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3796 { }
3797};
3798
3799/* toggle speaker-output according to the hp-jack state */
3800static void alc880_medion_rim_automute(struct hda_codec *codec)
3801{
a9fd4f3f
TI
3802 struct alc_spec *spec = codec->spec;
3803 alc_automute_amp(codec);
3804 /* toggle EAPD */
3805 if (spec->jack_present)
df99cd33
TI
3806 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3807 else
3808 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3809}
3810
3811static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3812 unsigned int res)
3813{
3814 /* Looks like the unsol event is incompatible with the standard
3815 * definition. 4bit tag is placed at 28 bit!
3816 */
3817 if ((res >> 28) == ALC880_HP_EVENT)
3818 alc880_medion_rim_automute(codec);
3819}
3820
4f5d1706 3821static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3822{
3823 struct alc_spec *spec = codec->spec;
3824
3825 spec->autocfg.hp_pins[0] = 0x14;
3826 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3827}
3828
cb53c626
TI
3829#ifdef CONFIG_SND_HDA_POWER_SAVE
3830static struct hda_amp_list alc880_loopbacks[] = {
3831 { 0x0b, HDA_INPUT, 0 },
3832 { 0x0b, HDA_INPUT, 1 },
3833 { 0x0b, HDA_INPUT, 2 },
3834 { 0x0b, HDA_INPUT, 3 },
3835 { 0x0b, HDA_INPUT, 4 },
3836 { } /* end */
3837};
3838
3839static struct hda_amp_list alc880_lg_loopbacks[] = {
3840 { 0x0b, HDA_INPUT, 1 },
3841 { 0x0b, HDA_INPUT, 6 },
3842 { 0x0b, HDA_INPUT, 7 },
3843 { } /* end */
3844};
3845#endif
3846
ae6b813a
TI
3847/*
3848 * Common callbacks
e9edcee0
TI
3849 */
3850
584c0c4c
TI
3851static void alc_init_special_input_src(struct hda_codec *codec);
3852
1da177e4
LT
3853static int alc_init(struct hda_codec *codec)
3854{
3855 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3856 unsigned int i;
3857
2c3bf9ab 3858 alc_fix_pll(codec);
4a79ba34 3859 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3860
e9edcee0
TI
3861 for (i = 0; i < spec->num_init_verbs; i++)
3862 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 3863 alc_init_special_input_src(codec);
ae6b813a
TI
3864
3865 if (spec->init_hook)
3866 spec->init_hook(codec);
3867
58701120
TI
3868 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
3869
9e5341b9 3870 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
3871 return 0;
3872}
3873
ae6b813a
TI
3874static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3875{
3876 struct alc_spec *spec = codec->spec;
3877
3878 if (spec->unsol_event)
3879 spec->unsol_event(codec, res);
3880}
3881
cb53c626
TI
3882#ifdef CONFIG_SND_HDA_POWER_SAVE
3883static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3884{
3885 struct alc_spec *spec = codec->spec;
3886 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3887}
3888#endif
3889
1da177e4
LT
3890/*
3891 * Analog playback callbacks
3892 */
3893static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3894 struct hda_codec *codec,
c8b6bf9b 3895 struct snd_pcm_substream *substream)
1da177e4
LT
3896{
3897 struct alc_spec *spec = codec->spec;
9a08160b
TI
3898 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3899 hinfo);
1da177e4
LT
3900}
3901
3902static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3903 struct hda_codec *codec,
3904 unsigned int stream_tag,
3905 unsigned int format,
c8b6bf9b 3906 struct snd_pcm_substream *substream)
1da177e4
LT
3907{
3908 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3909 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3910 stream_tag, format, substream);
1da177e4
LT
3911}
3912
3913static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3914 struct hda_codec *codec,
c8b6bf9b 3915 struct snd_pcm_substream *substream)
1da177e4
LT
3916{
3917 struct alc_spec *spec = codec->spec;
3918 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3919}
3920
3921/*
3922 * Digital out
3923 */
3924static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3925 struct hda_codec *codec,
c8b6bf9b 3926 struct snd_pcm_substream *substream)
1da177e4
LT
3927{
3928 struct alc_spec *spec = codec->spec;
3929 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3930}
3931
6b97eb45
TI
3932static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3933 struct hda_codec *codec,
3934 unsigned int stream_tag,
3935 unsigned int format,
3936 struct snd_pcm_substream *substream)
3937{
3938 struct alc_spec *spec = codec->spec;
3939 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3940 stream_tag, format, substream);
3941}
3942
9b5f12e5
TI
3943static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3944 struct hda_codec *codec,
3945 struct snd_pcm_substream *substream)
3946{
3947 struct alc_spec *spec = codec->spec;
3948 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3949}
3950
1da177e4
LT
3951static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3952 struct hda_codec *codec,
c8b6bf9b 3953 struct snd_pcm_substream *substream)
1da177e4
LT
3954{
3955 struct alc_spec *spec = codec->spec;
3956 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3957}
3958
3959/*
3960 * Analog capture
3961 */
6330079f 3962static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3963 struct hda_codec *codec,
3964 unsigned int stream_tag,
3965 unsigned int format,
c8b6bf9b 3966 struct snd_pcm_substream *substream)
1da177e4
LT
3967{
3968 struct alc_spec *spec = codec->spec;
3969
6330079f 3970 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3971 stream_tag, 0, format);
3972 return 0;
3973}
3974
6330079f 3975static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3976 struct hda_codec *codec,
c8b6bf9b 3977 struct snd_pcm_substream *substream)
1da177e4
LT
3978{
3979 struct alc_spec *spec = codec->spec;
3980
888afa15
TI
3981 snd_hda_codec_cleanup_stream(codec,
3982 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3983 return 0;
3984}
3985
840b64c0
TI
3986/* analog capture with dynamic dual-adc changes */
3987static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3988 struct hda_codec *codec,
3989 unsigned int stream_tag,
3990 unsigned int format,
3991 struct snd_pcm_substream *substream)
3992{
3993 struct alc_spec *spec = codec->spec;
3994 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3995 spec->cur_adc_stream_tag = stream_tag;
3996 spec->cur_adc_format = format;
3997 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3998 return 0;
3999}
4000
4001static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4002 struct hda_codec *codec,
4003 struct snd_pcm_substream *substream)
4004{
4005 struct alc_spec *spec = codec->spec;
4006 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4007 spec->cur_adc = 0;
4008 return 0;
4009}
4010
4011static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4012 .substreams = 1,
4013 .channels_min = 2,
4014 .channels_max = 2,
4015 .nid = 0, /* fill later */
4016 .ops = {
4017 .prepare = dualmic_capture_pcm_prepare,
4018 .cleanup = dualmic_capture_pcm_cleanup
4019 },
4020};
1da177e4
LT
4021
4022/*
4023 */
4024static struct hda_pcm_stream alc880_pcm_analog_playback = {
4025 .substreams = 1,
4026 .channels_min = 2,
4027 .channels_max = 8,
e9edcee0 4028 /* NID is set in alc_build_pcms */
1da177e4
LT
4029 .ops = {
4030 .open = alc880_playback_pcm_open,
4031 .prepare = alc880_playback_pcm_prepare,
4032 .cleanup = alc880_playback_pcm_cleanup
4033 },
4034};
4035
4036static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4037 .substreams = 1,
4038 .channels_min = 2,
4039 .channels_max = 2,
4040 /* NID is set in alc_build_pcms */
4041};
4042
4043static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4044 .substreams = 1,
4045 .channels_min = 2,
4046 .channels_max = 2,
4047 /* NID is set in alc_build_pcms */
4048};
4049
4050static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4051 .substreams = 2, /* can be overridden */
1da177e4
LT
4052 .channels_min = 2,
4053 .channels_max = 2,
e9edcee0 4054 /* NID is set in alc_build_pcms */
1da177e4 4055 .ops = {
6330079f
TI
4056 .prepare = alc880_alt_capture_pcm_prepare,
4057 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4058 },
4059};
4060
4061static struct hda_pcm_stream alc880_pcm_digital_playback = {
4062 .substreams = 1,
4063 .channels_min = 2,
4064 .channels_max = 2,
4065 /* NID is set in alc_build_pcms */
4066 .ops = {
4067 .open = alc880_dig_playback_pcm_open,
6b97eb45 4068 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4069 .prepare = alc880_dig_playback_pcm_prepare,
4070 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4071 },
4072};
4073
4074static struct hda_pcm_stream alc880_pcm_digital_capture = {
4075 .substreams = 1,
4076 .channels_min = 2,
4077 .channels_max = 2,
4078 /* NID is set in alc_build_pcms */
4079};
4080
4c5186ed 4081/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 4082static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4083 .substreams = 0,
4084 .channels_min = 0,
4085 .channels_max = 0,
4086};
4087
1da177e4
LT
4088static int alc_build_pcms(struct hda_codec *codec)
4089{
4090 struct alc_spec *spec = codec->spec;
4091 struct hda_pcm *info = spec->pcm_rec;
4092 int i;
4093
4094 codec->num_pcms = 1;
4095 codec->pcm_info = info;
4096
e64f14f4
TI
4097 if (spec->no_analog)
4098 goto skip_analog;
4099
812a2cca
TI
4100 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4101 "%s Analog", codec->chip_name);
1da177e4 4102 info->name = spec->stream_name_analog;
274693f3 4103
4a471b7d 4104 if (spec->stream_analog_playback) {
da3cec35
TI
4105 if (snd_BUG_ON(!spec->multiout.dac_nids))
4106 return -EINVAL;
4a471b7d
TI
4107 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4108 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4109 }
4110 if (spec->stream_analog_capture) {
da3cec35
TI
4111 if (snd_BUG_ON(!spec->adc_nids))
4112 return -EINVAL;
4a471b7d
TI
4113 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4114 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4115 }
4116
4117 if (spec->channel_mode) {
4118 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4119 for (i = 0; i < spec->num_channel_mode; i++) {
4120 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4121 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4122 }
1da177e4
LT
4123 }
4124 }
4125
e64f14f4 4126 skip_analog:
e08a007d 4127 /* SPDIF for stream index #1 */
1da177e4 4128 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4129 snprintf(spec->stream_name_digital,
4130 sizeof(spec->stream_name_digital),
4131 "%s Digital", codec->chip_name);
e08a007d 4132 codec->num_pcms = 2;
b25c9da1 4133 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4134 info = spec->pcm_rec + 1;
1da177e4 4135 info->name = spec->stream_name_digital;
8c441982
TI
4136 if (spec->dig_out_type)
4137 info->pcm_type = spec->dig_out_type;
4138 else
4139 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4140 if (spec->multiout.dig_out_nid &&
4141 spec->stream_digital_playback) {
1da177e4
LT
4142 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4143 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4144 }
4a471b7d
TI
4145 if (spec->dig_in_nid &&
4146 spec->stream_digital_capture) {
1da177e4
LT
4147 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4148 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4149 }
963f803f
TI
4150 /* FIXME: do we need this for all Realtek codec models? */
4151 codec->spdif_status_reset = 1;
1da177e4
LT
4152 }
4153
e64f14f4
TI
4154 if (spec->no_analog)
4155 return 0;
4156
e08a007d
TI
4157 /* If the use of more than one ADC is requested for the current
4158 * model, configure a second analog capture-only PCM.
4159 */
4160 /* Additional Analaog capture for index #2 */
6330079f
TI
4161 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4162 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4163 codec->num_pcms = 3;
c06134d7 4164 info = spec->pcm_rec + 2;
e08a007d 4165 info->name = spec->stream_name_analog;
6330079f
TI
4166 if (spec->alt_dac_nid) {
4167 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4168 *spec->stream_analog_alt_playback;
4169 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4170 spec->alt_dac_nid;
4171 } else {
4172 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4173 alc_pcm_null_stream;
4174 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4175 }
4176 if (spec->num_adc_nids > 1) {
4177 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4178 *spec->stream_analog_alt_capture;
4179 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4180 spec->adc_nids[1];
4181 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4182 spec->num_adc_nids - 1;
4183 } else {
4184 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4185 alc_pcm_null_stream;
4186 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4187 }
4188 }
4189
1da177e4
LT
4190 return 0;
4191}
4192
a4e09aa3
TI
4193static inline void alc_shutup(struct hda_codec *codec)
4194{
4195 snd_hda_shutup_pins(codec);
4196}
4197
603c4019
TI
4198static void alc_free_kctls(struct hda_codec *codec)
4199{
4200 struct alc_spec *spec = codec->spec;
4201
4202 if (spec->kctls.list) {
4203 struct snd_kcontrol_new *kctl = spec->kctls.list;
4204 int i;
4205 for (i = 0; i < spec->kctls.used; i++)
4206 kfree(kctl[i].name);
4207 }
4208 snd_array_free(&spec->kctls);
4209}
4210
1da177e4
LT
4211static void alc_free(struct hda_codec *codec)
4212{
e9edcee0 4213 struct alc_spec *spec = codec->spec;
e9edcee0 4214
f12ab1e0 4215 if (!spec)
e9edcee0
TI
4216 return;
4217
a4e09aa3 4218 alc_shutup(codec);
cd372fb3 4219 snd_hda_input_jack_free(codec);
603c4019 4220 alc_free_kctls(codec);
e9edcee0 4221 kfree(spec);
680cd536 4222 snd_hda_detach_beep_device(codec);
1da177e4
LT
4223}
4224
f5de24b0 4225#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4226static void alc_power_eapd(struct hda_codec *codec)
4227{
4228 /* We currently only handle front, HP */
4229 switch (codec->vendor_id) {
4230 case 0x10ec0260:
9e4c8496
TI
4231 set_eapd(codec, 0x0f, 0);
4232 set_eapd(codec, 0x10, 0);
c97259df
DC
4233 break;
4234 case 0x10ec0262:
4235 case 0x10ec0267:
4236 case 0x10ec0268:
4237 case 0x10ec0269:
9e4c8496 4238 case 0x10ec0270:
c97259df
DC
4239 case 0x10ec0272:
4240 case 0x10ec0660:
4241 case 0x10ec0662:
4242 case 0x10ec0663:
4243 case 0x10ec0862:
4244 case 0x10ec0889:
9e4c8496
TI
4245 set_eapd(codec, 0x14, 0);
4246 set_eapd(codec, 0x15, 0);
c97259df
DC
4247 break;
4248 }
4249}
4250
f5de24b0
HM
4251static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4252{
4253 struct alc_spec *spec = codec->spec;
a4e09aa3 4254 alc_shutup(codec);
f5de24b0 4255 if (spec && spec->power_hook)
c97259df 4256 spec->power_hook(codec);
f5de24b0
HM
4257 return 0;
4258}
4259#endif
4260
e044c39a 4261#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4262static int alc_resume(struct hda_codec *codec)
4263{
e044c39a
TI
4264 codec->patch_ops.init(codec);
4265 snd_hda_codec_resume_amp(codec);
4266 snd_hda_codec_resume_cache(codec);
9e5341b9 4267 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4268 return 0;
4269}
e044c39a
TI
4270#endif
4271
1da177e4
LT
4272/*
4273 */
4274static struct hda_codec_ops alc_patch_ops = {
4275 .build_controls = alc_build_controls,
4276 .build_pcms = alc_build_pcms,
4277 .init = alc_init,
4278 .free = alc_free,
ae6b813a 4279 .unsol_event = alc_unsol_event,
e044c39a
TI
4280#ifdef SND_HDA_NEEDS_RESUME
4281 .resume = alc_resume,
4282#endif
cb53c626 4283#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4284 .suspend = alc_suspend,
cb53c626
TI
4285 .check_power_status = alc_check_power_status,
4286#endif
c97259df 4287 .reboot_notify = alc_shutup,
1da177e4
LT
4288};
4289
c027ddcd
KY
4290/* replace the codec chip_name with the given string */
4291static int alc_codec_rename(struct hda_codec *codec, const char *name)
4292{
4293 kfree(codec->chip_name);
4294 codec->chip_name = kstrdup(name, GFP_KERNEL);
4295 if (!codec->chip_name) {
4296 alc_free(codec);
4297 return -ENOMEM;
4298 }
4299 return 0;
4300}
4301
2fa522be
TI
4302/*
4303 * Test configuration for debugging
4304 *
4305 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4306 * enum controls.
4307 */
4308#ifdef CONFIG_SND_DEBUG
4309static hda_nid_t alc880_test_dac_nids[4] = {
4310 0x02, 0x03, 0x04, 0x05
4311};
4312
4313static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4314 .num_items = 7,
2fa522be
TI
4315 .items = {
4316 { "In-1", 0x0 },
4317 { "In-2", 0x1 },
4318 { "In-3", 0x2 },
4319 { "In-4", 0x3 },
4320 { "CD", 0x4 },
ae6b813a
TI
4321 { "Front", 0x5 },
4322 { "Surround", 0x6 },
2fa522be
TI
4323 },
4324};
4325
d2a6d7dc 4326static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4327 { 2, NULL },
fd2c326d 4328 { 4, NULL },
2fa522be 4329 { 6, NULL },
fd2c326d 4330 { 8, NULL },
2fa522be
TI
4331};
4332
9c7f852e
TI
4333static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4334 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4335{
4336 static char *texts[] = {
4337 "N/A", "Line Out", "HP Out",
4338 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4339 };
4340 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4341 uinfo->count = 1;
4342 uinfo->value.enumerated.items = 8;
4343 if (uinfo->value.enumerated.item >= 8)
4344 uinfo->value.enumerated.item = 7;
4345 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4346 return 0;
4347}
4348
9c7f852e
TI
4349static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4350 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4351{
4352 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4353 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4354 unsigned int pin_ctl, item = 0;
4355
4356 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4357 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4358 if (pin_ctl & AC_PINCTL_OUT_EN) {
4359 if (pin_ctl & AC_PINCTL_HP_EN)
4360 item = 2;
4361 else
4362 item = 1;
4363 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4364 switch (pin_ctl & AC_PINCTL_VREFEN) {
4365 case AC_PINCTL_VREF_HIZ: item = 3; break;
4366 case AC_PINCTL_VREF_50: item = 4; break;
4367 case AC_PINCTL_VREF_GRD: item = 5; break;
4368 case AC_PINCTL_VREF_80: item = 6; break;
4369 case AC_PINCTL_VREF_100: item = 7; break;
4370 }
4371 }
4372 ucontrol->value.enumerated.item[0] = item;
4373 return 0;
4374}
4375
9c7f852e
TI
4376static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4377 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4378{
4379 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4380 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4381 static unsigned int ctls[] = {
4382 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4383 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4384 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4385 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4386 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4387 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4388 };
4389 unsigned int old_ctl, new_ctl;
4390
4391 old_ctl = snd_hda_codec_read(codec, nid, 0,
4392 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4393 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4394 if (old_ctl != new_ctl) {
82beb8fd
TI
4395 int val;
4396 snd_hda_codec_write_cache(codec, nid, 0,
4397 AC_VERB_SET_PIN_WIDGET_CONTROL,
4398 new_ctl);
47fd830a
TI
4399 val = ucontrol->value.enumerated.item[0] >= 3 ?
4400 HDA_AMP_MUTE : 0;
4401 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4402 HDA_AMP_MUTE, val);
2fa522be
TI
4403 return 1;
4404 }
4405 return 0;
4406}
4407
9c7f852e
TI
4408static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4409 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4410{
4411 static char *texts[] = {
4412 "Front", "Surround", "CLFE", "Side"
4413 };
4414 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4415 uinfo->count = 1;
4416 uinfo->value.enumerated.items = 4;
4417 if (uinfo->value.enumerated.item >= 4)
4418 uinfo->value.enumerated.item = 3;
4419 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4420 return 0;
4421}
4422
9c7f852e
TI
4423static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4424 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4425{
4426 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4427 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4428 unsigned int sel;
4429
4430 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4431 ucontrol->value.enumerated.item[0] = sel & 3;
4432 return 0;
4433}
4434
9c7f852e
TI
4435static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4436 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4437{
4438 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4439 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4440 unsigned int sel;
4441
4442 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4443 if (ucontrol->value.enumerated.item[0] != sel) {
4444 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4445 snd_hda_codec_write_cache(codec, nid, 0,
4446 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4447 return 1;
4448 }
4449 return 0;
4450}
4451
4452#define PIN_CTL_TEST(xname,nid) { \
4453 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4454 .name = xname, \
5b0cb1d8 4455 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4456 .info = alc_test_pin_ctl_info, \
4457 .get = alc_test_pin_ctl_get, \
4458 .put = alc_test_pin_ctl_put, \
4459 .private_value = nid \
4460 }
4461
4462#define PIN_SRC_TEST(xname,nid) { \
4463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4464 .name = xname, \
5b0cb1d8 4465 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4466 .info = alc_test_pin_src_info, \
4467 .get = alc_test_pin_src_get, \
4468 .put = alc_test_pin_src_put, \
4469 .private_value = nid \
4470 }
4471
c8b6bf9b 4472static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4473 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4474 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4475 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4476 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4477 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4478 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4479 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4480 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4481 PIN_CTL_TEST("Front Pin Mode", 0x14),
4482 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4483 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4484 PIN_CTL_TEST("Side Pin Mode", 0x17),
4485 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4486 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4487 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4488 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4489 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4490 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4491 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4492 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4493 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4494 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4495 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4496 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4497 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4498 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4499 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4500 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4501 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4502 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4503 {
4504 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4505 .name = "Channel Mode",
df694daa
KY
4506 .info = alc_ch_mode_info,
4507 .get = alc_ch_mode_get,
4508 .put = alc_ch_mode_put,
2fa522be
TI
4509 },
4510 { } /* end */
4511};
4512
4513static struct hda_verb alc880_test_init_verbs[] = {
4514 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4515 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4519 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4520 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4521 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4522 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4523 /* Vol output for 0x0c-0x0f */
05acb863
TI
4524 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4525 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4526 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4527 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4528 /* Set output pins 0x14-0x17 */
05acb863
TI
4529 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4530 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4531 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4532 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4533 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4534 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4535 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4536 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4537 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4538 /* Set input pins 0x18-0x1c */
16ded525
TI
4539 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4540 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4541 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4542 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4543 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4544 /* Mute input pins 0x18-0x1b */
05acb863
TI
4545 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4546 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4547 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4548 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4549 /* ADC set up */
05acb863 4550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4551 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4552 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4553 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4554 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4555 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4556 /* Analog input/passthru */
4557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4558 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4559 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4560 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4561 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4562 { }
4563};
4564#endif
4565
1da177e4
LT
4566/*
4567 */
4568
ea734963 4569static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4570 [ALC880_3ST] = "3stack",
4571 [ALC880_TCL_S700] = "tcl",
4572 [ALC880_3ST_DIG] = "3stack-digout",
4573 [ALC880_CLEVO] = "clevo",
4574 [ALC880_5ST] = "5stack",
4575 [ALC880_5ST_DIG] = "5stack-digout",
4576 [ALC880_W810] = "w810",
4577 [ALC880_Z71V] = "z71v",
4578 [ALC880_6ST] = "6stack",
4579 [ALC880_6ST_DIG] = "6stack-digout",
4580 [ALC880_ASUS] = "asus",
4581 [ALC880_ASUS_W1V] = "asus-w1v",
4582 [ALC880_ASUS_DIG] = "asus-dig",
4583 [ALC880_ASUS_DIG2] = "asus-dig2",
4584 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4585 [ALC880_UNIWILL_P53] = "uniwill-p53",
4586 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4587 [ALC880_F1734] = "F1734",
4588 [ALC880_LG] = "lg",
4589 [ALC880_LG_LW] = "lg-lw",
df99cd33 4590 [ALC880_MEDION_RIM] = "medion",
2fa522be 4591#ifdef CONFIG_SND_DEBUG
f5fcc13c 4592 [ALC880_TEST] = "test",
2fa522be 4593#endif
f5fcc13c
TI
4594 [ALC880_AUTO] = "auto",
4595};
4596
4597static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4598 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4599 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4600 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4601 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4602 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4603 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4604 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4605 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4606 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4607 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4608 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4609 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4610 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4611 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4612 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4613 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4614 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4615 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4616 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4617 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4618 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4619 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4620 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4621 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4622 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4623 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4624 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4625 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4626 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4627 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4628 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4629 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4630 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4631 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4632 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4633 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4634 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4635 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4636 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4637 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4638 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4639 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4640 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4641 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4642 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4643 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4644 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4645 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4646 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4647 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4648 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4649 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4650 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4651 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4652 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4653 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4654 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4655 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4656 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4657 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4658 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4659 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4660 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4661 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4662 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4663 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4664 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4665 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4666 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4667 /* default Intel */
4668 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4669 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4670 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4671 {}
4672};
4673
16ded525 4674/*
df694daa 4675 * ALC880 codec presets
16ded525 4676 */
16ded525
TI
4677static struct alc_config_preset alc880_presets[] = {
4678 [ALC880_3ST] = {
e9edcee0 4679 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4680 .init_verbs = { alc880_volume_init_verbs,
4681 alc880_pin_3stack_init_verbs },
16ded525 4682 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4683 .dac_nids = alc880_dac_nids,
16ded525
TI
4684 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4685 .channel_mode = alc880_threestack_modes,
4e195a7b 4686 .need_dac_fix = 1,
16ded525
TI
4687 .input_mux = &alc880_capture_source,
4688 },
4689 [ALC880_3ST_DIG] = {
e9edcee0 4690 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4691 .init_verbs = { alc880_volume_init_verbs,
4692 alc880_pin_3stack_init_verbs },
16ded525 4693 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4694 .dac_nids = alc880_dac_nids,
4695 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4696 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4697 .channel_mode = alc880_threestack_modes,
4e195a7b 4698 .need_dac_fix = 1,
16ded525
TI
4699 .input_mux = &alc880_capture_source,
4700 },
df694daa
KY
4701 [ALC880_TCL_S700] = {
4702 .mixers = { alc880_tcl_s700_mixer },
4703 .init_verbs = { alc880_volume_init_verbs,
4704 alc880_pin_tcl_S700_init_verbs,
4705 alc880_gpio2_init_verbs },
4706 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4707 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4708 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4709 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4710 .hp_nid = 0x03,
4711 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4712 .channel_mode = alc880_2_jack_modes,
4713 .input_mux = &alc880_capture_source,
4714 },
16ded525 4715 [ALC880_5ST] = {
f12ab1e0
TI
4716 .mixers = { alc880_three_stack_mixer,
4717 alc880_five_stack_mixer},
4718 .init_verbs = { alc880_volume_init_verbs,
4719 alc880_pin_5stack_init_verbs },
16ded525
TI
4720 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4721 .dac_nids = alc880_dac_nids,
16ded525
TI
4722 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4723 .channel_mode = alc880_fivestack_modes,
4724 .input_mux = &alc880_capture_source,
4725 },
4726 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4727 .mixers = { alc880_three_stack_mixer,
4728 alc880_five_stack_mixer },
4729 .init_verbs = { alc880_volume_init_verbs,
4730 alc880_pin_5stack_init_verbs },
16ded525
TI
4731 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4732 .dac_nids = alc880_dac_nids,
4733 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4734 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4735 .channel_mode = alc880_fivestack_modes,
4736 .input_mux = &alc880_capture_source,
4737 },
b6482d48
TI
4738 [ALC880_6ST] = {
4739 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4740 .init_verbs = { alc880_volume_init_verbs,
4741 alc880_pin_6stack_init_verbs },
b6482d48
TI
4742 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4743 .dac_nids = alc880_6st_dac_nids,
4744 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4745 .channel_mode = alc880_sixstack_modes,
4746 .input_mux = &alc880_6stack_capture_source,
4747 },
16ded525 4748 [ALC880_6ST_DIG] = {
e9edcee0 4749 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4750 .init_verbs = { alc880_volume_init_verbs,
4751 alc880_pin_6stack_init_verbs },
16ded525
TI
4752 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4753 .dac_nids = alc880_6st_dac_nids,
4754 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4755 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4756 .channel_mode = alc880_sixstack_modes,
4757 .input_mux = &alc880_6stack_capture_source,
4758 },
4759 [ALC880_W810] = {
e9edcee0 4760 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4761 .init_verbs = { alc880_volume_init_verbs,
4762 alc880_pin_w810_init_verbs,
b0af0de5 4763 alc880_gpio2_init_verbs },
16ded525
TI
4764 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4765 .dac_nids = alc880_w810_dac_nids,
4766 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4767 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4768 .channel_mode = alc880_w810_modes,
4769 .input_mux = &alc880_capture_source,
4770 },
4771 [ALC880_Z71V] = {
e9edcee0 4772 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4773 .init_verbs = { alc880_volume_init_verbs,
4774 alc880_pin_z71v_init_verbs },
16ded525
TI
4775 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4776 .dac_nids = alc880_z71v_dac_nids,
4777 .dig_out_nid = ALC880_DIGOUT_NID,
4778 .hp_nid = 0x03,
e9edcee0
TI
4779 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4780 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4781 .input_mux = &alc880_capture_source,
4782 },
4783 [ALC880_F1734] = {
e9edcee0 4784 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4785 .init_verbs = { alc880_volume_init_verbs,
4786 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4787 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4788 .dac_nids = alc880_f1734_dac_nids,
4789 .hp_nid = 0x02,
4790 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4791 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4792 .input_mux = &alc880_f1734_capture_source,
4793 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4794 .setup = alc880_uniwill_p53_setup,
4795 .init_hook = alc_automute_amp,
16ded525
TI
4796 },
4797 [ALC880_ASUS] = {
e9edcee0 4798 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4799 .init_verbs = { alc880_volume_init_verbs,
4800 alc880_pin_asus_init_verbs,
e9edcee0
TI
4801 alc880_gpio1_init_verbs },
4802 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4803 .dac_nids = alc880_asus_dac_nids,
4804 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4805 .channel_mode = alc880_asus_modes,
4e195a7b 4806 .need_dac_fix = 1,
16ded525
TI
4807 .input_mux = &alc880_capture_source,
4808 },
4809 [ALC880_ASUS_DIG] = {
e9edcee0 4810 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4811 .init_verbs = { alc880_volume_init_verbs,
4812 alc880_pin_asus_init_verbs,
e9edcee0
TI
4813 alc880_gpio1_init_verbs },
4814 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4815 .dac_nids = alc880_asus_dac_nids,
16ded525 4816 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4817 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4818 .channel_mode = alc880_asus_modes,
4e195a7b 4819 .need_dac_fix = 1,
16ded525
TI
4820 .input_mux = &alc880_capture_source,
4821 },
df694daa
KY
4822 [ALC880_ASUS_DIG2] = {
4823 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4824 .init_verbs = { alc880_volume_init_verbs,
4825 alc880_pin_asus_init_verbs,
df694daa
KY
4826 alc880_gpio2_init_verbs }, /* use GPIO2 */
4827 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4828 .dac_nids = alc880_asus_dac_nids,
4829 .dig_out_nid = ALC880_DIGOUT_NID,
4830 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4831 .channel_mode = alc880_asus_modes,
4e195a7b 4832 .need_dac_fix = 1,
df694daa
KY
4833 .input_mux = &alc880_capture_source,
4834 },
16ded525 4835 [ALC880_ASUS_W1V] = {
e9edcee0 4836 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4837 .init_verbs = { alc880_volume_init_verbs,
4838 alc880_pin_asus_init_verbs,
e9edcee0
TI
4839 alc880_gpio1_init_verbs },
4840 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4841 .dac_nids = alc880_asus_dac_nids,
16ded525 4842 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4843 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4844 .channel_mode = alc880_asus_modes,
4e195a7b 4845 .need_dac_fix = 1,
16ded525
TI
4846 .input_mux = &alc880_capture_source,
4847 },
4848 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4849 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4850 .init_verbs = { alc880_volume_init_verbs,
4851 alc880_pin_asus_init_verbs },
e9edcee0
TI
4852 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4853 .dac_nids = alc880_asus_dac_nids,
16ded525 4854 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4855 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4856 .channel_mode = alc880_asus_modes,
4e195a7b 4857 .need_dac_fix = 1,
16ded525
TI
4858 .input_mux = &alc880_capture_source,
4859 },
ccc656ce
KY
4860 [ALC880_UNIWILL] = {
4861 .mixers = { alc880_uniwill_mixer },
4862 .init_verbs = { alc880_volume_init_verbs,
4863 alc880_uniwill_init_verbs },
4864 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4865 .dac_nids = alc880_asus_dac_nids,
4866 .dig_out_nid = ALC880_DIGOUT_NID,
4867 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4868 .channel_mode = alc880_threestack_modes,
4869 .need_dac_fix = 1,
4870 .input_mux = &alc880_capture_source,
4871 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4872 .setup = alc880_uniwill_setup,
a9fd4f3f 4873 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4874 },
4875 [ALC880_UNIWILL_P53] = {
4876 .mixers = { alc880_uniwill_p53_mixer },
4877 .init_verbs = { alc880_volume_init_verbs,
4878 alc880_uniwill_p53_init_verbs },
4879 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4880 .dac_nids = alc880_asus_dac_nids,
4881 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4882 .channel_mode = alc880_threestack_modes,
4883 .input_mux = &alc880_capture_source,
4884 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4885 .setup = alc880_uniwill_p53_setup,
4886 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4887 },
4888 [ALC880_FUJITSU] = {
45bdd1c1 4889 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4890 .init_verbs = { alc880_volume_init_verbs,
4891 alc880_uniwill_p53_init_verbs,
4892 alc880_beep_init_verbs },
4893 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4894 .dac_nids = alc880_dac_nids,
d53d7d9e 4895 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4896 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4897 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4898 .input_mux = &alc880_capture_source,
4899 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4900 .setup = alc880_uniwill_p53_setup,
4901 .init_hook = alc_automute_amp,
ccc656ce 4902 },
df694daa
KY
4903 [ALC880_CLEVO] = {
4904 .mixers = { alc880_three_stack_mixer },
4905 .init_verbs = { alc880_volume_init_verbs,
4906 alc880_pin_clevo_init_verbs },
4907 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4908 .dac_nids = alc880_dac_nids,
4909 .hp_nid = 0x03,
4910 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4911 .channel_mode = alc880_threestack_modes,
4e195a7b 4912 .need_dac_fix = 1,
df694daa
KY
4913 .input_mux = &alc880_capture_source,
4914 },
ae6b813a
TI
4915 [ALC880_LG] = {
4916 .mixers = { alc880_lg_mixer },
4917 .init_verbs = { alc880_volume_init_verbs,
4918 alc880_lg_init_verbs },
4919 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4920 .dac_nids = alc880_lg_dac_nids,
4921 .dig_out_nid = ALC880_DIGOUT_NID,
4922 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4923 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4924 .need_dac_fix = 1,
ae6b813a 4925 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4926 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4927 .setup = alc880_lg_setup,
4928 .init_hook = alc_automute_amp,
cb53c626
TI
4929#ifdef CONFIG_SND_HDA_POWER_SAVE
4930 .loopbacks = alc880_lg_loopbacks,
4931#endif
ae6b813a 4932 },
d681518a
TI
4933 [ALC880_LG_LW] = {
4934 .mixers = { alc880_lg_lw_mixer },
4935 .init_verbs = { alc880_volume_init_verbs,
4936 alc880_lg_lw_init_verbs },
0a8c5da3 4937 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4938 .dac_nids = alc880_dac_nids,
4939 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4940 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4941 .channel_mode = alc880_lg_lw_modes,
d681518a 4942 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4943 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4944 .setup = alc880_lg_lw_setup,
4945 .init_hook = alc_automute_amp,
d681518a 4946 },
df99cd33
TI
4947 [ALC880_MEDION_RIM] = {
4948 .mixers = { alc880_medion_rim_mixer },
4949 .init_verbs = { alc880_volume_init_verbs,
4950 alc880_medion_rim_init_verbs,
4951 alc_gpio2_init_verbs },
4952 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4953 .dac_nids = alc880_dac_nids,
4954 .dig_out_nid = ALC880_DIGOUT_NID,
4955 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4956 .channel_mode = alc880_2_jack_modes,
4957 .input_mux = &alc880_medion_rim_capture_source,
4958 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4959 .setup = alc880_medion_rim_setup,
4960 .init_hook = alc880_medion_rim_automute,
df99cd33 4961 },
16ded525
TI
4962#ifdef CONFIG_SND_DEBUG
4963 [ALC880_TEST] = {
e9edcee0
TI
4964 .mixers = { alc880_test_mixer },
4965 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4966 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4967 .dac_nids = alc880_test_dac_nids,
4968 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4969 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4970 .channel_mode = alc880_test_modes,
4971 .input_mux = &alc880_test_capture_source,
4972 },
4973#endif
4974};
4975
e9edcee0
TI
4976/*
4977 * Automatic parse of I/O pins from the BIOS configuration
4978 */
4979
e9edcee0
TI
4980enum {
4981 ALC_CTL_WIDGET_VOL,
4982 ALC_CTL_WIDGET_MUTE,
4983 ALC_CTL_BIND_MUTE,
4984};
c8b6bf9b 4985static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4986 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4987 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4988 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4989};
4990
4991/* add dynamic controls */
f12ab1e0 4992static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 4993 int cidx, unsigned long val)
e9edcee0 4994{
c8b6bf9b 4995 struct snd_kcontrol_new *knew;
e9edcee0 4996
603c4019
TI
4997 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4998 knew = snd_array_new(&spec->kctls);
4999 if (!knew)
5000 return -ENOMEM;
e9edcee0 5001 *knew = alc880_control_templates[type];
543537bd 5002 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5003 if (!knew->name)
e9edcee0 5004 return -ENOMEM;
66ceeb6b 5005 knew->index = cidx;
4d02d1b6 5006 if (get_amp_nid_(val))
5e26dfd0 5007 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5008 knew->private_value = val;
e9edcee0
TI
5009 return 0;
5010}
5011
0afe5f89
TI
5012static int add_control_with_pfx(struct alc_spec *spec, int type,
5013 const char *pfx, const char *dir,
66ceeb6b 5014 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5015{
5016 char name[32];
5017 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5018 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5019}
5020
66ceeb6b
TI
5021#define add_pb_vol_ctrl(spec, type, pfx, val) \
5022 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5023#define add_pb_sw_ctrl(spec, type, pfx, val) \
5024 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5025#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5026 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5027#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5028 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5029
e9edcee0
TI
5030#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5031#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5032#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5033#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5034#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5035#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5036#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5037#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5038#define ALC880_PIN_CD_NID 0x1c
5039
5040/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5041static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5042 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5043{
5044 hda_nid_t nid;
5045 int assigned[4];
5046 int i, j;
5047
5048 memset(assigned, 0, sizeof(assigned));
b0af0de5 5049 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5050
5051 /* check the pins hardwired to audio widget */
5052 for (i = 0; i < cfg->line_outs; i++) {
5053 nid = cfg->line_out_pins[i];
5054 if (alc880_is_fixed_pin(nid)) {
5055 int idx = alc880_fixed_pin_idx(nid);
5014f193 5056 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5057 assigned[idx] = 1;
5058 }
5059 }
5060 /* left pins can be connect to any audio widget */
5061 for (i = 0; i < cfg->line_outs; i++) {
5062 nid = cfg->line_out_pins[i];
5063 if (alc880_is_fixed_pin(nid))
5064 continue;
5065 /* search for an empty channel */
5066 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
5067 if (!assigned[j]) {
5068 spec->multiout.dac_nids[i] =
5069 alc880_idx_to_dac(j);
e9edcee0
TI
5070 assigned[j] = 1;
5071 break;
5072 }
5073 }
5074 }
5075 spec->multiout.num_dacs = cfg->line_outs;
5076 return 0;
5077}
5078
bcb2f0f5
TI
5079static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5080 bool can_be_master)
5081{
5082 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5083 return "Master";
5084
5085 switch (cfg->line_out_type) {
5086 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5087 if (cfg->line_outs == 1)
5088 return "Speaker";
5089 break;
bcb2f0f5
TI
5090 case AUTO_PIN_HP_OUT:
5091 return "Headphone";
5092 default:
5093 if (cfg->line_outs == 1)
5094 return "PCM";
5095 break;
5096 }
5097 return NULL;
5098}
5099
e9edcee0 5100/* add playback controls from the parsed DAC table */
df694daa
KY
5101static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5102 const struct auto_pin_cfg *cfg)
e9edcee0 5103{
ea734963 5104 static const char * const chname[4] = {
f12ab1e0
TI
5105 "Front", "Surround", NULL /*CLFE*/, "Side"
5106 };
bcb2f0f5 5107 const char *pfx = alc_get_line_out_pfx(cfg, false);
e9edcee0
TI
5108 hda_nid_t nid;
5109 int i, err;
5110
5111 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 5112 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5113 continue;
5114 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5115 if (!pfx && i == 2) {
e9edcee0 5116 /* Center/LFE */
0afe5f89
TI
5117 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5118 "Center",
f12ab1e0
TI
5119 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5120 HDA_OUTPUT));
5121 if (err < 0)
e9edcee0 5122 return err;
0afe5f89
TI
5123 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5124 "LFE",
f12ab1e0
TI
5125 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5126 HDA_OUTPUT));
5127 if (err < 0)
e9edcee0 5128 return err;
0afe5f89
TI
5129 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5130 "Center",
f12ab1e0
TI
5131 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5132 HDA_INPUT));
5133 if (err < 0)
e9edcee0 5134 return err;
0afe5f89
TI
5135 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5136 "LFE",
f12ab1e0
TI
5137 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5138 HDA_INPUT));
5139 if (err < 0)
e9edcee0
TI
5140 return err;
5141 } else {
bcb2f0f5 5142 const char *name = pfx;
7e59e097
DH
5143 int index = i;
5144 if (!name) {
bcb2f0f5 5145 name = chname[i];
7e59e097
DH
5146 index = 0;
5147 }
bcb2f0f5 5148 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5149 name, index,
f12ab1e0
TI
5150 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5151 HDA_OUTPUT));
5152 if (err < 0)
e9edcee0 5153 return err;
bcb2f0f5 5154 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5155 name, index,
f12ab1e0
TI
5156 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5157 HDA_INPUT));
5158 if (err < 0)
e9edcee0
TI
5159 return err;
5160 }
5161 }
e9edcee0
TI
5162 return 0;
5163}
5164
8d88bc3d
TI
5165/* add playback controls for speaker and HP outputs */
5166static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5167 const char *pfx)
e9edcee0
TI
5168{
5169 hda_nid_t nid;
5170 int err;
5171
f12ab1e0 5172 if (!pin)
e9edcee0
TI
5173 return 0;
5174
5175 if (alc880_is_fixed_pin(pin)) {
5176 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5177 /* specify the DAC as the extra output */
f12ab1e0 5178 if (!spec->multiout.hp_nid)
e9edcee0 5179 spec->multiout.hp_nid = nid;
82bc955f
TI
5180 else
5181 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5182 /* control HP volume/switch on the output mixer amp */
5183 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5184 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5185 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5186 if (err < 0)
e9edcee0 5187 return err;
0afe5f89 5188 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5189 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5190 if (err < 0)
e9edcee0
TI
5191 return err;
5192 } else if (alc880_is_multi_pin(pin)) {
5193 /* set manual connection */
e9edcee0 5194 /* we have only a switch on HP-out PIN */
0afe5f89 5195 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5196 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5197 if (err < 0)
e9edcee0
TI
5198 return err;
5199 }
5200 return 0;
5201}
5202
5203/* create input playback/capture controls for the given pin */
f12ab1e0 5204static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5205 const char *ctlname, int ctlidx,
df694daa 5206 int idx, hda_nid_t mix_nid)
e9edcee0 5207{
df694daa 5208 int err;
e9edcee0 5209
66ceeb6b 5210 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5211 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5212 if (err < 0)
e9edcee0 5213 return err;
66ceeb6b 5214 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5215 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5216 if (err < 0)
e9edcee0
TI
5217 return err;
5218 return 0;
5219}
5220
05f5f477
TI
5221static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5222{
5223 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5224 return (pincap & AC_PINCAP_IN) != 0;
5225}
5226
e9edcee0 5227/* create playback/capture controls for input pins */
05f5f477
TI
5228static int alc_auto_create_input_ctls(struct hda_codec *codec,
5229 const struct auto_pin_cfg *cfg,
5230 hda_nid_t mixer,
5231 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5232{
05f5f477 5233 struct alc_spec *spec = codec->spec;
61b9b9b1 5234 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5235 int i, err, idx, type_idx = 0;
5236 const char *prev_label = NULL;
e9edcee0 5237
66ceeb6b 5238 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5239 hda_nid_t pin;
10a20af7 5240 const char *label;
05f5f477 5241
66ceeb6b 5242 pin = cfg->inputs[i].pin;
05f5f477
TI
5243 if (!alc_is_input_pin(codec, pin))
5244 continue;
5245
5322bf27
DH
5246 label = hda_get_autocfg_input_label(codec, cfg, i);
5247 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5248 type_idx++;
5249 else
5250 type_idx = 0;
5322bf27
DH
5251 prev_label = label;
5252
05f5f477
TI
5253 if (mixer) {
5254 idx = get_connection_index(codec, mixer, pin);
5255 if (idx >= 0) {
5256 err = new_analog_input(spec, pin,
10a20af7
TI
5257 label, type_idx,
5258 idx, mixer);
05f5f477
TI
5259 if (err < 0)
5260 return err;
5261 }
5262 }
5263
5264 if (!cap1)
5265 continue;
5266 idx = get_connection_index(codec, cap1, pin);
5267 if (idx < 0 && cap2)
5268 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5269 if (idx >= 0)
5270 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5271 }
5272 return 0;
5273}
5274
05f5f477
TI
5275static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5276 const struct auto_pin_cfg *cfg)
5277{
5278 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5279}
5280
f6c7e546
TI
5281static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5282 unsigned int pin_type)
5283{
5284 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5285 pin_type);
5286 /* unmute pin */
d260cdf6
TI
5287 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5288 AMP_OUT_UNMUTE);
f6c7e546
TI
5289}
5290
df694daa
KY
5291static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5292 hda_nid_t nid, int pin_type,
e9edcee0
TI
5293 int dac_idx)
5294{
f6c7e546 5295 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5296 /* need the manual connection? */
5297 if (alc880_is_multi_pin(nid)) {
5298 struct alc_spec *spec = codec->spec;
5299 int idx = alc880_multi_pin_idx(nid);
5300 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5301 AC_VERB_SET_CONNECT_SEL,
5302 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5303 }
5304}
5305
baba8ee9
TI
5306static int get_pin_type(int line_out_type)
5307{
5308 if (line_out_type == AUTO_PIN_HP_OUT)
5309 return PIN_HP;
5310 else
5311 return PIN_OUT;
5312}
5313
e9edcee0
TI
5314static void alc880_auto_init_multi_out(struct hda_codec *codec)
5315{
5316 struct alc_spec *spec = codec->spec;
5317 int i;
ea1fb29a 5318
e9edcee0
TI
5319 for (i = 0; i < spec->autocfg.line_outs; i++) {
5320 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5321 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5322 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5323 }
5324}
5325
8d88bc3d 5326static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5327{
5328 struct alc_spec *spec = codec->spec;
5329 hda_nid_t pin;
5330
82bc955f 5331 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5332 if (pin) /* connect to front */
5333 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5334 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5335 if (pin) /* connect to front */
5336 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5337}
5338
5339static void alc880_auto_init_analog_input(struct hda_codec *codec)
5340{
5341 struct alc_spec *spec = codec->spec;
66ceeb6b 5342 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5343 int i;
5344
66ceeb6b
TI
5345 for (i = 0; i < cfg->num_inputs; i++) {
5346 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5347 if (alc_is_input_pin(codec, nid)) {
30ea098f 5348 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5349 if (nid != ALC880_PIN_CD_NID &&
5350 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5351 snd_hda_codec_write(codec, nid, 0,
5352 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5353 AMP_OUT_MUTE);
5354 }
5355 }
5356}
5357
7f311a46
TI
5358static void alc880_auto_init_input_src(struct hda_codec *codec)
5359{
5360 struct alc_spec *spec = codec->spec;
5361 int c;
5362
5363 for (c = 0; c < spec->num_adc_nids; c++) {
5364 unsigned int mux_idx;
5365 const struct hda_input_mux *imux;
5366 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5367 imux = &spec->input_mux[mux_idx];
5368 if (!imux->num_items && mux_idx > 0)
5369 imux = &spec->input_mux[0];
5370 if (imux)
5371 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5372 AC_VERB_SET_CONNECT_SEL,
5373 imux->items[0].index);
5374 }
5375}
5376
e9edcee0 5377/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5378/* return 1 if successful, 0 if the proper config is not found,
5379 * or a negative error code
5380 */
e9edcee0
TI
5381static int alc880_parse_auto_config(struct hda_codec *codec)
5382{
5383 struct alc_spec *spec = codec->spec;
757899ac 5384 int err;
df694daa 5385 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5386
f12ab1e0
TI
5387 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5388 alc880_ignore);
5389 if (err < 0)
e9edcee0 5390 return err;
f12ab1e0 5391 if (!spec->autocfg.line_outs)
e9edcee0 5392 return 0; /* can't find valid BIOS pin config */
df694daa 5393
f12ab1e0
TI
5394 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5395 if (err < 0)
5396 return err;
5397 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5398 if (err < 0)
5399 return err;
5400 err = alc880_auto_create_extra_out(spec,
5401 spec->autocfg.speaker_pins[0],
5402 "Speaker");
5403 if (err < 0)
5404 return err;
5405 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5406 "Headphone");
5407 if (err < 0)
5408 return err;
05f5f477 5409 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5410 if (err < 0)
e9edcee0
TI
5411 return err;
5412
5413 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5414
757899ac 5415 alc_auto_parse_digital(codec);
e9edcee0 5416
603c4019 5417 if (spec->kctls.list)
d88897ea 5418 add_mixer(spec, spec->kctls.list);
e9edcee0 5419
d88897ea 5420 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5421
a1e8d2da 5422 spec->num_mux_defs = 1;
61b9b9b1 5423 spec->input_mux = &spec->private_imux[0];
e9edcee0 5424
6227cdce 5425 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5426
e9edcee0
TI
5427 return 1;
5428}
5429
ae6b813a
TI
5430/* additional initialization for auto-configuration model */
5431static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5432{
f6c7e546 5433 struct alc_spec *spec = codec->spec;
e9edcee0 5434 alc880_auto_init_multi_out(codec);
8d88bc3d 5435 alc880_auto_init_extra_out(codec);
e9edcee0 5436 alc880_auto_init_analog_input(codec);
7f311a46 5437 alc880_auto_init_input_src(codec);
757899ac 5438 alc_auto_init_digital(codec);
f6c7e546 5439 if (spec->unsol_event)
7fb0d78f 5440 alc_inithook(codec);
e9edcee0
TI
5441}
5442
b59bdf3b
TI
5443/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5444 * one of two digital mic pins, e.g. on ALC272
5445 */
5446static void fixup_automic_adc(struct hda_codec *codec)
5447{
5448 struct alc_spec *spec = codec->spec;
5449 int i;
5450
5451 for (i = 0; i < spec->num_adc_nids; i++) {
5452 hda_nid_t cap = spec->capsrc_nids ?
5453 spec->capsrc_nids[i] : spec->adc_nids[i];
5454 int iidx, eidx;
5455
5456 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5457 if (iidx < 0)
5458 continue;
5459 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5460 if (eidx < 0)
5461 continue;
5462 spec->int_mic.mux_idx = iidx;
5463 spec->ext_mic.mux_idx = eidx;
5464 if (spec->capsrc_nids)
5465 spec->capsrc_nids += i;
5466 spec->adc_nids += i;
5467 spec->num_adc_nids = 1;
5468 return;
5469 }
5470 snd_printd(KERN_INFO "hda_codec: %s: "
5471 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5472 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5473 spec->auto_mic = 0; /* disable auto-mic to be sure */
5474}
5475
748cce43
TI
5476/* select or unmute the given capsrc route */
5477static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5478 int idx)
5479{
5480 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5481 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5482 HDA_AMP_MUTE, 0);
5483 } else {
5484 snd_hda_codec_write_cache(codec, cap, 0,
5485 AC_VERB_SET_CONNECT_SEL, idx);
5486 }
5487}
5488
840b64c0
TI
5489/* set the default connection to that pin */
5490static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5491{
5492 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5493 int i;
5494
eaa9b3a7
TI
5495 for (i = 0; i < spec->num_adc_nids; i++) {
5496 hda_nid_t cap = spec->capsrc_nids ?
5497 spec->capsrc_nids[i] : spec->adc_nids[i];
5498 int idx;
5499
5500 idx = get_connection_index(codec, cap, pin);
5501 if (idx < 0)
5502 continue;
748cce43 5503 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5504 return i; /* return the found index */
5505 }
5506 return -1; /* not found */
5507}
5508
5509/* choose the ADC/MUX containing the input pin and initialize the setup */
5510static void fixup_single_adc(struct hda_codec *codec)
5511{
5512 struct alc_spec *spec = codec->spec;
66ceeb6b 5513 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5514 int i;
5515
5516 /* search for the input pin; there must be only one */
66ceeb6b 5517 if (cfg->num_inputs != 1)
eaa9b3a7 5518 return;
66ceeb6b 5519 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5520 if (i >= 0) {
5521 /* use only this ADC */
5522 if (spec->capsrc_nids)
5523 spec->capsrc_nids += i;
5524 spec->adc_nids += i;
5525 spec->num_adc_nids = 1;
584c0c4c 5526 spec->single_input_src = 1;
eaa9b3a7
TI
5527 }
5528}
5529
840b64c0
TI
5530/* initialize dual adcs */
5531static void fixup_dual_adc_switch(struct hda_codec *codec)
5532{
5533 struct alc_spec *spec = codec->spec;
5534 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5535 init_capsrc_for_pin(codec, spec->int_mic.pin);
5536}
5537
584c0c4c
TI
5538/* initialize some special cases for input sources */
5539static void alc_init_special_input_src(struct hda_codec *codec)
5540{
5541 struct alc_spec *spec = codec->spec;
5542 if (spec->dual_adc_switch)
5543 fixup_dual_adc_switch(codec);
5544 else if (spec->single_input_src)
5545 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5546}
5547
b59bdf3b 5548static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5549{
b59bdf3b 5550 struct alc_spec *spec = codec->spec;
a23b688f
TI
5551 static struct snd_kcontrol_new *caps[2][3] = {
5552 { alc_capture_mixer_nosrc1,
5553 alc_capture_mixer_nosrc2,
5554 alc_capture_mixer_nosrc3 },
5555 { alc_capture_mixer1,
5556 alc_capture_mixer2,
5557 alc_capture_mixer3 },
f9e336f6 5558 };
a23b688f 5559 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5560 int mux = 0;
840b64c0
TI
5561 int num_adcs = spec->num_adc_nids;
5562 if (spec->dual_adc_switch)
584c0c4c 5563 num_adcs = 1;
840b64c0 5564 else if (spec->auto_mic)
b59bdf3b 5565 fixup_automic_adc(codec);
eaa9b3a7
TI
5566 else if (spec->input_mux) {
5567 if (spec->input_mux->num_items > 1)
5568 mux = 1;
5569 else if (spec->input_mux->num_items == 1)
5570 fixup_single_adc(codec);
5571 }
840b64c0 5572 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5573 }
f9e336f6
TI
5574}
5575
6694635d
TI
5576/* fill adc_nids (and capsrc_nids) containing all active input pins */
5577static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5578 int num_nids)
5579{
5580 struct alc_spec *spec = codec->spec;
66ceeb6b 5581 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5582 int n;
5583 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5584
5585 for (n = 0; n < num_nids; n++) {
5586 hda_nid_t adc, cap;
5587 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5588 int nconns, i, j;
5589
5590 adc = nids[n];
5591 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5592 continue;
5593 cap = adc;
5594 nconns = snd_hda_get_connections(codec, cap, conn,
5595 ARRAY_SIZE(conn));
5596 if (nconns == 1) {
5597 cap = conn[0];
5598 nconns = snd_hda_get_connections(codec, cap, conn,
5599 ARRAY_SIZE(conn));
5600 }
5601 if (nconns <= 0)
5602 continue;
5603 if (!fallback_adc) {
5604 fallback_adc = adc;
5605 fallback_cap = cap;
5606 }
66ceeb6b
TI
5607 for (i = 0; i < cfg->num_inputs; i++) {
5608 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5609 for (j = 0; j < nconns; j++) {
5610 if (conn[j] == nid)
5611 break;
5612 }
5613 if (j >= nconns)
5614 break;
5615 }
66ceeb6b 5616 if (i >= cfg->num_inputs) {
6694635d
TI
5617 int num_adcs = spec->num_adc_nids;
5618 spec->private_adc_nids[num_adcs] = adc;
5619 spec->private_capsrc_nids[num_adcs] = cap;
5620 spec->num_adc_nids++;
5621 spec->adc_nids = spec->private_adc_nids;
5622 if (adc != cap)
5623 spec->capsrc_nids = spec->private_capsrc_nids;
5624 }
5625 }
5626 if (!spec->num_adc_nids) {
5627 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5628 " using fallback 0x%x\n",
5629 codec->chip_name, fallback_adc);
6694635d
TI
5630 spec->private_adc_nids[0] = fallback_adc;
5631 spec->adc_nids = spec->private_adc_nids;
5632 if (fallback_adc != fallback_cap) {
5633 spec->private_capsrc_nids[0] = fallback_cap;
5634 spec->capsrc_nids = spec->private_adc_nids;
5635 }
5636 }
5637}
5638
67d634c0 5639#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5640#define set_beep_amp(spec, nid, idx, dir) \
5641 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5642
5643static struct snd_pci_quirk beep_white_list[] = {
5644 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5645 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5646 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5647 {}
5648};
5649
5650static inline int has_cdefine_beep(struct hda_codec *codec)
5651{
5652 struct alc_spec *spec = codec->spec;
5653 const struct snd_pci_quirk *q;
5654 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5655 if (q)
5656 return q->value;
5657 return spec->cdefine.enable_pcbeep;
5658}
67d634c0
TI
5659#else
5660#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5661#define has_cdefine_beep(codec) 0
67d634c0 5662#endif
45bdd1c1
TI
5663
5664/*
5665 * OK, here we have finally the patch for ALC880
5666 */
5667
1da177e4
LT
5668static int patch_alc880(struct hda_codec *codec)
5669{
5670 struct alc_spec *spec;
5671 int board_config;
df694daa 5672 int err;
1da177e4 5673
e560d8d8 5674 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5675 if (spec == NULL)
5676 return -ENOMEM;
5677
5678 codec->spec = spec;
5679
f5fcc13c
TI
5680 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5681 alc880_models,
5682 alc880_cfg_tbl);
5683 if (board_config < 0) {
9a11f1aa
TI
5684 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5685 codec->chip_name);
e9edcee0 5686 board_config = ALC880_AUTO;
1da177e4 5687 }
1da177e4 5688
e9edcee0
TI
5689 if (board_config == ALC880_AUTO) {
5690 /* automatic parse from the BIOS config */
5691 err = alc880_parse_auto_config(codec);
5692 if (err < 0) {
5693 alc_free(codec);
5694 return err;
f12ab1e0 5695 } else if (!err) {
9c7f852e
TI
5696 printk(KERN_INFO
5697 "hda_codec: Cannot set up configuration "
5698 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5699 board_config = ALC880_3ST;
5700 }
1da177e4
LT
5701 }
5702
680cd536
KK
5703 err = snd_hda_attach_beep_device(codec, 0x1);
5704 if (err < 0) {
5705 alc_free(codec);
5706 return err;
5707 }
5708
df694daa 5709 if (board_config != ALC880_AUTO)
e9c364c0 5710 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5711
1da177e4
LT
5712 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5713 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5714 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5715
1da177e4
LT
5716 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5717 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5718
f12ab1e0 5719 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5720 /* check whether NID 0x07 is valid */
54d17403 5721 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5722 /* get type */
a22d543a 5723 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5724 if (wcap != AC_WID_AUD_IN) {
5725 spec->adc_nids = alc880_adc_nids_alt;
5726 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5727 } else {
5728 spec->adc_nids = alc880_adc_nids;
5729 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5730 }
5731 }
b59bdf3b 5732 set_capture_mixer(codec);
45bdd1c1 5733 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5734
2134ea4f
TI
5735 spec->vmaster_nid = 0x0c;
5736
1da177e4 5737 codec->patch_ops = alc_patch_ops;
e9edcee0 5738 if (board_config == ALC880_AUTO)
ae6b813a 5739 spec->init_hook = alc880_auto_init;
cb53c626
TI
5740#ifdef CONFIG_SND_HDA_POWER_SAVE
5741 if (!spec->loopback.amplist)
5742 spec->loopback.amplist = alc880_loopbacks;
5743#endif
1da177e4
LT
5744
5745 return 0;
5746}
5747
e9edcee0 5748
1da177e4
LT
5749/*
5750 * ALC260 support
5751 */
5752
e9edcee0
TI
5753static hda_nid_t alc260_dac_nids[1] = {
5754 /* front */
5755 0x02,
5756};
5757
5758static hda_nid_t alc260_adc_nids[1] = {
5759 /* ADC0 */
5760 0x04,
5761};
5762
df694daa 5763static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5764 /* ADC1 */
5765 0x05,
5766};
5767
d57fdac0
JW
5768/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5769 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5770 */
5771static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5772 /* ADC0, ADC1 */
5773 0x04, 0x05
5774};
5775
e9edcee0
TI
5776#define ALC260_DIGOUT_NID 0x03
5777#define ALC260_DIGIN_NID 0x06
5778
5779static struct hda_input_mux alc260_capture_source = {
5780 .num_items = 4,
5781 .items = {
5782 { "Mic", 0x0 },
5783 { "Front Mic", 0x1 },
5784 { "Line", 0x2 },
5785 { "CD", 0x4 },
5786 },
5787};
5788
17e7aec6 5789/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5790 * headphone jack and the internal CD lines since these are the only pins at
5791 * which audio can appear. For flexibility, also allow the option of
5792 * recording the mixer output on the second ADC (ADC0 doesn't have a
5793 * connection to the mixer output).
a9430dd8 5794 */
a1e8d2da
JW
5795static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5796 {
5797 .num_items = 3,
5798 .items = {
5799 { "Mic/Line", 0x0 },
5800 { "CD", 0x4 },
5801 { "Headphone", 0x2 },
5802 },
a9430dd8 5803 },
a1e8d2da
JW
5804 {
5805 .num_items = 4,
5806 .items = {
5807 { "Mic/Line", 0x0 },
5808 { "CD", 0x4 },
5809 { "Headphone", 0x2 },
5810 { "Mixer", 0x5 },
5811 },
5812 },
5813
a9430dd8
JW
5814};
5815
a1e8d2da
JW
5816/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5817 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5818 */
a1e8d2da
JW
5819static struct hda_input_mux alc260_acer_capture_sources[2] = {
5820 {
5821 .num_items = 4,
5822 .items = {
5823 { "Mic", 0x0 },
5824 { "Line", 0x2 },
5825 { "CD", 0x4 },
5826 { "Headphone", 0x5 },
5827 },
5828 },
5829 {
5830 .num_items = 5,
5831 .items = {
5832 { "Mic", 0x0 },
5833 { "Line", 0x2 },
5834 { "CD", 0x4 },
5835 { "Headphone", 0x6 },
5836 { "Mixer", 0x5 },
5837 },
0bfc90e9
JW
5838 },
5839};
cc959489
MS
5840
5841/* Maxdata Favorit 100XS */
5842static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5843 {
5844 .num_items = 2,
5845 .items = {
5846 { "Line/Mic", 0x0 },
5847 { "CD", 0x4 },
5848 },
5849 },
5850 {
5851 .num_items = 3,
5852 .items = {
5853 { "Line/Mic", 0x0 },
5854 { "CD", 0x4 },
5855 { "Mixer", 0x5 },
5856 },
5857 },
5858};
5859
1da177e4
LT
5860/*
5861 * This is just place-holder, so there's something for alc_build_pcms to look
5862 * at when it calculates the maximum number of channels. ALC260 has no mixer
5863 * element which allows changing the channel mode, so the verb list is
5864 * never used.
5865 */
d2a6d7dc 5866static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5867 { 2, NULL },
5868};
5869
df694daa
KY
5870
5871/* Mixer combinations
5872 *
5873 * basic: base_output + input + pc_beep + capture
5874 * HP: base_output + input + capture_alt
5875 * HP_3013: hp_3013 + input + capture
5876 * fujitsu: fujitsu + capture
0bfc90e9 5877 * acer: acer + capture
df694daa
KY
5878 */
5879
5880static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5881 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5882 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5883 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5884 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5885 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5886 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5887 { } /* end */
f12ab1e0 5888};
1da177e4 5889
df694daa 5890static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5891 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5892 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5893 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5894 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5896 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5897 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5898 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5899 { } /* end */
5900};
5901
bec15c3a
TI
5902/* update HP, line and mono out pins according to the master switch */
5903static void alc260_hp_master_update(struct hda_codec *codec,
5904 hda_nid_t hp, hda_nid_t line,
5905 hda_nid_t mono)
5906{
5907 struct alc_spec *spec = codec->spec;
5908 unsigned int val = spec->master_sw ? PIN_HP : 0;
5909 /* change HP and line-out pins */
30cde0aa 5910 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5911 val);
30cde0aa 5912 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5913 val);
5914 /* mono (speaker) depending on the HP jack sense */
5915 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5916 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5917 val);
5918}
5919
5920static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5921 struct snd_ctl_elem_value *ucontrol)
5922{
5923 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5924 struct alc_spec *spec = codec->spec;
5925 *ucontrol->value.integer.value = spec->master_sw;
5926 return 0;
5927}
5928
5929static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5930 struct snd_ctl_elem_value *ucontrol)
5931{
5932 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5933 struct alc_spec *spec = codec->spec;
5934 int val = !!*ucontrol->value.integer.value;
5935 hda_nid_t hp, line, mono;
5936
5937 if (val == spec->master_sw)
5938 return 0;
5939 spec->master_sw = val;
5940 hp = (kcontrol->private_value >> 16) & 0xff;
5941 line = (kcontrol->private_value >> 8) & 0xff;
5942 mono = kcontrol->private_value & 0xff;
5943 alc260_hp_master_update(codec, hp, line, mono);
5944 return 1;
5945}
5946
5947static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5948 {
5949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5950 .name = "Master Playback Switch",
5b0cb1d8 5951 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5952 .info = snd_ctl_boolean_mono_info,
5953 .get = alc260_hp_master_sw_get,
5954 .put = alc260_hp_master_sw_put,
5955 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5956 },
5957 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5958 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5959 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5960 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5961 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5962 HDA_OUTPUT),
5963 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5964 { } /* end */
5965};
5966
5967static struct hda_verb alc260_hp_unsol_verbs[] = {
5968 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5969 {},
5970};
5971
5972static void alc260_hp_automute(struct hda_codec *codec)
5973{
5974 struct alc_spec *spec = codec->spec;
bec15c3a 5975
864f92be 5976 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5977 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5978}
5979
5980static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5981{
5982 if ((res >> 26) == ALC880_HP_EVENT)
5983 alc260_hp_automute(codec);
5984}
5985
df694daa 5986static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5987 {
5988 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5989 .name = "Master Playback Switch",
5b0cb1d8 5990 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5991 .info = snd_ctl_boolean_mono_info,
5992 .get = alc260_hp_master_sw_get,
5993 .put = alc260_hp_master_sw_put,
30cde0aa 5994 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5995 },
df694daa
KY
5996 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5997 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5998 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5999 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6000 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6001 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6002 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6003 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6004 { } /* end */
6005};
6006
3f878308
KY
6007static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6008 .ops = &snd_hda_bind_vol,
6009 .values = {
6010 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6011 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6012 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6013 0
6014 },
6015};
6016
6017static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6018 .ops = &snd_hda_bind_sw,
6019 .values = {
6020 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6021 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6022 0
6023 },
6024};
6025
6026static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6027 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6028 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6029 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6030 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6031 { } /* end */
6032};
6033
bec15c3a
TI
6034static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6035 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6036 {},
6037};
6038
6039static void alc260_hp_3013_automute(struct hda_codec *codec)
6040{
6041 struct alc_spec *spec = codec->spec;
bec15c3a 6042
864f92be 6043 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 6044 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
6045}
6046
6047static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6048 unsigned int res)
6049{
6050 if ((res >> 26) == ALC880_HP_EVENT)
6051 alc260_hp_3013_automute(codec);
6052}
6053
3f878308
KY
6054static void alc260_hp_3012_automute(struct hda_codec *codec)
6055{
864f92be 6056 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 6057
3f878308
KY
6058 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6059 bits);
6060 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6061 bits);
6062 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6063 bits);
6064}
6065
6066static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6067 unsigned int res)
6068{
6069 if ((res >> 26) == ALC880_HP_EVENT)
6070 alc260_hp_3012_automute(codec);
6071}
6072
6073/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6074 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6075 */
c8b6bf9b 6076static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6077 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6078 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6079 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6080 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6081 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6082 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6083 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6084 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6085 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6086 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6087 { } /* end */
6088};
6089
a1e8d2da
JW
6090/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6091 * versions of the ALC260 don't act on requests to enable mic bias from NID
6092 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6093 * datasheet doesn't mention this restriction. At this stage it's not clear
6094 * whether this behaviour is intentional or is a hardware bug in chip
6095 * revisions available in early 2006. Therefore for now allow the
6096 * "Headphone Jack Mode" control to span all choices, but if it turns out
6097 * that the lack of mic bias for this NID is intentional we could change the
6098 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6099 *
6100 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6101 * don't appear to make the mic bias available from the "line" jack, even
6102 * though the NID used for this jack (0x14) can supply it. The theory is
6103 * that perhaps Acer have included blocking capacitors between the ALC260
6104 * and the output jack. If this turns out to be the case for all such
6105 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6106 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6107 *
6108 * The C20x Tablet series have a mono internal speaker which is controlled
6109 * via the chip's Mono sum widget and pin complex, so include the necessary
6110 * controls for such models. On models without a "mono speaker" the control
6111 * won't do anything.
a1e8d2da 6112 */
0bfc90e9
JW
6113static struct snd_kcontrol_new alc260_acer_mixer[] = {
6114 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6115 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6116 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6117 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6118 HDA_OUTPUT),
31bffaa9 6119 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6120 HDA_INPUT),
0bfc90e9
JW
6121 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6122 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6123 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6124 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6125 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6126 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6127 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6128 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6129 { } /* end */
6130};
6131
cc959489
MS
6132/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6133 */
6134static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6135 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6136 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6137 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6138 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6139 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6140 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6141 { } /* end */
6142};
6143
bc9f98a9
KY
6144/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6145 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6146 */
6147static struct snd_kcontrol_new alc260_will_mixer[] = {
6148 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6149 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6150 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6151 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6152 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6153 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6154 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6155 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6156 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6157 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6158 { } /* end */
6159};
6160
6161/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6162 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6163 */
6164static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6165 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6166 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6168 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6169 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6170 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6171 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6172 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6173 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6174 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6175 { } /* end */
6176};
6177
df694daa
KY
6178/*
6179 * initialization verbs
6180 */
1da177e4
LT
6181static struct hda_verb alc260_init_verbs[] = {
6182 /* Line In pin widget for input */
05acb863 6183 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6184 /* CD pin widget for input */
05acb863 6185 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6186 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6187 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6188 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6189 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6190 /* LINE-2 is used for line-out in rear */
05acb863 6191 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6192 /* select line-out */
fd56f2db 6193 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6194 /* LINE-OUT pin */
05acb863 6195 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6196 /* enable HP */
05acb863 6197 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6198 /* enable Mono */
05acb863
TI
6199 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6200 /* mute capture amp left and right */
16ded525 6201 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6202 /* set connection select to line in (default select for this ADC) */
6203 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6204 /* mute capture amp left and right */
6205 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6206 /* set connection select to line in (default select for this ADC) */
6207 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6208 /* set vol=0 Line-Out mixer amp left and right */
6209 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6210 /* unmute pin widget amp left and right (no gain on this amp) */
6211 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6212 /* set vol=0 HP mixer amp left and right */
6213 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6214 /* unmute pin widget amp left and right (no gain on this amp) */
6215 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6216 /* set vol=0 Mono mixer amp left and right */
6217 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6218 /* unmute pin widget amp left and right (no gain on this amp) */
6219 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6220 /* unmute LINE-2 out pin */
6221 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6222 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6223 * Line In 2 = 0x03
6224 */
cb53c626
TI
6225 /* mute analog inputs */
6226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6229 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6231 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6232 /* mute Front out path */
6233 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6234 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6235 /* mute Headphone out path */
6236 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6237 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6238 /* mute Mono out path */
6239 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6240 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6241 { }
6242};
6243
474167d6 6244#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6245static struct hda_verb alc260_hp_init_verbs[] = {
6246 /* Headphone and output */
6247 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6248 /* mono output */
6249 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6250 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6251 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6252 /* Mic2 (front panel) pin widget for input and vref at 80% */
6253 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6254 /* Line In pin widget for input */
6255 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6256 /* Line-2 pin widget for output */
6257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6258 /* CD pin widget for input */
6259 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6260 /* unmute amp left and right */
6261 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6262 /* set connection select to line in (default select for this ADC) */
6263 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6264 /* unmute Line-Out mixer amp left and right (volume = 0) */
6265 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6266 /* mute pin widget amp left and right (no gain on this amp) */
6267 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6268 /* unmute HP mixer amp left and right (volume = 0) */
6269 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6270 /* mute pin widget amp left and right (no gain on this amp) */
6271 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6272 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6273 * Line In 2 = 0x03
6274 */
cb53c626
TI
6275 /* mute analog inputs */
6276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6281 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6282 /* Unmute Front out path */
6283 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6284 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6285 /* Unmute Headphone out path */
6286 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6287 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6288 /* Unmute Mono out path */
6289 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6290 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6291 { }
6292};
474167d6 6293#endif
df694daa
KY
6294
6295static struct hda_verb alc260_hp_3013_init_verbs[] = {
6296 /* Line out and output */
6297 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6298 /* mono output */
6299 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6300 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6301 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6302 /* Mic2 (front panel) pin widget for input and vref at 80% */
6303 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6304 /* Line In pin widget for input */
6305 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6306 /* Headphone pin widget for output */
6307 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6308 /* CD pin widget for input */
6309 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6310 /* unmute amp left and right */
6311 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6312 /* set connection select to line in (default select for this ADC) */
6313 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6314 /* unmute Line-Out mixer amp left and right (volume = 0) */
6315 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6316 /* mute pin widget amp left and right (no gain on this amp) */
6317 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6318 /* unmute HP mixer amp left and right (volume = 0) */
6319 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6320 /* mute pin widget amp left and right (no gain on this amp) */
6321 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6322 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6323 * Line In 2 = 0x03
6324 */
cb53c626
TI
6325 /* mute analog inputs */
6326 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6327 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6328 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6331 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6332 /* Unmute Front out path */
6333 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6334 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6335 /* Unmute Headphone out path */
6336 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6337 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6338 /* Unmute Mono out path */
6339 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6340 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6341 { }
6342};
6343
a9430dd8 6344/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6345 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6346 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6347 */
6348static struct hda_verb alc260_fujitsu_init_verbs[] = {
6349 /* Disable all GPIOs */
6350 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6351 /* Internal speaker is connected to headphone pin */
6352 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6353 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6355 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6356 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6357 /* Ensure all other unused pins are disabled and muted. */
6358 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6359 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6360 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6361 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6362 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6363 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6366
6367 /* Disable digital (SPDIF) pins */
6368 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6369 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6370
ea1fb29a 6371 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6372 * when acting as an output.
6373 */
6374 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6375
f7ace40d 6376 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6377 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6378 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6379 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6380 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6381 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6382 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6383 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6384 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6385 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6386
f7ace40d
JW
6387 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6388 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6389 /* Unmute Line1 pin widget output buffer since it starts as an output.
6390 * If the pin mode is changed by the user the pin mode control will
6391 * take care of enabling the pin's input/output buffers as needed.
6392 * Therefore there's no need to enable the input buffer at this
6393 * stage.
cdcd9268 6394 */
f7ace40d 6395 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6396 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6397 * mixer ctrl)
6398 */
f7ace40d
JW
6399 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6400
6401 /* Mute capture amp left and right */
6402 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6403 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6404 * in (on mic1 pin)
6405 */
6406 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6407
6408 /* Do the same for the second ADC: mute capture input amp and
6409 * set ADC connection to line in (on mic1 pin)
6410 */
6411 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6412 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6413
6414 /* Mute all inputs to mixer widget (even unconnected ones) */
6415 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6416 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6418 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6419 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6420 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6421 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6422 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6423
6424 { }
a9430dd8
JW
6425};
6426
0bfc90e9
JW
6427/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6428 * similar laptops (adapted from Fujitsu init verbs).
6429 */
6430static struct hda_verb alc260_acer_init_verbs[] = {
6431 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6432 * the headphone jack. Turn this on and rely on the standard mute
6433 * methods whenever the user wants to turn these outputs off.
6434 */
6435 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6436 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6437 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6438 /* Internal speaker/Headphone jack is connected to Line-out pin */
6439 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6440 /* Internal microphone/Mic jack is connected to Mic1 pin */
6441 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6442 /* Line In jack is connected to Line1 pin */
6443 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6444 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6445 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6446 /* Ensure all other unused pins are disabled and muted. */
6447 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6448 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6449 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6450 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6451 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6453 /* Disable digital (SPDIF) pins */
6454 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6455 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6456
ea1fb29a 6457 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6458 * bus when acting as outputs.
6459 */
6460 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6461 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6462
6463 /* Start with output sum widgets muted and their output gains at min */
6464 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6465 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6466 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6467 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6468 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6469 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6470 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6471 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6472 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6473
f12ab1e0
TI
6474 /* Unmute Line-out pin widget amp left and right
6475 * (no equiv mixer ctrl)
6476 */
0bfc90e9 6477 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6478 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6479 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6480 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6481 * inputs. If the pin mode is changed by the user the pin mode control
6482 * will take care of enabling the pin's input/output buffers as needed.
6483 * Therefore there's no need to enable the input buffer at this
6484 * stage.
6485 */
6486 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6487 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6488
6489 /* Mute capture amp left and right */
6490 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6491 /* Set ADC connection select to match default mixer setting - mic
6492 * (on mic1 pin)
6493 */
6494 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6495
6496 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6497 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6498 */
6499 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6500 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6501
6502 /* Mute all inputs to mixer widget (even unconnected ones) */
6503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6505 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6506 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6508 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6510 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6511
6512 { }
6513};
6514
cc959489
MS
6515/* Initialisation sequence for Maxdata Favorit 100XS
6516 * (adapted from Acer init verbs).
6517 */
6518static struct hda_verb alc260_favorit100_init_verbs[] = {
6519 /* GPIO 0 enables the output jack.
6520 * Turn this on and rely on the standard mute
6521 * methods whenever the user wants to turn these outputs off.
6522 */
6523 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6524 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6525 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6526 /* Line/Mic input jack is connected to Mic1 pin */
6527 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6528 /* Ensure all other unused pins are disabled and muted. */
6529 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6530 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6531 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6532 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6533 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6534 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6536 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6537 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6539 /* Disable digital (SPDIF) pins */
6540 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6541 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6542
6543 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6544 * bus when acting as outputs.
6545 */
6546 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6547 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6548
6549 /* Start with output sum widgets muted and their output gains at min */
6550 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6551 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6552 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6553 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6554 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6555 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6556 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6557 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6558 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6559
6560 /* Unmute Line-out pin widget amp left and right
6561 * (no equiv mixer ctrl)
6562 */
6563 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6564 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6565 * inputs. If the pin mode is changed by the user the pin mode control
6566 * will take care of enabling the pin's input/output buffers as needed.
6567 * Therefore there's no need to enable the input buffer at this
6568 * stage.
6569 */
6570 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6571
6572 /* Mute capture amp left and right */
6573 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6574 /* Set ADC connection select to match default mixer setting - mic
6575 * (on mic1 pin)
6576 */
6577 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6578
6579 /* Do similar with the second ADC: mute capture input amp and
6580 * set ADC connection to mic to match ALSA's default state.
6581 */
6582 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6583 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6584
6585 /* Mute all inputs to mixer widget (even unconnected ones) */
6586 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6587 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6589 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6593 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6594
6595 { }
6596};
6597
bc9f98a9
KY
6598static struct hda_verb alc260_will_verbs[] = {
6599 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6600 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6601 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6602 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6603 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6604 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6605 {}
6606};
6607
6608static struct hda_verb alc260_replacer_672v_verbs[] = {
6609 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6610 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6611 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6612
6613 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6614 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6615 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6616
6617 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6618 {}
6619};
6620
6621/* toggle speaker-output according to the hp-jack state */
6622static void alc260_replacer_672v_automute(struct hda_codec *codec)
6623{
6624 unsigned int present;
6625
6626 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6627 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6628 if (present) {
82beb8fd
TI
6629 snd_hda_codec_write_cache(codec, 0x01, 0,
6630 AC_VERB_SET_GPIO_DATA, 1);
6631 snd_hda_codec_write_cache(codec, 0x0f, 0,
6632 AC_VERB_SET_PIN_WIDGET_CONTROL,
6633 PIN_HP);
bc9f98a9 6634 } else {
82beb8fd
TI
6635 snd_hda_codec_write_cache(codec, 0x01, 0,
6636 AC_VERB_SET_GPIO_DATA, 0);
6637 snd_hda_codec_write_cache(codec, 0x0f, 0,
6638 AC_VERB_SET_PIN_WIDGET_CONTROL,
6639 PIN_OUT);
bc9f98a9
KY
6640 }
6641}
6642
6643static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6644 unsigned int res)
6645{
6646 if ((res >> 26) == ALC880_HP_EVENT)
6647 alc260_replacer_672v_automute(codec);
6648}
6649
3f878308
KY
6650static struct hda_verb alc260_hp_dc7600_verbs[] = {
6651 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6652 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6653 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6654 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6655 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6656 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6657 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6658 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6659 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6660 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6661 {}
6662};
6663
7cf51e48
JW
6664/* Test configuration for debugging, modelled after the ALC880 test
6665 * configuration.
6666 */
6667#ifdef CONFIG_SND_DEBUG
6668static hda_nid_t alc260_test_dac_nids[1] = {
6669 0x02,
6670};
6671static hda_nid_t alc260_test_adc_nids[2] = {
6672 0x04, 0x05,
6673};
a1e8d2da 6674/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6675 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6676 * is NID 0x04.
17e7aec6 6677 */
a1e8d2da
JW
6678static struct hda_input_mux alc260_test_capture_sources[2] = {
6679 {
6680 .num_items = 7,
6681 .items = {
6682 { "MIC1 pin", 0x0 },
6683 { "MIC2 pin", 0x1 },
6684 { "LINE1 pin", 0x2 },
6685 { "LINE2 pin", 0x3 },
6686 { "CD pin", 0x4 },
6687 { "LINE-OUT pin", 0x5 },
6688 { "HP-OUT pin", 0x6 },
6689 },
6690 },
6691 {
6692 .num_items = 8,
6693 .items = {
6694 { "MIC1 pin", 0x0 },
6695 { "MIC2 pin", 0x1 },
6696 { "LINE1 pin", 0x2 },
6697 { "LINE2 pin", 0x3 },
6698 { "CD pin", 0x4 },
6699 { "Mixer", 0x5 },
6700 { "LINE-OUT pin", 0x6 },
6701 { "HP-OUT pin", 0x7 },
6702 },
7cf51e48
JW
6703 },
6704};
6705static struct snd_kcontrol_new alc260_test_mixer[] = {
6706 /* Output driver widgets */
6707 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6708 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6709 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6710 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6711 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6712 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6713
a1e8d2da
JW
6714 /* Modes for retasking pin widgets
6715 * Note: the ALC260 doesn't seem to act on requests to enable mic
6716 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6717 * mention this restriction. At this stage it's not clear whether
6718 * this behaviour is intentional or is a hardware bug in chip
6719 * revisions available at least up until early 2006. Therefore for
6720 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6721 * choices, but if it turns out that the lack of mic bias for these
6722 * NIDs is intentional we could change their modes from
6723 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6724 */
7cf51e48
JW
6725 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6726 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6727 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6728 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6729 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6730 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6731
6732 /* Loopback mixer controls */
6733 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6734 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6735 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6736 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6737 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6738 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6739 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6740 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6741 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6742 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6743 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6744 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6745 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6746 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6747
6748 /* Controls for GPIO pins, assuming they are configured as outputs */
6749 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6750 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6751 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6752 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6753
92621f13
JW
6754 /* Switches to allow the digital IO pins to be enabled. The datasheet
6755 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6756 * make this output available should provide clarification.
92621f13
JW
6757 */
6758 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6759 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6760
f8225f6d
JW
6761 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6762 * this output to turn on an external amplifier.
6763 */
6764 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6765 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6766
7cf51e48
JW
6767 { } /* end */
6768};
6769static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6770 /* Enable all GPIOs as outputs with an initial value of 0 */
6771 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6772 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6773 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6774
7cf51e48
JW
6775 /* Enable retasking pins as output, initially without power amp */
6776 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6777 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6778 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6779 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6780 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6781 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6782
92621f13
JW
6783 /* Disable digital (SPDIF) pins initially, but users can enable
6784 * them via a mixer switch. In the case of SPDIF-out, this initverb
6785 * payload also sets the generation to 0, output to be in "consumer"
6786 * PCM format, copyright asserted, no pre-emphasis and no validity
6787 * control.
6788 */
7cf51e48
JW
6789 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6790 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6791
ea1fb29a 6792 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6793 * OUT1 sum bus when acting as an output.
6794 */
6795 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6796 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6797 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6798 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6799
6800 /* Start with output sum widgets muted and their output gains at min */
6801 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6802 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6803 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6804 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6805 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6806 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6807 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6808 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6809 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6810
cdcd9268
JW
6811 /* Unmute retasking pin widget output buffers since the default
6812 * state appears to be output. As the pin mode is changed by the
6813 * user the pin mode control will take care of enabling the pin's
6814 * input/output buffers as needed.
6815 */
7cf51e48
JW
6816 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6817 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6818 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6820 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6821 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6822 /* Also unmute the mono-out pin widget */
6823 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6824
7cf51e48
JW
6825 /* Mute capture amp left and right */
6826 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6827 /* Set ADC connection select to match default mixer setting (mic1
6828 * pin)
7cf51e48
JW
6829 */
6830 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6831
6832 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6833 * set ADC connection to mic1 pin
7cf51e48
JW
6834 */
6835 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6836 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6837
6838 /* Mute all inputs to mixer widget (even unconnected ones) */
6839 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6840 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6841 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6842 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6843 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6844 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6845 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6846 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6847
6848 { }
6849};
6850#endif
6851
6330079f
TI
6852#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6853#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6854
a3bcba38
TI
6855#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6856#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6857
df694daa
KY
6858/*
6859 * for BIOS auto-configuration
6860 */
16ded525 6861
df694daa 6862static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6863 const char *pfx, int *vol_bits)
df694daa
KY
6864{
6865 hda_nid_t nid_vol;
6866 unsigned long vol_val, sw_val;
df694daa
KY
6867 int err;
6868
6869 if (nid >= 0x0f && nid < 0x11) {
6870 nid_vol = nid - 0x7;
6871 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6872 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6873 } else if (nid == 0x11) {
6874 nid_vol = nid - 0x7;
6875 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6876 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6877 } else if (nid >= 0x12 && nid <= 0x15) {
6878 nid_vol = 0x08;
6879 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6880 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6881 } else
6882 return 0; /* N/A */
ea1fb29a 6883
863b4518
TI
6884 if (!(*vol_bits & (1 << nid_vol))) {
6885 /* first control for the volume widget */
0afe5f89 6886 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6887 if (err < 0)
6888 return err;
6889 *vol_bits |= (1 << nid_vol);
6890 }
0afe5f89 6891 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6892 if (err < 0)
df694daa
KY
6893 return err;
6894 return 1;
6895}
6896
6897/* add playback controls from the parsed DAC table */
6898static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6899 const struct auto_pin_cfg *cfg)
6900{
6901 hda_nid_t nid;
6902 int err;
863b4518 6903 int vols = 0;
df694daa
KY
6904
6905 spec->multiout.num_dacs = 1;
6906 spec->multiout.dac_nids = spec->private_dac_nids;
6907 spec->multiout.dac_nids[0] = 0x02;
6908
6909 nid = cfg->line_out_pins[0];
6910 if (nid) {
23112d6d
TI
6911 const char *pfx;
6912 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6913 pfx = "Master";
6914 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6915 pfx = "Speaker";
6916 else
6917 pfx = "Front";
6918 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6919 if (err < 0)
6920 return err;
6921 }
6922
82bc955f 6923 nid = cfg->speaker_pins[0];
df694daa 6924 if (nid) {
863b4518 6925 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6926 if (err < 0)
6927 return err;
6928 }
6929
eb06ed8f 6930 nid = cfg->hp_pins[0];
df694daa 6931 if (nid) {
863b4518
TI
6932 err = alc260_add_playback_controls(spec, nid, "Headphone",
6933 &vols);
df694daa
KY
6934 if (err < 0)
6935 return err;
6936 }
f12ab1e0 6937 return 0;
df694daa
KY
6938}
6939
6940/* create playback/capture controls for input pins */
05f5f477 6941static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6942 const struct auto_pin_cfg *cfg)
6943{
05f5f477 6944 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6945}
6946
6947static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6948 hda_nid_t nid, int pin_type,
6949 int sel_idx)
6950{
f6c7e546 6951 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6952 /* need the manual connection? */
6953 if (nid >= 0x12) {
6954 int idx = nid - 0x12;
6955 snd_hda_codec_write(codec, idx + 0x0b, 0,
6956 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6957 }
6958}
6959
6960static void alc260_auto_init_multi_out(struct hda_codec *codec)
6961{
6962 struct alc_spec *spec = codec->spec;
6963 hda_nid_t nid;
6964
f12ab1e0 6965 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6966 if (nid) {
6967 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6968 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6969 }
ea1fb29a 6970
82bc955f 6971 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6972 if (nid)
6973 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6974
eb06ed8f 6975 nid = spec->autocfg.hp_pins[0];
df694daa 6976 if (nid)
baba8ee9 6977 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6978}
df694daa
KY
6979
6980#define ALC260_PIN_CD_NID 0x16
6981static void alc260_auto_init_analog_input(struct hda_codec *codec)
6982{
6983 struct alc_spec *spec = codec->spec;
66ceeb6b 6984 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6985 int i;
6986
66ceeb6b
TI
6987 for (i = 0; i < cfg->num_inputs; i++) {
6988 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6989 if (nid >= 0x12) {
30ea098f 6990 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6991 if (nid != ALC260_PIN_CD_NID &&
6992 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6993 snd_hda_codec_write(codec, nid, 0,
6994 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6995 AMP_OUT_MUTE);
6996 }
6997 }
6998}
6999
7f311a46
TI
7000#define alc260_auto_init_input_src alc880_auto_init_input_src
7001
df694daa
KY
7002/*
7003 * generic initialization of ADC, input mixers and output mixers
7004 */
7005static struct hda_verb alc260_volume_init_verbs[] = {
7006 /*
7007 * Unmute ADC0-1 and set the default input to mic-in
7008 */
7009 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7010 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7011 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7012 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7013
df694daa
KY
7014 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7015 * mixer widget
f12ab1e0
TI
7016 * Note: PASD motherboards uses the Line In 2 as the input for
7017 * front panel mic (mic 2)
df694daa
KY
7018 */
7019 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7020 /* mute analog inputs */
7021 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7022 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7023 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7024 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7025 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7026
7027 /*
7028 * Set up output mixers (0x08 - 0x0a)
7029 */
7030 /* set vol=0 to output mixers */
7031 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7032 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7033 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7034 /* set up input amps for analog loopback */
7035 /* Amp Indices: DAC = 0, mixer = 1 */
7036 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7037 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7038 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7039 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7040 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7041 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7042
df694daa
KY
7043 { }
7044};
7045
7046static int alc260_parse_auto_config(struct hda_codec *codec)
7047{
7048 struct alc_spec *spec = codec->spec;
df694daa
KY
7049 int err;
7050 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7051
f12ab1e0
TI
7052 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7053 alc260_ignore);
7054 if (err < 0)
df694daa 7055 return err;
f12ab1e0
TI
7056 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7057 if (err < 0)
4a471b7d 7058 return err;
603c4019 7059 if (!spec->kctls.list)
df694daa 7060 return 0; /* can't find valid BIOS pin config */
05f5f477 7061 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7062 if (err < 0)
df694daa
KY
7063 return err;
7064
7065 spec->multiout.max_channels = 2;
7066
0852d7a6 7067 if (spec->autocfg.dig_outs)
df694daa 7068 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7069 if (spec->kctls.list)
d88897ea 7070 add_mixer(spec, spec->kctls.list);
df694daa 7071
d88897ea 7072 add_verb(spec, alc260_volume_init_verbs);
df694daa 7073
a1e8d2da 7074 spec->num_mux_defs = 1;
61b9b9b1 7075 spec->input_mux = &spec->private_imux[0];
df694daa 7076
6227cdce 7077 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7078
df694daa
KY
7079 return 1;
7080}
7081
ae6b813a
TI
7082/* additional initialization for auto-configuration model */
7083static void alc260_auto_init(struct hda_codec *codec)
df694daa 7084{
f6c7e546 7085 struct alc_spec *spec = codec->spec;
df694daa
KY
7086 alc260_auto_init_multi_out(codec);
7087 alc260_auto_init_analog_input(codec);
7f311a46 7088 alc260_auto_init_input_src(codec);
757899ac 7089 alc_auto_init_digital(codec);
f6c7e546 7090 if (spec->unsol_event)
7fb0d78f 7091 alc_inithook(codec);
df694daa
KY
7092}
7093
cb53c626
TI
7094#ifdef CONFIG_SND_HDA_POWER_SAVE
7095static struct hda_amp_list alc260_loopbacks[] = {
7096 { 0x07, HDA_INPUT, 0 },
7097 { 0x07, HDA_INPUT, 1 },
7098 { 0x07, HDA_INPUT, 2 },
7099 { 0x07, HDA_INPUT, 3 },
7100 { 0x07, HDA_INPUT, 4 },
7101 { } /* end */
7102};
7103#endif
7104
fc091769
TI
7105/*
7106 * Pin config fixes
7107 */
7108enum {
7109 PINFIX_HP_DC5750,
7110};
7111
fc091769
TI
7112static const struct alc_fixup alc260_fixups[] = {
7113 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7114 .type = ALC_FIXUP_PINS,
7115 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7116 { 0x11, 0x90130110 }, /* speaker */
7117 { }
7118 }
fc091769
TI
7119 },
7120};
7121
7122static struct snd_pci_quirk alc260_fixup_tbl[] = {
7123 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7124 {}
7125};
7126
df694daa
KY
7127/*
7128 * ALC260 configurations
7129 */
ea734963 7130static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7131 [ALC260_BASIC] = "basic",
7132 [ALC260_HP] = "hp",
7133 [ALC260_HP_3013] = "hp-3013",
2922c9af 7134 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7135 [ALC260_FUJITSU_S702X] = "fujitsu",
7136 [ALC260_ACER] = "acer",
bc9f98a9
KY
7137 [ALC260_WILL] = "will",
7138 [ALC260_REPLACER_672V] = "replacer",
cc959489 7139 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7140#ifdef CONFIG_SND_DEBUG
f5fcc13c 7141 [ALC260_TEST] = "test",
7cf51e48 7142#endif
f5fcc13c
TI
7143 [ALC260_AUTO] = "auto",
7144};
7145
7146static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7147 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7148 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7149 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7150 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7151 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7152 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7153 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7154 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7155 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7156 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7157 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7158 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7159 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7160 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7161 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7162 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7163 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7164 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7165 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7166 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7167 {}
7168};
7169
7170static struct alc_config_preset alc260_presets[] = {
7171 [ALC260_BASIC] = {
7172 .mixers = { alc260_base_output_mixer,
45bdd1c1 7173 alc260_input_mixer },
df694daa
KY
7174 .init_verbs = { alc260_init_verbs },
7175 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7176 .dac_nids = alc260_dac_nids,
f9e336f6 7177 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7178 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7179 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7180 .channel_mode = alc260_modes,
7181 .input_mux = &alc260_capture_source,
7182 },
7183 [ALC260_HP] = {
bec15c3a 7184 .mixers = { alc260_hp_output_mixer,
f9e336f6 7185 alc260_input_mixer },
bec15c3a
TI
7186 .init_verbs = { alc260_init_verbs,
7187 alc260_hp_unsol_verbs },
df694daa
KY
7188 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7189 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7190 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7191 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7192 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7193 .channel_mode = alc260_modes,
7194 .input_mux = &alc260_capture_source,
bec15c3a
TI
7195 .unsol_event = alc260_hp_unsol_event,
7196 .init_hook = alc260_hp_automute,
df694daa 7197 },
3f878308
KY
7198 [ALC260_HP_DC7600] = {
7199 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7200 alc260_input_mixer },
3f878308
KY
7201 .init_verbs = { alc260_init_verbs,
7202 alc260_hp_dc7600_verbs },
7203 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7204 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7205 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7206 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7207 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7208 .channel_mode = alc260_modes,
7209 .input_mux = &alc260_capture_source,
7210 .unsol_event = alc260_hp_3012_unsol_event,
7211 .init_hook = alc260_hp_3012_automute,
7212 },
df694daa
KY
7213 [ALC260_HP_3013] = {
7214 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7215 alc260_input_mixer },
bec15c3a
TI
7216 .init_verbs = { alc260_hp_3013_init_verbs,
7217 alc260_hp_3013_unsol_verbs },
df694daa
KY
7218 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7219 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7220 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7221 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7222 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7223 .channel_mode = alc260_modes,
7224 .input_mux = &alc260_capture_source,
bec15c3a
TI
7225 .unsol_event = alc260_hp_3013_unsol_event,
7226 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7227 },
7228 [ALC260_FUJITSU_S702X] = {
f9e336f6 7229 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7230 .init_verbs = { alc260_fujitsu_init_verbs },
7231 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7232 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7233 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7234 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7235 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7236 .channel_mode = alc260_modes,
a1e8d2da
JW
7237 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7238 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7239 },
0bfc90e9 7240 [ALC260_ACER] = {
f9e336f6 7241 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7242 .init_verbs = { alc260_acer_init_verbs },
7243 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7244 .dac_nids = alc260_dac_nids,
7245 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7246 .adc_nids = alc260_dual_adc_nids,
7247 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7248 .channel_mode = alc260_modes,
a1e8d2da
JW
7249 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7250 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7251 },
cc959489
MS
7252 [ALC260_FAVORIT100] = {
7253 .mixers = { alc260_favorit100_mixer },
7254 .init_verbs = { alc260_favorit100_init_verbs },
7255 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7256 .dac_nids = alc260_dac_nids,
7257 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7258 .adc_nids = alc260_dual_adc_nids,
7259 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7260 .channel_mode = alc260_modes,
7261 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7262 .input_mux = alc260_favorit100_capture_sources,
7263 },
bc9f98a9 7264 [ALC260_WILL] = {
f9e336f6 7265 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7266 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7267 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7268 .dac_nids = alc260_dac_nids,
7269 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7270 .adc_nids = alc260_adc_nids,
7271 .dig_out_nid = ALC260_DIGOUT_NID,
7272 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7273 .channel_mode = alc260_modes,
7274 .input_mux = &alc260_capture_source,
7275 },
7276 [ALC260_REPLACER_672V] = {
f9e336f6 7277 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7278 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7279 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7280 .dac_nids = alc260_dac_nids,
7281 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7282 .adc_nids = alc260_adc_nids,
7283 .dig_out_nid = ALC260_DIGOUT_NID,
7284 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7285 .channel_mode = alc260_modes,
7286 .input_mux = &alc260_capture_source,
7287 .unsol_event = alc260_replacer_672v_unsol_event,
7288 .init_hook = alc260_replacer_672v_automute,
7289 },
7cf51e48
JW
7290#ifdef CONFIG_SND_DEBUG
7291 [ALC260_TEST] = {
f9e336f6 7292 .mixers = { alc260_test_mixer },
7cf51e48
JW
7293 .init_verbs = { alc260_test_init_verbs },
7294 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7295 .dac_nids = alc260_test_dac_nids,
7296 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7297 .adc_nids = alc260_test_adc_nids,
7298 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7299 .channel_mode = alc260_modes,
a1e8d2da
JW
7300 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7301 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7302 },
7303#endif
df694daa
KY
7304};
7305
7306static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7307{
7308 struct alc_spec *spec;
df694daa 7309 int err, board_config;
1da177e4 7310
e560d8d8 7311 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7312 if (spec == NULL)
7313 return -ENOMEM;
7314
7315 codec->spec = spec;
7316
f5fcc13c
TI
7317 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7318 alc260_models,
7319 alc260_cfg_tbl);
7320 if (board_config < 0) {
9a11f1aa 7321 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7322 codec->chip_name);
df694daa 7323 board_config = ALC260_AUTO;
16ded525 7324 }
1da177e4 7325
b5bfbc67
TI
7326 if (board_config == ALC260_AUTO) {
7327 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7328 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7329 }
fc091769 7330
df694daa
KY
7331 if (board_config == ALC260_AUTO) {
7332 /* automatic parse from the BIOS config */
7333 err = alc260_parse_auto_config(codec);
7334 if (err < 0) {
7335 alc_free(codec);
7336 return err;
f12ab1e0 7337 } else if (!err) {
9c7f852e
TI
7338 printk(KERN_INFO
7339 "hda_codec: Cannot set up configuration "
7340 "from BIOS. Using base mode...\n");
df694daa
KY
7341 board_config = ALC260_BASIC;
7342 }
a9430dd8 7343 }
e9edcee0 7344
680cd536
KK
7345 err = snd_hda_attach_beep_device(codec, 0x1);
7346 if (err < 0) {
7347 alc_free(codec);
7348 return err;
7349 }
7350
df694daa 7351 if (board_config != ALC260_AUTO)
e9c364c0 7352 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7353
1da177e4
LT
7354 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7355 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7356 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7357
a3bcba38
TI
7358 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7359 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7360
4ef0ef19
TI
7361 if (!spec->adc_nids && spec->input_mux) {
7362 /* check whether NID 0x04 is valid */
7363 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7364 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7365 /* get type */
7366 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7367 spec->adc_nids = alc260_adc_nids_alt;
7368 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7369 } else {
7370 spec->adc_nids = alc260_adc_nids;
7371 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7372 }
7373 }
b59bdf3b 7374 set_capture_mixer(codec);
45bdd1c1 7375 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7376
b5bfbc67 7377 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7378
2134ea4f
TI
7379 spec->vmaster_nid = 0x08;
7380
1da177e4 7381 codec->patch_ops = alc_patch_ops;
df694daa 7382 if (board_config == ALC260_AUTO)
ae6b813a 7383 spec->init_hook = alc260_auto_init;
cb53c626
TI
7384#ifdef CONFIG_SND_HDA_POWER_SAVE
7385 if (!spec->loopback.amplist)
7386 spec->loopback.amplist = alc260_loopbacks;
7387#endif
1da177e4
LT
7388
7389 return 0;
7390}
7391
e9edcee0 7392
1da177e4 7393/*
4953550a 7394 * ALC882/883/885/888/889 support
1da177e4
LT
7395 *
7396 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7397 * configuration. Each pin widget can choose any input DACs and a mixer.
7398 * Each ADC is connected from a mixer of all inputs. This makes possible
7399 * 6-channel independent captures.
7400 *
7401 * In addition, an independent DAC for the multi-playback (not used in this
7402 * driver yet).
7403 */
df694daa
KY
7404#define ALC882_DIGOUT_NID 0x06
7405#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7406#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7407#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7408#define ALC1200_DIGOUT_NID 0x10
7409
1da177e4 7410
d2a6d7dc 7411static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7412 { 8, NULL }
7413};
7414
4953550a 7415/* DACs */
1da177e4
LT
7416static hda_nid_t alc882_dac_nids[4] = {
7417 /* front, rear, clfe, rear_surr */
7418 0x02, 0x03, 0x04, 0x05
7419};
4953550a 7420#define alc883_dac_nids alc882_dac_nids
1da177e4 7421
4953550a 7422/* ADCs */
df694daa
KY
7423#define alc882_adc_nids alc880_adc_nids
7424#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7425#define alc883_adc_nids alc882_adc_nids_alt
7426static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7427static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7428#define alc889_adc_nids alc880_adc_nids
1da177e4 7429
e1406348
TI
7430static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7431static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7432#define alc883_capsrc_nids alc882_capsrc_nids_alt
7433static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7434#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7435
1da177e4
LT
7436/* input MUX */
7437/* FIXME: should be a matrix-type input source selection */
7438
7439static struct hda_input_mux alc882_capture_source = {
7440 .num_items = 4,
7441 .items = {
7442 { "Mic", 0x0 },
7443 { "Front Mic", 0x1 },
7444 { "Line", 0x2 },
7445 { "CD", 0x4 },
7446 },
7447};
41d5545d 7448
4953550a
TI
7449#define alc883_capture_source alc882_capture_source
7450
87a8c370
JK
7451static struct hda_input_mux alc889_capture_source = {
7452 .num_items = 3,
7453 .items = {
7454 { "Front Mic", 0x0 },
7455 { "Mic", 0x3 },
7456 { "Line", 0x2 },
7457 },
7458};
7459
41d5545d
KS
7460static struct hda_input_mux mb5_capture_source = {
7461 .num_items = 3,
7462 .items = {
7463 { "Mic", 0x1 },
b8f171e7 7464 { "Line", 0x7 },
41d5545d
KS
7465 { "CD", 0x4 },
7466 },
7467};
7468
e458b1fa
LY
7469static struct hda_input_mux macmini3_capture_source = {
7470 .num_items = 2,
7471 .items = {
7472 { "Line", 0x2 },
7473 { "CD", 0x4 },
7474 },
7475};
7476
4953550a
TI
7477static struct hda_input_mux alc883_3stack_6ch_intel = {
7478 .num_items = 4,
7479 .items = {
7480 { "Mic", 0x1 },
7481 { "Front Mic", 0x0 },
7482 { "Line", 0x2 },
7483 { "CD", 0x4 },
7484 },
7485};
7486
7487static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7488 .num_items = 2,
7489 .items = {
7490 { "Mic", 0x1 },
7491 { "Line", 0x2 },
7492 },
7493};
7494
7495static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7496 .num_items = 4,
7497 .items = {
7498 { "Mic", 0x0 },
28c4edb7 7499 { "Internal Mic", 0x1 },
4953550a
TI
7500 { "Line", 0x2 },
7501 { "CD", 0x4 },
7502 },
7503};
7504
7505static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7506 .num_items = 2,
7507 .items = {
7508 { "Mic", 0x0 },
28c4edb7 7509 { "Internal Mic", 0x1 },
4953550a
TI
7510 },
7511};
7512
7513static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7514 .num_items = 3,
7515 .items = {
7516 { "Mic", 0x0 },
7517 { "Front Mic", 0x1 },
7518 { "Line", 0x4 },
7519 },
7520};
7521
7522static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7523 .num_items = 2,
7524 .items = {
7525 { "Mic", 0x0 },
7526 { "Line", 0x2 },
7527 },
7528};
7529
7530static struct hda_input_mux alc889A_mb31_capture_source = {
7531 .num_items = 2,
7532 .items = {
7533 { "Mic", 0x0 },
7534 /* Front Mic (0x01) unused */
7535 { "Line", 0x2 },
7536 /* Line 2 (0x03) unused */
af901ca1 7537 /* CD (0x04) unused? */
4953550a
TI
7538 },
7539};
7540
b7cccc52
JM
7541static struct hda_input_mux alc889A_imac91_capture_source = {
7542 .num_items = 2,
7543 .items = {
7544 { "Mic", 0x01 },
7545 { "Line", 0x2 }, /* Not sure! */
7546 },
7547};
7548
4953550a
TI
7549/*
7550 * 2ch mode
7551 */
7552static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7553 { 2, NULL }
7554};
7555
272a527c
KY
7556/*
7557 * 2ch mode
7558 */
7559static struct hda_verb alc882_3ST_ch2_init[] = {
7560 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7561 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7562 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7563 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7564 { } /* end */
7565};
7566
4953550a
TI
7567/*
7568 * 4ch mode
7569 */
7570static struct hda_verb alc882_3ST_ch4_init[] = {
7571 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7572 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7573 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7574 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7575 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7576 { } /* end */
7577};
7578
272a527c
KY
7579/*
7580 * 6ch mode
7581 */
7582static struct hda_verb alc882_3ST_ch6_init[] = {
7583 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7584 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7585 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7586 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7587 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7588 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7589 { } /* end */
7590};
7591
4953550a 7592static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7593 { 2, alc882_3ST_ch2_init },
4953550a 7594 { 4, alc882_3ST_ch4_init },
272a527c
KY
7595 { 6, alc882_3ST_ch6_init },
7596};
7597
4953550a
TI
7598#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7599
a65cc60f 7600/*
7601 * 2ch mode
7602 */
7603static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7604 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7605 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7606 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7607 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7608 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7609 { } /* end */
7610};
7611
7612/*
7613 * 4ch mode
7614 */
7615static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7616 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7617 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7618 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7619 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7620 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7621 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7622 { } /* end */
7623};
7624
7625/*
7626 * 6ch mode
7627 */
7628static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7629 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7630 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7631 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7632 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7633 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7634 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7635 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7636 { } /* end */
7637};
7638
7639static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7640 { 2, alc883_3ST_ch2_clevo_init },
7641 { 4, alc883_3ST_ch4_clevo_init },
7642 { 6, alc883_3ST_ch6_clevo_init },
7643};
7644
7645
df694daa
KY
7646/*
7647 * 6ch mode
7648 */
7649static struct hda_verb alc882_sixstack_ch6_init[] = {
7650 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7651 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7652 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7653 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7654 { } /* end */
7655};
7656
7657/*
7658 * 8ch mode
7659 */
7660static struct hda_verb alc882_sixstack_ch8_init[] = {
7661 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7662 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7663 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7664 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7665 { } /* end */
7666};
7667
7668static struct hda_channel_mode alc882_sixstack_modes[2] = {
7669 { 6, alc882_sixstack_ch6_init },
7670 { 8, alc882_sixstack_ch8_init },
7671};
7672
76e6f5a9
RH
7673
7674/* Macbook Air 2,1 */
7675
7676static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7677 { 2, NULL },
7678};
7679
87350ad0 7680/*
def319f9 7681 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7682 */
7683
7684/*
7685 * 2ch mode
7686 */
7687static struct hda_verb alc885_mbp_ch2_init[] = {
7688 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7689 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7690 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7691 { } /* end */
7692};
7693
7694/*
a3f730af 7695 * 4ch mode
87350ad0 7696 */
a3f730af 7697static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7698 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7699 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7700 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7701 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7702 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7703 { } /* end */
7704};
7705
a3f730af 7706static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7707 { 2, alc885_mbp_ch2_init },
a3f730af 7708 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7709};
7710
92b9de83
KS
7711/*
7712 * 2ch
7713 * Speakers/Woofer/HP = Front
7714 * LineIn = Input
7715 */
7716static struct hda_verb alc885_mb5_ch2_init[] = {
7717 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7718 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7719 { } /* end */
7720};
7721
7722/*
7723 * 6ch mode
7724 * Speakers/HP = Front
7725 * Woofer = LFE
7726 * LineIn = Surround
7727 */
7728static struct hda_verb alc885_mb5_ch6_init[] = {
7729 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7730 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7731 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7732 { } /* end */
7733};
7734
7735static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7736 { 2, alc885_mb5_ch2_init },
7737 { 6, alc885_mb5_ch6_init },
7738};
87350ad0 7739
d01aecdf 7740#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7741
7742/*
7743 * 2ch mode
7744 */
7745static struct hda_verb alc883_4ST_ch2_init[] = {
7746 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7747 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7748 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7749 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7750 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7751 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7752 { } /* end */
7753};
7754
7755/*
7756 * 4ch mode
7757 */
7758static struct hda_verb alc883_4ST_ch4_init[] = {
7759 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7760 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7761 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7762 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7763 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7764 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7765 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7766 { } /* end */
7767};
7768
7769/*
7770 * 6ch mode
7771 */
7772static struct hda_verb alc883_4ST_ch6_init[] = {
7773 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7774 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7775 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7776 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7777 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7778 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7779 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7780 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7781 { } /* end */
7782};
7783
7784/*
7785 * 8ch mode
7786 */
7787static struct hda_verb alc883_4ST_ch8_init[] = {
7788 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7789 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7790 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7791 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7792 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7793 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7794 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7795 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7796 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7797 { } /* end */
7798};
7799
7800static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7801 { 2, alc883_4ST_ch2_init },
7802 { 4, alc883_4ST_ch4_init },
7803 { 6, alc883_4ST_ch6_init },
7804 { 8, alc883_4ST_ch8_init },
7805};
7806
7807
7808/*
7809 * 2ch mode
7810 */
7811static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7812 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7813 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7814 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7815 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7816 { } /* end */
7817};
7818
7819/*
7820 * 4ch mode
7821 */
7822static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7823 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7824 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7825 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7826 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7827 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7828 { } /* end */
7829};
7830
7831/*
7832 * 6ch mode
7833 */
7834static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7835 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7836 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7837 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7838 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7839 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7840 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7841 { } /* end */
7842};
7843
7844static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7845 { 2, alc883_3ST_ch2_intel_init },
7846 { 4, alc883_3ST_ch4_intel_init },
7847 { 6, alc883_3ST_ch6_intel_init },
7848};
7849
dd7714c9
WF
7850/*
7851 * 2ch mode
7852 */
7853static struct hda_verb alc889_ch2_intel_init[] = {
7854 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7855 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7856 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7857 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7858 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7859 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7860 { } /* end */
7861};
7862
87a8c370
JK
7863/*
7864 * 6ch mode
7865 */
7866static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7867 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7868 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7869 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7870 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7871 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7872 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7873 { } /* end */
7874};
7875
7876/*
7877 * 8ch mode
7878 */
7879static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7880 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7881 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7882 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7883 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7884 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7885 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7886 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7887 { } /* end */
7888};
7889
dd7714c9
WF
7890static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7891 { 2, alc889_ch2_intel_init },
87a8c370
JK
7892 { 6, alc889_ch6_intel_init },
7893 { 8, alc889_ch8_intel_init },
7894};
7895
4953550a
TI
7896/*
7897 * 6ch mode
7898 */
7899static struct hda_verb alc883_sixstack_ch6_init[] = {
7900 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7901 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7902 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7903 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7904 { } /* end */
7905};
7906
7907/*
7908 * 8ch mode
7909 */
7910static struct hda_verb alc883_sixstack_ch8_init[] = {
7911 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7912 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7913 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7914 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7915 { } /* end */
7916};
7917
7918static struct hda_channel_mode alc883_sixstack_modes[2] = {
7919 { 6, alc883_sixstack_ch6_init },
7920 { 8, alc883_sixstack_ch8_init },
7921};
7922
7923
1da177e4
LT
7924/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7925 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7926 */
c8b6bf9b 7927static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7928 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7929 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7930 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7931 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7932 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7933 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7934 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7935 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7936 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7937 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7938 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7939 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7940 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7941 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7942 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7943 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 7944 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
7945 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7946 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 7947 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 7948 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7949 { } /* end */
7950};
7951
76e6f5a9
RH
7952/* Macbook Air 2,1 same control for HP and internal Speaker */
7953
7954static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7955 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7956 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7957 { }
7958};
7959
7960
87350ad0 7961static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7962 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7963 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7964 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7965 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7966 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7967 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7968 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7969 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7970 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
7971 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7972 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
7973 { } /* end */
7974};
41d5545d
KS
7975
7976static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
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),
a76221d4
AM
7983 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7984 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7985 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7986 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7987 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7988 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
7989 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7990 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
7991 { } /* end */
7992};
92b9de83 7993
e458b1fa
LY
7994static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7995 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7996 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7997 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7998 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7999 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8000 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8001 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8002 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8004 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8005 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8006 { } /* end */
8007};
8008
4b7e1803 8009static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8010 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8011 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8012 { } /* end */
8013};
8014
8015
bdd148a3
KY
8016static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8017 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8018 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8019 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8020 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8021 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8022 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8024 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8026 { } /* end */
8027};
8028
272a527c
KY
8029static struct snd_kcontrol_new alc882_targa_mixer[] = {
8030 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8031 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8032 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8033 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8034 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8035 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8036 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8039 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8040 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8041 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8042 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8043 { } /* end */
8044};
8045
8046/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8047 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8048 */
8049static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8050 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8051 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8052 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8053 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8054 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8055 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8056 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8057 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8058 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8059 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8060 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8061 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8062 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8063 { } /* end */
8064};
8065
914759b7
TI
8066static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8067 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8068 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8069 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8070 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8071 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8072 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8073 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8074 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8075 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8076 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8077 { } /* end */
8078};
8079
df694daa
KY
8080static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8081 {
8082 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8083 .name = "Channel Mode",
8084 .info = alc_ch_mode_info,
8085 .get = alc_ch_mode_get,
8086 .put = alc_ch_mode_put,
8087 },
8088 { } /* end */
8089};
8090
4953550a 8091static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8092 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8093 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8094 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8095 /* Rear mixer */
05acb863
TI
8096 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8097 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8098 /* CLFE mixer */
05acb863
TI
8099 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8100 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8101 /* Side mixer */
05acb863
TI
8102 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8103 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8104
e9edcee0 8105 /* Front Pin: output 0 (0x0c) */
05acb863 8106 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8107 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8108 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8109 /* Rear Pin: output 1 (0x0d) */
05acb863 8110 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8112 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8113 /* CLFE Pin: output 2 (0x0e) */
05acb863 8114 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8115 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8116 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8117 /* Side Pin: output 3 (0x0f) */
05acb863 8118 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8119 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8120 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8121 /* Mic (rear) pin: input vref at 80% */
16ded525 8122 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8123 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8124 /* Front Mic pin: input vref at 80% */
16ded525 8125 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8126 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8127 /* Line In pin: input */
05acb863 8128 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8129 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8130 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8131 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8132 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8133 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8134 /* CD pin widget for input */
05acb863 8135 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8136
8137 /* FIXME: use matrix-type input source selection */
8138 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8139 /* Input mixer2 */
05acb863 8140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8141 /* Input mixer3 */
05acb863 8142 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8143 /* ADC2: mute amp left and right */
8144 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8145 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8146 /* ADC3: mute amp left and right */
8147 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8148 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8149
8150 { }
8151};
8152
4953550a
TI
8153static struct hda_verb alc882_adc1_init_verbs[] = {
8154 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8155 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8156 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8157 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8158 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8159 /* ADC1: mute amp left and right */
8160 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8161 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8162 { }
8163};
8164
4b146cb0
TI
8165static struct hda_verb alc882_eapd_verbs[] = {
8166 /* change to EAPD mode */
8167 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8168 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8169 { }
4b146cb0
TI
8170};
8171
87a8c370
JK
8172static struct hda_verb alc889_eapd_verbs[] = {
8173 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8174 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8175 { }
8176};
8177
6732bd0d
WF
8178static struct hda_verb alc_hp15_unsol_verbs[] = {
8179 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8181 {}
8182};
87a8c370
JK
8183
8184static struct hda_verb alc885_init_verbs[] = {
8185 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8186 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8187 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8188 /* Rear mixer */
88102f3f
KY
8189 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8190 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8191 /* CLFE mixer */
88102f3f
KY
8192 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8193 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8194 /* Side mixer */
88102f3f
KY
8195 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8196 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8197
8198 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8199 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8200 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8201 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8202 /* Front Pin: output 0 (0x0c) */
8203 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8204 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8205 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8206 /* Rear Pin: output 1 (0x0d) */
8207 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8208 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8209 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8210 /* CLFE Pin: output 2 (0x0e) */
8211 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8212 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8213 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8214 /* Side Pin: output 3 (0x0f) */
8215 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8216 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8217 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8218 /* Mic (rear) pin: input vref at 80% */
8219 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8220 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8221 /* Front Mic pin: input vref at 80% */
8222 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8223 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8224 /* Line In pin: input */
8225 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8226 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8227
8228 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8229 /* Input mixer1 */
88102f3f 8230 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8231 /* Input mixer2 */
8232 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8233 /* Input mixer3 */
88102f3f 8234 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8235 /* ADC2: mute amp left and right */
8236 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8237 /* ADC3: mute amp left and right */
8238 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8239
8240 { }
8241};
8242
8243static struct hda_verb alc885_init_input_verbs[] = {
8244 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8245 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8247 { }
8248};
8249
8250
8251/* Unmute Selector 24h and set the default input to front mic */
8252static struct hda_verb alc889_init_input_verbs[] = {
8253 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8254 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8255 { }
8256};
8257
8258
4953550a
TI
8259#define alc883_init_verbs alc882_base_init_verbs
8260
9102cd1c
TD
8261/* Mac Pro test */
8262static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8263 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8264 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8265 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8266 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8267 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8268 /* FIXME: this looks suspicious...
d355c82a
JK
8269 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8270 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8271 */
9102cd1c
TD
8272 { } /* end */
8273};
8274
8275static struct hda_verb alc882_macpro_init_verbs[] = {
8276 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8277 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8278 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8279 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8280 /* Front Pin: output 0 (0x0c) */
8281 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8282 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8283 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8284 /* Front Mic pin: input vref at 80% */
8285 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8286 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8287 /* Speaker: output */
8288 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8289 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8290 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8291 /* Headphone output (output 0 - 0x0c) */
8292 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8293 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8294 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8295
8296 /* FIXME: use matrix-type input source selection */
8297 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8298 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8300 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8303 /* Input mixer2 */
8304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8308 /* Input mixer3 */
8309 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8310 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8313 /* ADC1: mute amp left and right */
8314 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8315 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8316 /* ADC2: mute amp left and right */
8317 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8318 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8319 /* ADC3: mute amp left and right */
8320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8321 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8322
8323 { }
8324};
f12ab1e0 8325
41d5545d
KS
8326/* Macbook 5,1 */
8327static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8328 /* DACs */
8329 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8330 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8331 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8332 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8333 /* Front mixer */
41d5545d
KS
8334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8336 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8337 /* Surround mixer */
8338 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8339 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8340 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8341 /* LFE mixer */
8342 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8343 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8344 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8345 /* HP mixer */
8346 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8347 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8348 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8349 /* Front Pin (0x0c) */
41d5545d
KS
8350 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8351 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8352 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8353 /* LFE Pin (0x0e) */
8354 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8355 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8356 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8357 /* HP Pin (0x0f) */
41d5545d
KS
8358 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8359 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8360 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8361 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8362 /* Front Mic pin: input vref at 80% */
8363 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8364 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8365 /* Line In pin */
8366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8368
b8f171e7
AM
8369 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8370 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8371 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8372 { }
8373};
8374
e458b1fa
LY
8375/* Macmini 3,1 */
8376static struct hda_verb alc885_macmini3_init_verbs[] = {
8377 /* DACs */
8378 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8379 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8380 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8381 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8382 /* Front mixer */
8383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8384 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8385 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8386 /* Surround mixer */
8387 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8388 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8389 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8390 /* LFE mixer */
8391 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8392 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8393 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8394 /* HP mixer */
8395 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8396 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8397 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8398 /* Front Pin (0x0c) */
8399 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8400 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8401 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8402 /* LFE Pin (0x0e) */
8403 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8404 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8405 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8406 /* HP Pin (0x0f) */
8407 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8408 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8409 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8410 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8411 /* Line In pin */
8412 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8413 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8414
8415 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8416 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8417 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8418 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8419 { }
8420};
8421
76e6f5a9
RH
8422
8423static struct hda_verb alc885_mba21_init_verbs[] = {
8424 /*Internal and HP Speaker Mixer*/
8425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8428 /*Internal Speaker Pin (0x0c)*/
8429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8431 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8432 /* HP Pin: output 0 (0x0e) */
8433 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8434 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8435 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8436 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8437 /* Line in (is hp when jack connected)*/
8438 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8439 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8440
8441 { }
8442 };
8443
8444
87350ad0
TI
8445/* Macbook Pro rev3 */
8446static struct hda_verb alc885_mbp3_init_verbs[] = {
8447 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8448 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8449 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8451 /* Rear mixer */
8452 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8453 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8454 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8455 /* HP mixer */
8456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8457 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8458 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8459 /* Front Pin: output 0 (0x0c) */
8460 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8461 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8462 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8463 /* HP Pin: output 0 (0x0e) */
87350ad0 8464 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8465 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8466 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8467 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8468 /* Mic (rear) pin: input vref at 80% */
8469 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8470 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8471 /* Front Mic pin: input vref at 80% */
8472 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8473 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8474 /* Line In pin: use output 1 when in LineOut mode */
8475 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8476 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8477 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8478
8479 /* FIXME: use matrix-type input source selection */
8480 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8481 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8482 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8483 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8484 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8485 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8486 /* Input mixer2 */
8487 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8488 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8489 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8490 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8491 /* Input mixer3 */
8492 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8493 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8496 /* ADC1: mute amp left and right */
8497 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8498 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8499 /* ADC2: mute amp left and right */
8500 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8501 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8502 /* ADC3: mute amp left and right */
8503 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8504 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8505
8506 { }
8507};
8508
4b7e1803
JM
8509/* iMac 9,1 */
8510static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8511 /* Internal Speaker Pin (0x0c) */
8512 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8514 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8515 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8516 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8517 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8518 /* HP Pin: Rear */
4b7e1803
JM
8519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8520 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8521 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8522 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8523 /* Line in Rear */
8524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8525 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8526 /* Front Mic pin: input vref at 80% */
8527 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8528 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8529 /* Rear mixer */
8530 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8531 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8533 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8534 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8535 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8537 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8538 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8539 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8540 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8541 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8542 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8543 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8545 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8546 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8547 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8548 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8549 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8550 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8551 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8552 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8553 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8554 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8555 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8557 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8558 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8560 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8561 { }
8562};
8563
c54728d8
NF
8564/* iMac 24 mixer. */
8565static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8566 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8567 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8568 { } /* end */
8569};
8570
8571/* iMac 24 init verbs. */
8572static struct hda_verb alc885_imac24_init_verbs[] = {
8573 /* Internal speakers: output 0 (0x0c) */
8574 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8575 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8576 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8577 /* Internal speakers: output 0 (0x0c) */
8578 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8579 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8580 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8581 /* Headphone: output 0 (0x0c) */
8582 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8583 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8584 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8585 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8586 /* Front Mic: input vref at 80% */
8587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8589 { }
8590};
8591
8592/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8593static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8594{
a9fd4f3f 8595 struct alc_spec *spec = codec->spec;
c54728d8 8596
a9fd4f3f
TI
8597 spec->autocfg.hp_pins[0] = 0x14;
8598 spec->autocfg.speaker_pins[0] = 0x18;
8599 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8600}
8601
9d54f08b
TI
8602#define alc885_mb5_setup alc885_imac24_setup
8603#define alc885_macmini3_setup alc885_imac24_setup
8604
76e6f5a9
RH
8605/* Macbook Air 2,1 */
8606static void alc885_mba21_setup(struct hda_codec *codec)
8607{
8608 struct alc_spec *spec = codec->spec;
8609
8610 spec->autocfg.hp_pins[0] = 0x14;
8611 spec->autocfg.speaker_pins[0] = 0x18;
8612}
8613
8614
8615
4f5d1706 8616static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8617{
a9fd4f3f 8618 struct alc_spec *spec = codec->spec;
87350ad0 8619
a9fd4f3f
TI
8620 spec->autocfg.hp_pins[0] = 0x15;
8621 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8622}
8623
9d54f08b 8624static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8625{
9d54f08b 8626 struct alc_spec *spec = codec->spec;
4b7e1803 8627
9d54f08b 8628 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8629 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8630 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8631}
87350ad0 8632
272a527c
KY
8633static struct hda_verb alc882_targa_verbs[] = {
8634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8636
8637 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8638 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8639
272a527c
KY
8640 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8641 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8642 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8643
8644 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8645 { } /* end */
8646};
8647
8648/* toggle speaker-output according to the hp-jack state */
8649static void alc882_targa_automute(struct hda_codec *codec)
8650{
a9fd4f3f
TI
8651 struct alc_spec *spec = codec->spec;
8652 alc_automute_amp(codec);
82beb8fd 8653 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8654 spec->jack_present ? 1 : 3);
8655}
8656
4f5d1706 8657static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8658{
8659 struct alc_spec *spec = codec->spec;
8660
8661 spec->autocfg.hp_pins[0] = 0x14;
8662 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8663}
8664
8665static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8666{
a9fd4f3f 8667 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8668 alc882_targa_automute(codec);
272a527c
KY
8669}
8670
8671static struct hda_verb alc882_asus_a7j_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
272a527c
KY
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
914759b7
TI
8689static struct hda_verb alc882_asus_a7m_verbs[] = {
8690 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8691 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8692
8693 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8694 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8695 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8696
914759b7
TI
8697 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8698 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8699 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8700
8701 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8702 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8703 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8704 { } /* end */
8705};
8706
9102cd1c
TD
8707static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8708{
8709 unsigned int gpiostate, gpiomask, gpiodir;
8710
8711 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8712 AC_VERB_GET_GPIO_DATA, 0);
8713
8714 if (!muted)
8715 gpiostate |= (1 << pin);
8716 else
8717 gpiostate &= ~(1 << pin);
8718
8719 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8720 AC_VERB_GET_GPIO_MASK, 0);
8721 gpiomask |= (1 << pin);
8722
8723 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8724 AC_VERB_GET_GPIO_DIRECTION, 0);
8725 gpiodir |= (1 << pin);
8726
8727
8728 snd_hda_codec_write(codec, codec->afg, 0,
8729 AC_VERB_SET_GPIO_MASK, gpiomask);
8730 snd_hda_codec_write(codec, codec->afg, 0,
8731 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8732
8733 msleep(1);
8734
8735 snd_hda_codec_write(codec, codec->afg, 0,
8736 AC_VERB_SET_GPIO_DATA, gpiostate);
8737}
8738
7debbe51
TI
8739/* set up GPIO at initialization */
8740static void alc885_macpro_init_hook(struct hda_codec *codec)
8741{
8742 alc882_gpio_mute(codec, 0, 0);
8743 alc882_gpio_mute(codec, 1, 0);
8744}
8745
8746/* set up GPIO and update auto-muting at initialization */
8747static void alc885_imac24_init_hook(struct hda_codec *codec)
8748{
8749 alc885_macpro_init_hook(codec);
4f5d1706 8750 alc_automute_amp(codec);
7debbe51
TI
8751}
8752
df694daa
KY
8753/*
8754 * generic initialization of ADC, input mixers and output mixers
8755 */
4953550a 8756static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8757 /*
8758 * Unmute ADC0-2 and set the default input to mic-in
8759 */
4953550a
TI
8760 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8761 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8762 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8763 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8764
4953550a
TI
8765 /*
8766 * Set up output mixers (0x0c - 0x0f)
8767 */
8768 /* set vol=0 to output mixers */
8769 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8770 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8771 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8772 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8773 /* set up input amps for analog loopback */
8774 /* Amp Indices: DAC = 0, mixer = 1 */
8775 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8776 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8777 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8778 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8779 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8780 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8781 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8782 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8783 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8784 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8785
4953550a
TI
8786 /* FIXME: use matrix-type input source selection */
8787 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8788 /* Input mixer2 */
88102f3f 8789 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8790 /* Input mixer3 */
88102f3f 8791 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8792 { }
9c7f852e
TI
8793};
8794
eb4c41d3
TS
8795/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8796static struct hda_verb alc889A_mb31_ch2_init[] = {
8797 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
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/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8805static struct hda_verb alc889A_mb31_ch4_init[] = {
8806 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8807 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
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
8813/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8814static struct hda_verb alc889A_mb31_ch5_init[] = {
8815 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8816 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8817 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8818 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8819 { } /* end */
8820};
8821
8822/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8823static struct hda_verb alc889A_mb31_ch6_init[] = {
8824 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8825 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8826 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8827 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8828 { } /* end */
8829};
8830
8831static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8832 { 2, alc889A_mb31_ch2_init },
8833 { 4, alc889A_mb31_ch4_init },
8834 { 5, alc889A_mb31_ch5_init },
8835 { 6, alc889A_mb31_ch6_init },
8836};
8837
b373bdeb
AN
8838static struct hda_verb alc883_medion_eapd_verbs[] = {
8839 /* eanable EAPD on medion laptop */
8840 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8841 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8842 { }
8843};
8844
4953550a 8845#define alc883_base_mixer alc882_base_mixer
834be88d 8846
a8848bd6
AS
8847static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8848 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8849 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8850 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8851 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8852 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8853 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8854 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8856 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8858 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8859 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8860 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8861 { } /* end */
8862};
8863
0c4cc443 8864static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8865 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8866 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8867 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8868 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8869 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8870 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8871 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8872 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8873 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8874 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8875 { } /* end */
8876};
8877
fb97dc67
J
8878static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8879 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8880 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8881 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8882 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8883 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8884 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8885 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8886 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8887 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8888 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8889 { } /* end */
8890};
8891
9c7f852e
TI
8892static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8893 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8894 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8895 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8896 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8897 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8898 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8899 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8900 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8901 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8903 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8904 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8905 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8906 { } /* end */
8907};
df694daa 8908
9c7f852e
TI
8909static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8910 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8911 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8912 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8913 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8914 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8915 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8916 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8917 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8918 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8919 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8920 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8921 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8922 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8923 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8924 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8925 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8926 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8927 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8928 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8929 { } /* end */
8930};
8931
17bba1b7
J
8932static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8933 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8934 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8935 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8936 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8937 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8938 HDA_OUTPUT),
8939 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8940 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8941 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8942 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8943 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8944 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8945 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8946 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8947 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8948 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
8949 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8950 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8951 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 8952 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8953 { } /* end */
8954};
8955
87a8c370
JK
8956static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8957 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8958 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8959 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8960 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8961 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8962 HDA_OUTPUT),
8963 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8964 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8965 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8966 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8967 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8968 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 8972 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
8973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8974 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8975 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
8976 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8977 { } /* end */
8978};
8979
d1d985f0 8980static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8981 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8982 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8983 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8984 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8985 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8986 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8987 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8988 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8989 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8990 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8991 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8992 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8993 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8995 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
8996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8997 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8998 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 8999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9000 { } /* end */
9001};
9002
c259249f 9003static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9004 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9005 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9006 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9007 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9008 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9009 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9010 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9011 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9012 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9013 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9014 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9015 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9016 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9017 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9018 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9019 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9021 { } /* end */
f12ab1e0 9022};
ccc656ce 9023
c259249f 9024static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9025 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9026 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9027 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9028 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9029 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9030 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9031 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9032 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9033 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9034 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9035 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9036 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9037 { } /* end */
f12ab1e0 9038};
ccc656ce 9039
b99dba34
TI
9040static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9041 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9042 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9043 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9044 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9045 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9046 { } /* end */
9047};
9048
bc9f98a9
KY
9049static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9050 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9051 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9052 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9053 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9054 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9055 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9056 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9057 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9058 { } /* end */
f12ab1e0 9059};
bc9f98a9 9060
272a527c
KY
9061static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9062 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9063 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9064 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9065 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9066 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9069 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9070 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9071 { } /* end */
ea1fb29a 9072};
272a527c 9073
7ad7b218
MC
9074static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9075 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9076 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9077 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9078 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9079 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9080 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9081 { } /* end */
9082};
9083
9084static struct hda_verb alc883_medion_wim2160_verbs[] = {
9085 /* Unmute front mixer */
9086 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9087 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9088
9089 /* Set speaker pin to front mixer */
9090 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9091
9092 /* Init headphone pin */
9093 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9094 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9095 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9096 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9097
9098 { } /* end */
9099};
9100
9101/* toggle speaker-output according to the hp-jack state */
9102static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9103{
9104 struct alc_spec *spec = codec->spec;
9105
9106 spec->autocfg.hp_pins[0] = 0x1a;
9107 spec->autocfg.speaker_pins[0] = 0x15;
9108}
9109
2880a867 9110static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9111 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9112 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9113 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9114 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9115 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9117 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9119 { } /* end */
d1a991a6 9120};
2880a867 9121
d2fd4b09
TV
9122static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9123 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9124 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9127 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9128 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9129 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9130 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9131 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9132 { } /* end */
9133};
9134
e2757d5e
KY
9135static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9137 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9138 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9139 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9140 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9141 0x0d, 1, 0x0, HDA_OUTPUT),
9142 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9143 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9144 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9146 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9147 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9148 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9149 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9150 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9151 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9152 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9153 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9154 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9155 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9156 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9157 { } /* end */
9158};
9159
eb4c41d3
TS
9160static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9161 /* Output mixers */
9162 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9163 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9164 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9165 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9166 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9167 HDA_OUTPUT),
9168 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9169 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9170 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9171 /* Output switches */
9172 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9173 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9174 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9175 /* Boost mixers */
5f99f86a
DH
9176 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9177 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9178 /* Input mixers */
9179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9180 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9181 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9182 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9183 { } /* end */
9184};
9185
3e1647c5
GG
9186static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9187 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9188 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9189 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9191 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9193 { } /* end */
9194};
9195
e2757d5e
KY
9196static struct hda_bind_ctls alc883_bind_cap_vol = {
9197 .ops = &snd_hda_bind_vol,
9198 .values = {
9199 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9200 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9201 0
9202 },
9203};
9204
9205static struct hda_bind_ctls alc883_bind_cap_switch = {
9206 .ops = &snd_hda_bind_sw,
9207 .values = {
9208 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9209 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9210 0
9211 },
9212};
9213
9214static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9215 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9216 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9217 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9218 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9219 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9221 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9223 { } /* end */
9224};
df694daa 9225
4953550a
TI
9226static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9227 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9228 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9229 {
9230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9231 /* .name = "Capture Source", */
9232 .name = "Input Source",
9233 .count = 1,
9234 .info = alc_mux_enum_info,
9235 .get = alc_mux_enum_get,
9236 .put = alc_mux_enum_put,
9237 },
9238 { } /* end */
9239};
9c7f852e 9240
4953550a
TI
9241static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9242 {
9243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9244 .name = "Channel Mode",
9245 .info = alc_ch_mode_info,
9246 .get = alc_ch_mode_get,
9247 .put = alc_ch_mode_put,
9248 },
9249 { } /* end */
9c7f852e
TI
9250};
9251
a8848bd6 9252/* toggle speaker-output according to the hp-jack state */
4f5d1706 9253static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9254{
a9fd4f3f 9255 struct alc_spec *spec = codec->spec;
a8848bd6 9256
a9fd4f3f
TI
9257 spec->autocfg.hp_pins[0] = 0x15;
9258 spec->autocfg.speaker_pins[0] = 0x14;
9259 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9260}
9261
a8848bd6
AS
9262static struct hda_verb alc883_mitac_verbs[] = {
9263 /* HP */
9264 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9265 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9266 /* Subwoofer */
9267 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9268 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9269
9270 /* enable unsolicited event */
9271 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9272 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9273
9274 { } /* end */
9275};
9276
a65cc60f 9277static struct hda_verb alc883_clevo_m540r_verbs[] = {
9278 /* HP */
9279 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9280 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9281 /* Int speaker */
9282 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9283
9284 /* enable unsolicited event */
9285 /*
9286 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9287 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9288 */
9289
9290 { } /* end */
9291};
9292
0c4cc443 9293static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9294 /* HP */
9295 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9296 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9297 /* Int speaker */
9298 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9299 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9300
9301 /* enable unsolicited event */
9302 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9303 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9304
9305 { } /* end */
9306};
9307
fb97dc67
J
9308static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9309 /* HP */
9310 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9311 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9312 /* Subwoofer */
9313 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9314 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9315
9316 /* enable unsolicited event */
9317 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9318
9319 { } /* end */
9320};
9321
c259249f 9322static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9325
9326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9327 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9328
64a8be74
DH
9329/* Connect Line-Out side jack (SPDIF) to Side */
9330 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9331 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9332 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9333/* Connect Mic jack to CLFE */
9334 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9335 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9336 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9337/* Connect Line-in jack to Surround */
9338 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9339 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9340 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9341/* Connect HP out jack to Front */
9342 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9343 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9344 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9345
9346 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9347
9348 { } /* end */
9349};
9350
bc9f98a9
KY
9351static struct hda_verb alc883_lenovo_101e_verbs[] = {
9352 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9353 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9354 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9355 { } /* end */
9356};
9357
272a527c
KY
9358static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9359 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9361 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9362 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9363 { } /* end */
9364};
9365
9366static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9369 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9370 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9371 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9372 { } /* end */
9373};
9374
189609ae
KY
9375static struct hda_verb alc883_haier_w66_verbs[] = {
9376 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9377 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9378
9379 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9380
9381 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9382 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9383 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9384 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9385 { } /* end */
9386};
9387
e2757d5e
KY
9388static struct hda_verb alc888_lenovo_sky_verbs[] = {
9389 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9390 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9391 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9392 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9393 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9394 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9395 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9396 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9397 { } /* end */
9398};
9399
8718b700
HRK
9400static struct hda_verb alc888_6st_dell_verbs[] = {
9401 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9402 { }
9403};
9404
3e1647c5
GG
9405static struct hda_verb alc883_vaiott_verbs[] = {
9406 /* HP */
9407 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9408 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9409
9410 /* enable unsolicited event */
9411 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9412
9413 { } /* end */
9414};
9415
4f5d1706 9416static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9417{
a9fd4f3f 9418 struct alc_spec *spec = codec->spec;
8718b700 9419
a9fd4f3f
TI
9420 spec->autocfg.hp_pins[0] = 0x1b;
9421 spec->autocfg.speaker_pins[0] = 0x14;
9422 spec->autocfg.speaker_pins[1] = 0x16;
9423 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9424}
9425
4723c022 9426static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9427 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9428 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9429 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9430 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9431 { } /* end */
5795b9e6
CM
9432};
9433
3ea0d7cf
HRK
9434/*
9435 * 2ch mode
9436 */
4723c022 9437static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9438 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9439 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9440 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9441 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9442 { } /* end */
8341de60
CM
9443};
9444
3ea0d7cf
HRK
9445/*
9446 * 4ch mode
9447 */
9448static struct hda_verb alc888_3st_hp_4ch_init[] = {
9449 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9450 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9451 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9452 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9453 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9454 { } /* end */
9455};
9456
9457/*
9458 * 6ch mode
9459 */
4723c022 9460static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9461 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9462 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9463 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9464 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9465 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9466 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9467 { } /* end */
8341de60
CM
9468};
9469
3ea0d7cf 9470static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9471 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9472 { 4, alc888_3st_hp_4ch_init },
4723c022 9473 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9474};
9475
272a527c
KY
9476/* toggle front-jack and RCA according to the hp-jack state */
9477static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9478{
864f92be 9479 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9480
47fd830a
TI
9481 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9482 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9483 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9484 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9485}
9486
9487/* toggle RCA according to the front-jack state */
9488static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9489{
864f92be 9490 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9491
47fd830a
TI
9492 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9493 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9494}
47fd830a 9495
272a527c
KY
9496static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9497 unsigned int res)
9498{
9499 if ((res >> 26) == ALC880_HP_EVENT)
9500 alc888_lenovo_ms7195_front_automute(codec);
9501 if ((res >> 26) == ALC880_FRONT_EVENT)
9502 alc888_lenovo_ms7195_rca_automute(codec);
9503}
9504
272a527c 9505/* toggle speaker-output according to the hp-jack state */
dc427170 9506static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9507{
a9fd4f3f 9508 struct alc_spec *spec = codec->spec;
272a527c 9509
a9fd4f3f
TI
9510 spec->autocfg.hp_pins[0] = 0x14;
9511 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9512}
9513
ccc656ce 9514/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9515#define alc883_targa_init_hook alc882_targa_init_hook
9516#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9517
4f5d1706 9518static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9519{
a9fd4f3f
TI
9520 struct alc_spec *spec = codec->spec;
9521
9522 spec->autocfg.hp_pins[0] = 0x15;
9523 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9524}
9525
9526static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9527{
a9fd4f3f 9528 alc_automute_amp(codec);
eeb43387 9529 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9530}
9531
9532static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9533 unsigned int res)
9534{
0c4cc443 9535 switch (res >> 26) {
0c4cc443 9536 case ALC880_MIC_EVENT:
eeb43387 9537 alc88x_simple_mic_automute(codec);
0c4cc443 9538 break;
a9fd4f3f
TI
9539 default:
9540 alc_automute_amp_unsol_event(codec, res);
9541 break;
0c4cc443 9542 }
368c7a95
J
9543}
9544
fb97dc67 9545/* toggle speaker-output according to the hp-jack state */
4f5d1706 9546static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9547{
a9fd4f3f 9548 struct alc_spec *spec = codec->spec;
fb97dc67 9549
a9fd4f3f
TI
9550 spec->autocfg.hp_pins[0] = 0x14;
9551 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9552}
9553
4f5d1706 9554static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9555{
a9fd4f3f 9556 struct alc_spec *spec = codec->spec;
189609ae 9557
a9fd4f3f
TI
9558 spec->autocfg.hp_pins[0] = 0x1b;
9559 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9560}
9561
bc9f98a9
KY
9562static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9563{
864f92be 9564 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9565
47fd830a
TI
9566 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9567 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9568}
9569
9570static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9571{
864f92be 9572 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9573
47fd830a
TI
9574 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9575 HDA_AMP_MUTE, bits);
9576 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9577 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9578}
9579
9580static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9581 unsigned int res)
9582{
9583 if ((res >> 26) == ALC880_HP_EVENT)
9584 alc883_lenovo_101e_all_automute(codec);
9585 if ((res >> 26) == ALC880_FRONT_EVENT)
9586 alc883_lenovo_101e_ispeaker_automute(codec);
9587}
9588
676a9b53 9589/* toggle speaker-output according to the hp-jack state */
4f5d1706 9590static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9591{
a9fd4f3f 9592 struct alc_spec *spec = codec->spec;
676a9b53 9593
a9fd4f3f
TI
9594 spec->autocfg.hp_pins[0] = 0x14;
9595 spec->autocfg.speaker_pins[0] = 0x15;
9596 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9597}
9598
d1a991a6
KY
9599static struct hda_verb alc883_acer_eapd_verbs[] = {
9600 /* HP Pin: output 0 (0x0c) */
9601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9602 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9603 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9604 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9605 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9606 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9607 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9608 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9609 /* eanable EAPD on medion laptop */
9610 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9611 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9612 /* enable unsolicited event */
9613 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9614 { }
9615};
9616
4f5d1706 9617static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9618{
a9fd4f3f 9619 struct alc_spec *spec = codec->spec;
5795b9e6 9620
a9fd4f3f
TI
9621 spec->autocfg.hp_pins[0] = 0x1b;
9622 spec->autocfg.speaker_pins[0] = 0x14;
9623 spec->autocfg.speaker_pins[1] = 0x15;
9624 spec->autocfg.speaker_pins[2] = 0x16;
9625 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9626}
9627
4f5d1706 9628static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9629{
a9fd4f3f 9630 struct alc_spec *spec = codec->spec;
e2757d5e 9631
a9fd4f3f
TI
9632 spec->autocfg.hp_pins[0] = 0x1b;
9633 spec->autocfg.speaker_pins[0] = 0x14;
9634 spec->autocfg.speaker_pins[1] = 0x15;
9635 spec->autocfg.speaker_pins[2] = 0x16;
9636 spec->autocfg.speaker_pins[3] = 0x17;
9637 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9638}
9639
4f5d1706 9640static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9641{
9642 struct alc_spec *spec = codec->spec;
9643
9644 spec->autocfg.hp_pins[0] = 0x15;
9645 spec->autocfg.speaker_pins[0] = 0x14;
9646 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9647}
9648
e2757d5e
KY
9649static struct hda_verb alc888_asus_m90v_verbs[] = {
9650 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9651 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9652 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9653 /* enable unsolicited event */
9654 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9655 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9656 { } /* end */
9657};
9658
4f5d1706 9659static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9660{
a9fd4f3f 9661 struct alc_spec *spec = codec->spec;
e2757d5e 9662
a9fd4f3f
TI
9663 spec->autocfg.hp_pins[0] = 0x1b;
9664 spec->autocfg.speaker_pins[0] = 0x14;
9665 spec->autocfg.speaker_pins[1] = 0x15;
9666 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9667 spec->ext_mic.pin = 0x18;
9668 spec->int_mic.pin = 0x19;
9669 spec->ext_mic.mux_idx = 0;
9670 spec->int_mic.mux_idx = 1;
9671 spec->auto_mic = 1;
e2757d5e
KY
9672}
9673
9674static struct hda_verb alc888_asus_eee1601_verbs[] = {
9675 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9676 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9678 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9679 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9680 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9681 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9682 /* enable unsolicited event */
9683 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9684 { } /* end */
9685};
9686
e2757d5e
KY
9687static void alc883_eee1601_inithook(struct hda_codec *codec)
9688{
a9fd4f3f
TI
9689 struct alc_spec *spec = codec->spec;
9690
9691 spec->autocfg.hp_pins[0] = 0x14;
9692 spec->autocfg.speaker_pins[0] = 0x1b;
9693 alc_automute_pin(codec);
e2757d5e
KY
9694}
9695
eb4c41d3
TS
9696static struct hda_verb alc889A_mb31_verbs[] = {
9697 /* Init rear pin (used as headphone output) */
9698 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9699 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9700 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9701 /* Init line pin (used as output in 4ch and 6ch mode) */
9702 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9703 /* Init line 2 pin (used as headphone out by default) */
9704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9706 { } /* end */
9707};
9708
9709/* Mute speakers according to the headphone jack state */
9710static void alc889A_mb31_automute(struct hda_codec *codec)
9711{
9712 unsigned int present;
9713
9714 /* Mute only in 2ch or 4ch mode */
9715 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9716 == 0x00) {
864f92be 9717 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9718 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9719 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9720 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9721 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9722 }
9723}
9724
9725static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9726{
9727 if ((res >> 26) == ALC880_HP_EVENT)
9728 alc889A_mb31_automute(codec);
9729}
9730
4953550a 9731
cb53c626 9732#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9733#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9734#endif
9735
def319f9 9736/* pcm configuration: identical with ALC880 */
4953550a
TI
9737#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9738#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9739#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9740#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9741
9742static hda_nid_t alc883_slave_dig_outs[] = {
9743 ALC1200_DIGOUT_NID, 0,
9744};
9745
9746static hda_nid_t alc1200_slave_dig_outs[] = {
9747 ALC883_DIGOUT_NID, 0,
9748};
9c7f852e
TI
9749
9750/*
9751 * configuration and preset
9752 */
ea734963 9753static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9754 [ALC882_3ST_DIG] = "3stack-dig",
9755 [ALC882_6ST_DIG] = "6stack-dig",
9756 [ALC882_ARIMA] = "arima",
9757 [ALC882_W2JC] = "w2jc",
9758 [ALC882_TARGA] = "targa",
9759 [ALC882_ASUS_A7J] = "asus-a7j",
9760 [ALC882_ASUS_A7M] = "asus-a7m",
9761 [ALC885_MACPRO] = "macpro",
9762 [ALC885_MB5] = "mb5",
e458b1fa 9763 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9764 [ALC885_MBA21] = "mba21",
4953550a
TI
9765 [ALC885_MBP3] = "mbp3",
9766 [ALC885_IMAC24] = "imac24",
4b7e1803 9767 [ALC885_IMAC91] = "imac91",
4953550a 9768 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9769 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9770 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9771 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9772 [ALC883_TARGA_DIG] = "targa-dig",
9773 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9774 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9775 [ALC883_ACER] = "acer",
2880a867 9776 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9777 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9778 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9779 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9780 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9781 [ALC883_MEDION] = "medion",
7ad7b218 9782 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9783 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9784 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9785 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9786 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9787 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9788 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9789 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9790 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9791 [ALC883_MITAC] = "mitac",
a65cc60f 9792 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9793 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9794 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9795 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9796 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9797 [ALC889A_INTEL] = "intel-alc889a",
9798 [ALC889_INTEL] = "intel-x58",
3ab90935 9799 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9800 [ALC889A_MB31] = "mb31",
3e1647c5 9801 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9802 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9803};
9804
4953550a
TI
9805static struct snd_pci_quirk alc882_cfg_tbl[] = {
9806 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9807
ac3e3741 9808 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9809 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9810 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9811 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9812 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9813 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9814 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9815 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9816 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9817 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9818 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9819 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9820 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9821 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9822 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9823 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9824 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9825 ALC888_ACER_ASPIRE_6530G),
cc374c47 9826 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9827 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9828 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9829 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9830 /* default Acer -- disabled as it causes more problems.
9831 * model=auto should work fine now
9832 */
9833 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9834
5795b9e6 9835 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9836
febe3375 9837 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9838 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9839 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9840 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9841 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9842 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9843
9844 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9845 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9846 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9847 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9848 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9849 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9850 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9851 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9852 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9853 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9854 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9855
9856 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9857 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9858 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9859 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9860 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9861 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9862 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9863 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9864 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9865
6f3bf657 9866 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9867 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9868 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9869 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9870 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9871 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9872 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9873 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9874 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9875 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9876 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9877 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9878 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9879 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9880 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9881 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9882 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9883 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9884 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9885 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9886 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9887 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9888 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9889 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9890 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9891 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9892 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9893 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9894 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9895 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9896 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9897
ac3e3741 9898 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9899 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9900 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9901 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9902 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9903 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9904 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9905 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9906 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9907 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9908 ALC883_FUJITSU_PI2515),
bfb53037 9909 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9910 ALC888_FUJITSU_XA3530),
272a527c 9911 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9912 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9913 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9914 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9915 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9916 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9917 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9918 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9919
17bba1b7
J
9920 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9921 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9922 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9923 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9924 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9925 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9926 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9927
4953550a 9928 {}
f3cd3f5d
WF
9929};
9930
4953550a
TI
9931/* codec SSID table for Intel Mac */
9932static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9933 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9934 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9935 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9936 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9937 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9938 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9939 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9940 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9941 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9942 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9943 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9944 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9945 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9946 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9947 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9948 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9949 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9950 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9951 * so apparently no perfect solution yet
4953550a
TI
9952 */
9953 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9954 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9955 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9956 {} /* terminator */
b25c9da1
WF
9957};
9958
4953550a
TI
9959static struct alc_config_preset alc882_presets[] = {
9960 [ALC882_3ST_DIG] = {
9961 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9962 .init_verbs = { alc882_base_init_verbs,
9963 alc882_adc1_init_verbs },
4953550a
TI
9964 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9965 .dac_nids = alc882_dac_nids,
9966 .dig_out_nid = ALC882_DIGOUT_NID,
9967 .dig_in_nid = ALC882_DIGIN_NID,
9968 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9969 .channel_mode = alc882_ch_modes,
9970 .need_dac_fix = 1,
9971 .input_mux = &alc882_capture_source,
9972 },
9973 [ALC882_6ST_DIG] = {
9974 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9975 .init_verbs = { alc882_base_init_verbs,
9976 alc882_adc1_init_verbs },
4953550a
TI
9977 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9978 .dac_nids = alc882_dac_nids,
9979 .dig_out_nid = ALC882_DIGOUT_NID,
9980 .dig_in_nid = ALC882_DIGIN_NID,
9981 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9982 .channel_mode = alc882_sixstack_modes,
9983 .input_mux = &alc882_capture_source,
9984 },
9985 [ALC882_ARIMA] = {
9986 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9987 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9988 alc882_eapd_verbs },
4953550a
TI
9989 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9990 .dac_nids = alc882_dac_nids,
9991 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9992 .channel_mode = alc882_sixstack_modes,
9993 .input_mux = &alc882_capture_source,
9994 },
9995 [ALC882_W2JC] = {
9996 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9997 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9998 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9999 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10000 .dac_nids = alc882_dac_nids,
10001 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10002 .channel_mode = alc880_threestack_modes,
10003 .need_dac_fix = 1,
10004 .input_mux = &alc882_capture_source,
10005 .dig_out_nid = ALC882_DIGOUT_NID,
10006 },
76e6f5a9
RH
10007 [ALC885_MBA21] = {
10008 .mixers = { alc885_mba21_mixer },
10009 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10010 .num_dacs = 2,
10011 .dac_nids = alc882_dac_nids,
10012 .channel_mode = alc885_mba21_ch_modes,
10013 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10014 .input_mux = &alc882_capture_source,
10015 .unsol_event = alc_automute_amp_unsol_event,
10016 .setup = alc885_mba21_setup,
10017 .init_hook = alc_automute_amp,
10018 },
4953550a
TI
10019 [ALC885_MBP3] = {
10020 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10021 .init_verbs = { alc885_mbp3_init_verbs,
10022 alc880_gpio1_init_verbs },
be0ae923 10023 .num_dacs = 2,
4953550a 10024 .dac_nids = alc882_dac_nids,
be0ae923
TI
10025 .hp_nid = 0x04,
10026 .channel_mode = alc885_mbp_4ch_modes,
10027 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10028 .input_mux = &alc882_capture_source,
10029 .dig_out_nid = ALC882_DIGOUT_NID,
10030 .dig_in_nid = ALC882_DIGIN_NID,
10031 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10032 .setup = alc885_mbp3_setup,
10033 .init_hook = alc_automute_amp,
4953550a
TI
10034 },
10035 [ALC885_MB5] = {
10036 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10037 .init_verbs = { alc885_mb5_init_verbs,
10038 alc880_gpio1_init_verbs },
10039 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10040 .dac_nids = alc882_dac_nids,
10041 .channel_mode = alc885_mb5_6ch_modes,
10042 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10043 .input_mux = &mb5_capture_source,
10044 .dig_out_nid = ALC882_DIGOUT_NID,
10045 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10046 .unsol_event = alc_automute_amp_unsol_event,
10047 .setup = alc885_mb5_setup,
10048 .init_hook = alc_automute_amp,
4953550a 10049 },
e458b1fa
LY
10050 [ALC885_MACMINI3] = {
10051 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10052 .init_verbs = { alc885_macmini3_init_verbs,
10053 alc880_gpio1_init_verbs },
10054 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10055 .dac_nids = alc882_dac_nids,
10056 .channel_mode = alc885_macmini3_6ch_modes,
10057 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10058 .input_mux = &macmini3_capture_source,
10059 .dig_out_nid = ALC882_DIGOUT_NID,
10060 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10061 .unsol_event = alc_automute_amp_unsol_event,
10062 .setup = alc885_macmini3_setup,
10063 .init_hook = alc_automute_amp,
e458b1fa 10064 },
4953550a
TI
10065 [ALC885_MACPRO] = {
10066 .mixers = { alc882_macpro_mixer },
10067 .init_verbs = { alc882_macpro_init_verbs },
10068 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10069 .dac_nids = alc882_dac_nids,
10070 .dig_out_nid = ALC882_DIGOUT_NID,
10071 .dig_in_nid = ALC882_DIGIN_NID,
10072 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10073 .channel_mode = alc882_ch_modes,
10074 .input_mux = &alc882_capture_source,
10075 .init_hook = alc885_macpro_init_hook,
10076 },
10077 [ALC885_IMAC24] = {
10078 .mixers = { alc885_imac24_mixer },
10079 .init_verbs = { alc885_imac24_init_verbs },
10080 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10081 .dac_nids = alc882_dac_nids,
10082 .dig_out_nid = ALC882_DIGOUT_NID,
10083 .dig_in_nid = ALC882_DIGIN_NID,
10084 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10085 .channel_mode = alc882_ch_modes,
10086 .input_mux = &alc882_capture_source,
10087 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 10088 .setup = alc885_imac24_setup,
4953550a
TI
10089 .init_hook = alc885_imac24_init_hook,
10090 },
4b7e1803 10091 [ALC885_IMAC91] = {
b7cccc52 10092 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10093 .init_verbs = { alc885_imac91_init_verbs,
10094 alc880_gpio1_init_verbs },
10095 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10096 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10097 .channel_mode = alc885_mba21_ch_modes,
10098 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10099 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10100 .dig_out_nid = ALC882_DIGOUT_NID,
10101 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10102 .unsol_event = alc_automute_amp_unsol_event,
10103 .setup = alc885_imac91_setup,
10104 .init_hook = alc_automute_amp,
4b7e1803 10105 },
4953550a
TI
10106 [ALC882_TARGA] = {
10107 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10108 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10109 alc880_gpio3_init_verbs, alc882_targa_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 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10121 .setup = alc882_targa_setup,
10122 .init_hook = alc882_targa_automute,
4953550a
TI
10123 },
10124 [ALC882_ASUS_A7J] = {
10125 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10126 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10127 alc882_asus_a7j_verbs},
4953550a
TI
10128 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10129 .dac_nids = alc882_dac_nids,
10130 .dig_out_nid = ALC882_DIGOUT_NID,
10131 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10132 .adc_nids = alc882_adc_nids,
10133 .capsrc_nids = alc882_capsrc_nids,
10134 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10135 .channel_mode = alc882_3ST_6ch_modes,
10136 .need_dac_fix = 1,
10137 .input_mux = &alc882_capture_source,
10138 },
10139 [ALC882_ASUS_A7M] = {
10140 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10141 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10142 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10143 alc882_asus_a7m_verbs },
10144 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10145 .dac_nids = alc882_dac_nids,
10146 .dig_out_nid = ALC882_DIGOUT_NID,
10147 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10148 .channel_mode = alc880_threestack_modes,
10149 .need_dac_fix = 1,
10150 .input_mux = &alc882_capture_source,
10151 },
9c7f852e
TI
10152 [ALC883_3ST_2ch_DIG] = {
10153 .mixers = { alc883_3ST_2ch_mixer },
10154 .init_verbs = { alc883_init_verbs },
10155 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10156 .dac_nids = alc883_dac_nids,
10157 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10158 .dig_in_nid = ALC883_DIGIN_NID,
10159 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10160 .channel_mode = alc883_3ST_2ch_modes,
10161 .input_mux = &alc883_capture_source,
10162 },
10163 [ALC883_3ST_6ch_DIG] = {
10164 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10165 .init_verbs = { alc883_init_verbs },
10166 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10167 .dac_nids = alc883_dac_nids,
10168 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10169 .dig_in_nid = ALC883_DIGIN_NID,
10170 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10171 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10172 .need_dac_fix = 1,
9c7f852e 10173 .input_mux = &alc883_capture_source,
f12ab1e0 10174 },
9c7f852e
TI
10175 [ALC883_3ST_6ch] = {
10176 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10177 .init_verbs = { alc883_init_verbs },
10178 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10179 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10180 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10181 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10182 .need_dac_fix = 1,
9c7f852e 10183 .input_mux = &alc883_capture_source,
f12ab1e0 10184 },
17bba1b7
J
10185 [ALC883_3ST_6ch_INTEL] = {
10186 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10187 .init_verbs = { alc883_init_verbs },
10188 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10189 .dac_nids = alc883_dac_nids,
10190 .dig_out_nid = ALC883_DIGOUT_NID,
10191 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10192 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10193 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10194 .channel_mode = alc883_3ST_6ch_intel_modes,
10195 .need_dac_fix = 1,
10196 .input_mux = &alc883_3stack_6ch_intel,
10197 },
87a8c370
JK
10198 [ALC889A_INTEL] = {
10199 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10200 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10201 alc_hp15_unsol_verbs },
87a8c370
JK
10202 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10203 .dac_nids = alc883_dac_nids,
10204 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10205 .adc_nids = alc889_adc_nids,
10206 .dig_out_nid = ALC883_DIGOUT_NID,
10207 .dig_in_nid = ALC883_DIGIN_NID,
10208 .slave_dig_outs = alc883_slave_dig_outs,
10209 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10210 .channel_mode = alc889_8ch_intel_modes,
10211 .capsrc_nids = alc889_capsrc_nids,
10212 .input_mux = &alc889_capture_source,
4f5d1706
TI
10213 .setup = alc889_automute_setup,
10214 .init_hook = alc_automute_amp,
6732bd0d 10215 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10216 .need_dac_fix = 1,
10217 },
10218 [ALC889_INTEL] = {
10219 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10220 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10221 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10222 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10223 .dac_nids = alc883_dac_nids,
10224 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10225 .adc_nids = alc889_adc_nids,
10226 .dig_out_nid = ALC883_DIGOUT_NID,
10227 .dig_in_nid = ALC883_DIGIN_NID,
10228 .slave_dig_outs = alc883_slave_dig_outs,
10229 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10230 .channel_mode = alc889_8ch_intel_modes,
10231 .capsrc_nids = alc889_capsrc_nids,
10232 .input_mux = &alc889_capture_source,
4f5d1706 10233 .setup = alc889_automute_setup,
6732bd0d
WF
10234 .init_hook = alc889_intel_init_hook,
10235 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10236 .need_dac_fix = 1,
10237 },
9c7f852e
TI
10238 [ALC883_6ST_DIG] = {
10239 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10240 .init_verbs = { alc883_init_verbs },
10241 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10242 .dac_nids = alc883_dac_nids,
10243 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10244 .dig_in_nid = ALC883_DIGIN_NID,
10245 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10246 .channel_mode = alc883_sixstack_modes,
10247 .input_mux = &alc883_capture_source,
10248 },
ccc656ce 10249 [ALC883_TARGA_DIG] = {
c259249f 10250 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10251 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10252 alc883_targa_verbs},
ccc656ce
KY
10253 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10254 .dac_nids = alc883_dac_nids,
10255 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10256 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10257 .channel_mode = alc883_3ST_6ch_modes,
10258 .need_dac_fix = 1,
10259 .input_mux = &alc883_capture_source,
c259249f 10260 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10261 .setup = alc882_targa_setup,
10262 .init_hook = alc882_targa_automute,
ccc656ce
KY
10263 },
10264 [ALC883_TARGA_2ch_DIG] = {
c259249f 10265 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10266 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10267 alc883_targa_verbs},
ccc656ce
KY
10268 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10269 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10270 .adc_nids = alc883_adc_nids_alt,
10271 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10272 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10273 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10274 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10275 .channel_mode = alc883_3ST_2ch_modes,
10276 .input_mux = &alc883_capture_source,
c259249f 10277 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10278 .setup = alc882_targa_setup,
10279 .init_hook = alc882_targa_automute,
ccc656ce 10280 },
64a8be74 10281 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10282 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10283 alc883_chmode_mixer },
64a8be74 10284 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10285 alc883_targa_verbs },
64a8be74
DH
10286 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10287 .dac_nids = alc883_dac_nids,
10288 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10289 .adc_nids = alc883_adc_nids_rev,
10290 .capsrc_nids = alc883_capsrc_nids_rev,
10291 .dig_out_nid = ALC883_DIGOUT_NID,
10292 .dig_in_nid = ALC883_DIGIN_NID,
10293 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10294 .channel_mode = alc883_4ST_8ch_modes,
10295 .need_dac_fix = 1,
10296 .input_mux = &alc883_capture_source,
c259249f 10297 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10298 .setup = alc882_targa_setup,
10299 .init_hook = alc882_targa_automute,
64a8be74 10300 },
bab282b9 10301 [ALC883_ACER] = {
676a9b53 10302 .mixers = { alc883_base_mixer },
bab282b9
VA
10303 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10304 * and the headphone jack. Turn this on and rely on the
10305 * standard mute methods whenever the user wants to turn
10306 * these outputs off.
10307 */
10308 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10309 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10310 .dac_nids = alc883_dac_nids,
bab282b9
VA
10311 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10312 .channel_mode = alc883_3ST_2ch_modes,
10313 .input_mux = &alc883_capture_source,
10314 },
2880a867 10315 [ALC883_ACER_ASPIRE] = {
676a9b53 10316 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10317 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10318 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10319 .dac_nids = alc883_dac_nids,
10320 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10321 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10322 .channel_mode = alc883_3ST_2ch_modes,
10323 .input_mux = &alc883_capture_source,
a9fd4f3f 10324 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10325 .setup = alc883_acer_aspire_setup,
10326 .init_hook = alc_automute_amp,
d1a991a6 10327 },
5b2d1eca 10328 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10329 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10330 alc883_chmode_mixer },
10331 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10332 alc888_acer_aspire_4930g_verbs },
10333 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10334 .dac_nids = alc883_dac_nids,
10335 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10336 .adc_nids = alc883_adc_nids_rev,
10337 .capsrc_nids = alc883_capsrc_nids_rev,
10338 .dig_out_nid = ALC883_DIGOUT_NID,
10339 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10340 .channel_mode = alc883_3ST_6ch_modes,
10341 .need_dac_fix = 1,
973b8cb0 10342 .const_channel_count = 6,
5b2d1eca 10343 .num_mux_defs =
ef8ef5fb
VP
10344 ARRAY_SIZE(alc888_2_capture_sources),
10345 .input_mux = alc888_2_capture_sources,
d2fd4b09 10346 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10347 .setup = alc888_acer_aspire_4930g_setup,
10348 .init_hook = alc_automute_amp,
d2fd4b09
TV
10349 },
10350 [ALC888_ACER_ASPIRE_6530G] = {
10351 .mixers = { alc888_acer_aspire_6530_mixer },
10352 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10353 alc888_acer_aspire_6530g_verbs },
10354 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10355 .dac_nids = alc883_dac_nids,
10356 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10357 .adc_nids = alc883_adc_nids_rev,
10358 .capsrc_nids = alc883_capsrc_nids_rev,
10359 .dig_out_nid = ALC883_DIGOUT_NID,
10360 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10361 .channel_mode = alc883_3ST_2ch_modes,
10362 .num_mux_defs =
10363 ARRAY_SIZE(alc888_2_capture_sources),
10364 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10365 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10366 .setup = alc888_acer_aspire_6530g_setup,
10367 .init_hook = alc_automute_amp,
5b2d1eca 10368 },
3b315d70 10369 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10370 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10371 alc883_chmode_mixer },
10372 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10373 alc889_acer_aspire_8930g_verbs,
10374 alc889_eapd_verbs},
3b315d70
HM
10375 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10376 .dac_nids = alc883_dac_nids,
018df418
HM
10377 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10378 .adc_nids = alc889_adc_nids,
10379 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10380 .dig_out_nid = ALC883_DIGOUT_NID,
10381 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10382 .channel_mode = alc883_3ST_6ch_modes,
10383 .need_dac_fix = 1,
10384 .const_channel_count = 6,
10385 .num_mux_defs =
018df418
HM
10386 ARRAY_SIZE(alc889_capture_sources),
10387 .input_mux = alc889_capture_sources,
3b315d70 10388 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10389 .setup = alc889_acer_aspire_8930g_setup,
10390 .init_hook = alc_automute_amp,
f5de24b0 10391#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10392 .power_hook = alc_power_eapd,
f5de24b0 10393#endif
3b315d70 10394 },
fc86f954
DK
10395 [ALC888_ACER_ASPIRE_7730G] = {
10396 .mixers = { alc883_3ST_6ch_mixer,
10397 alc883_chmode_mixer },
10398 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10399 alc888_acer_aspire_7730G_verbs },
10400 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10401 .dac_nids = alc883_dac_nids,
10402 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10403 .adc_nids = alc883_adc_nids_rev,
10404 .capsrc_nids = alc883_capsrc_nids_rev,
10405 .dig_out_nid = ALC883_DIGOUT_NID,
10406 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10407 .channel_mode = alc883_3ST_6ch_modes,
10408 .need_dac_fix = 1,
10409 .const_channel_count = 6,
10410 .input_mux = &alc883_capture_source,
10411 .unsol_event = alc_automute_amp_unsol_event,
d9477207 10412 .setup = alc888_acer_aspire_7730g_setup,
fc86f954
DK
10413 .init_hook = alc_automute_amp,
10414 },
c07584c8
TD
10415 [ALC883_MEDION] = {
10416 .mixers = { alc883_fivestack_mixer,
10417 alc883_chmode_mixer },
10418 .init_verbs = { alc883_init_verbs,
b373bdeb 10419 alc883_medion_eapd_verbs },
c07584c8
TD
10420 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10421 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10422 .adc_nids = alc883_adc_nids_alt,
10423 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10424 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10425 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10426 .channel_mode = alc883_sixstack_modes,
10427 .input_mux = &alc883_capture_source,
b373bdeb 10428 },
7ad7b218
MC
10429 [ALC883_MEDION_WIM2160] = {
10430 .mixers = { alc883_medion_wim2160_mixer },
10431 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10432 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10433 .dac_nids = alc883_dac_nids,
10434 .dig_out_nid = ALC883_DIGOUT_NID,
10435 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10436 .adc_nids = alc883_adc_nids,
10437 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10438 .channel_mode = alc883_3ST_2ch_modes,
10439 .input_mux = &alc883_capture_source,
10440 .unsol_event = alc_automute_amp_unsol_event,
10441 .setup = alc883_medion_wim2160_setup,
10442 .init_hook = alc_automute_amp,
10443 },
b373bdeb 10444 [ALC883_LAPTOP_EAPD] = {
676a9b53 10445 .mixers = { alc883_base_mixer },
b373bdeb
AN
10446 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10447 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10448 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10449 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10450 .channel_mode = alc883_3ST_2ch_modes,
10451 .input_mux = &alc883_capture_source,
10452 },
a65cc60f 10453 [ALC883_CLEVO_M540R] = {
10454 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10455 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10456 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10457 .dac_nids = alc883_dac_nids,
10458 .dig_out_nid = ALC883_DIGOUT_NID,
10459 .dig_in_nid = ALC883_DIGIN_NID,
10460 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10461 .channel_mode = alc883_3ST_6ch_clevo_modes,
10462 .need_dac_fix = 1,
10463 .input_mux = &alc883_capture_source,
10464 /* This machine has the hardware HP auto-muting, thus
10465 * we need no software mute via unsol event
10466 */
10467 },
0c4cc443
HRK
10468 [ALC883_CLEVO_M720] = {
10469 .mixers = { alc883_clevo_m720_mixer },
10470 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10471 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10472 .dac_nids = alc883_dac_nids,
10473 .dig_out_nid = ALC883_DIGOUT_NID,
10474 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10475 .channel_mode = alc883_3ST_2ch_modes,
10476 .input_mux = &alc883_capture_source,
0c4cc443 10477 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10478 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10479 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10480 },
bc9f98a9
KY
10481 [ALC883_LENOVO_101E_2ch] = {
10482 .mixers = { alc883_lenovo_101e_2ch_mixer},
10483 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10484 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10485 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10486 .adc_nids = alc883_adc_nids_alt,
10487 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10488 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10489 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10490 .channel_mode = alc883_3ST_2ch_modes,
10491 .input_mux = &alc883_lenovo_101e_capture_source,
10492 .unsol_event = alc883_lenovo_101e_unsol_event,
10493 .init_hook = alc883_lenovo_101e_all_automute,
10494 },
272a527c
KY
10495 [ALC883_LENOVO_NB0763] = {
10496 .mixers = { alc883_lenovo_nb0763_mixer },
10497 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10498 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10499 .dac_nids = alc883_dac_nids,
272a527c
KY
10500 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10501 .channel_mode = alc883_3ST_2ch_modes,
10502 .need_dac_fix = 1,
10503 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10504 .unsol_event = alc_automute_amp_unsol_event,
dc427170 10505 .setup = alc883_lenovo_nb0763_setup,
4f5d1706 10506 .init_hook = alc_automute_amp,
272a527c
KY
10507 },
10508 [ALC888_LENOVO_MS7195_DIG] = {
10509 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10510 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10511 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10512 .dac_nids = alc883_dac_nids,
10513 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10514 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10515 .channel_mode = alc883_3ST_6ch_modes,
10516 .need_dac_fix = 1,
10517 .input_mux = &alc883_capture_source,
10518 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10519 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10520 },
10521 [ALC883_HAIER_W66] = {
c259249f 10522 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10523 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525 .dac_nids = alc883_dac_nids,
10526 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10527 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10528 .channel_mode = alc883_3ST_2ch_modes,
10529 .input_mux = &alc883_capture_source,
a9fd4f3f 10530 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10531 .setup = alc883_haier_w66_setup,
10532 .init_hook = alc_automute_amp,
eea6419e 10533 },
4723c022 10534 [ALC888_3ST_HP] = {
eea6419e 10535 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10536 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10537 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10538 .dac_nids = alc883_dac_nids,
4723c022
CM
10539 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10540 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10541 .need_dac_fix = 1,
10542 .input_mux = &alc883_capture_source,
a9fd4f3f 10543 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10544 .setup = alc888_3st_hp_setup,
10545 .init_hook = alc_automute_amp,
8341de60 10546 },
5795b9e6 10547 [ALC888_6ST_DELL] = {
f24dbdc6 10548 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10549 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10550 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10551 .dac_nids = alc883_dac_nids,
10552 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10553 .dig_in_nid = ALC883_DIGIN_NID,
10554 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10555 .channel_mode = alc883_sixstack_modes,
10556 .input_mux = &alc883_capture_source,
a9fd4f3f 10557 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10558 .setup = alc888_6st_dell_setup,
10559 .init_hook = alc_automute_amp,
5795b9e6 10560 },
a8848bd6
AS
10561 [ALC883_MITAC] = {
10562 .mixers = { alc883_mitac_mixer },
10563 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10564 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10565 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10566 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10567 .channel_mode = alc883_3ST_2ch_modes,
10568 .input_mux = &alc883_capture_source,
a9fd4f3f 10569 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10570 .setup = alc883_mitac_setup,
10571 .init_hook = alc_automute_amp,
a8848bd6 10572 },
fb97dc67
J
10573 [ALC883_FUJITSU_PI2515] = {
10574 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10575 .init_verbs = { alc883_init_verbs,
10576 alc883_2ch_fujitsu_pi2515_verbs},
10577 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10578 .dac_nids = alc883_dac_nids,
10579 .dig_out_nid = ALC883_DIGOUT_NID,
10580 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10581 .channel_mode = alc883_3ST_2ch_modes,
10582 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10583 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10584 .setup = alc883_2ch_fujitsu_pi2515_setup,
10585 .init_hook = alc_automute_amp,
fb97dc67 10586 },
ef8ef5fb
VP
10587 [ALC888_FUJITSU_XA3530] = {
10588 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10589 .init_verbs = { alc883_init_verbs,
10590 alc888_fujitsu_xa3530_verbs },
10591 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10592 .dac_nids = alc883_dac_nids,
10593 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10594 .adc_nids = alc883_adc_nids_rev,
10595 .capsrc_nids = alc883_capsrc_nids_rev,
10596 .dig_out_nid = ALC883_DIGOUT_NID,
10597 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10598 .channel_mode = alc888_4ST_8ch_intel_modes,
10599 .num_mux_defs =
10600 ARRAY_SIZE(alc888_2_capture_sources),
10601 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10602 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10603 .setup = alc888_fujitsu_xa3530_setup,
10604 .init_hook = alc_automute_amp,
ef8ef5fb 10605 },
e2757d5e
KY
10606 [ALC888_LENOVO_SKY] = {
10607 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10608 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10609 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10610 .dac_nids = alc883_dac_nids,
10611 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10612 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10613 .channel_mode = alc883_sixstack_modes,
10614 .need_dac_fix = 1,
10615 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10616 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10617 .setup = alc888_lenovo_sky_setup,
10618 .init_hook = alc_automute_amp,
e2757d5e
KY
10619 },
10620 [ALC888_ASUS_M90V] = {
10621 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10622 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10623 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10624 .dac_nids = alc883_dac_nids,
10625 .dig_out_nid = ALC883_DIGOUT_NID,
10626 .dig_in_nid = ALC883_DIGIN_NID,
10627 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10628 .channel_mode = alc883_3ST_6ch_modes,
10629 .need_dac_fix = 1,
10630 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10631 .unsol_event = alc_sku_unsol_event,
10632 .setup = alc883_mode2_setup,
10633 .init_hook = alc_inithook,
e2757d5e
KY
10634 },
10635 [ALC888_ASUS_EEE1601] = {
10636 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10637 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10638 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10639 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10640 .dac_nids = alc883_dac_nids,
10641 .dig_out_nid = ALC883_DIGOUT_NID,
10642 .dig_in_nid = ALC883_DIGIN_NID,
10643 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10644 .channel_mode = alc883_3ST_2ch_modes,
10645 .need_dac_fix = 1,
10646 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10647 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10648 .init_hook = alc883_eee1601_inithook,
10649 },
3ab90935
WF
10650 [ALC1200_ASUS_P5Q] = {
10651 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10652 .init_verbs = { alc883_init_verbs },
10653 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10654 .dac_nids = alc883_dac_nids,
10655 .dig_out_nid = ALC1200_DIGOUT_NID,
10656 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10657 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10658 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10659 .channel_mode = alc883_sixstack_modes,
10660 .input_mux = &alc883_capture_source,
10661 },
eb4c41d3
TS
10662 [ALC889A_MB31] = {
10663 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10664 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10665 alc880_gpio1_init_verbs },
10666 .adc_nids = alc883_adc_nids,
10667 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10668 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10669 .dac_nids = alc883_dac_nids,
10670 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10671 .channel_mode = alc889A_mb31_6ch_modes,
10672 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10673 .input_mux = &alc889A_mb31_capture_source,
10674 .dig_out_nid = ALC883_DIGOUT_NID,
10675 .unsol_event = alc889A_mb31_unsol_event,
10676 .init_hook = alc889A_mb31_automute,
10677 },
3e1647c5
GG
10678 [ALC883_SONY_VAIO_TT] = {
10679 .mixers = { alc883_vaiott_mixer },
10680 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10681 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10682 .dac_nids = alc883_dac_nids,
10683 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10684 .channel_mode = alc883_3ST_2ch_modes,
10685 .input_mux = &alc883_capture_source,
10686 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10687 .setup = alc883_vaiott_setup,
10688 .init_hook = alc_automute_amp,
3e1647c5 10689 },
9c7f852e
TI
10690};
10691
10692
4953550a
TI
10693/*
10694 * Pin config fixes
10695 */
10696enum {
954a29c8 10697 PINFIX_ABIT_AW9D_MAX,
32eea388 10698 PINFIX_LENOVO_Y530,
954a29c8 10699 PINFIX_PB_M5210,
c3d226ab 10700 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10701};
10702
f8f25ba3
TI
10703static const struct alc_fixup alc882_fixups[] = {
10704 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10705 .type = ALC_FIXUP_PINS,
10706 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10707 { 0x15, 0x01080104 }, /* side */
10708 { 0x16, 0x01011012 }, /* rear */
10709 { 0x17, 0x01016011 }, /* clfe */
10710 { }
10711 }
f8f25ba3 10712 },
32eea388
DH
10713 [PINFIX_LENOVO_Y530] = {
10714 .type = ALC_FIXUP_PINS,
10715 .v.pins = (const struct alc_pincfg[]) {
10716 { 0x15, 0x99130112 }, /* rear int speakers */
10717 { 0x16, 0x99130111 }, /* subwoofer */
10718 { }
10719 }
10720 },
954a29c8 10721 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10722 .type = ALC_FIXUP_VERBS,
10723 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10724 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10725 {}
10726 }
954a29c8 10727 },
c3d226ab 10728 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10729 .type = ALC_FIXUP_SKU,
10730 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10731 },
4953550a
TI
10732};
10733
f8f25ba3 10734static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10735 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10736 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10737 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10738 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10739 {}
10740};
10741
9c7f852e
TI
10742/*
10743 * BIOS auto configuration
10744 */
05f5f477
TI
10745static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10746 const struct auto_pin_cfg *cfg)
10747{
10748 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10749}
10750
4953550a 10751static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10752 hda_nid_t nid, int pin_type,
489008cd 10753 hda_nid_t dac)
9c7f852e 10754{
f12ab1e0
TI
10755 int idx;
10756
489008cd 10757 /* set as output */
f6c7e546 10758 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10759
10760 if (dac == 0x25)
9c7f852e 10761 idx = 4;
489008cd
TI
10762 else if (dac >= 0x02 && dac <= 0x05)
10763 idx = dac - 2;
f9700d5a 10764 else
489008cd 10765 return;
9c7f852e 10766 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10767}
10768
4953550a 10769static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10770{
10771 struct alc_spec *spec = codec->spec;
10772 int i;
10773
10774 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10775 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10776 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10777 if (nid)
4953550a 10778 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10779 spec->multiout.dac_nids[i]);
9c7f852e
TI
10780 }
10781}
10782
4953550a 10783static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10784{
10785 struct alc_spec *spec = codec->spec;
489008cd 10786 hda_nid_t pin, dac;
5855fb80 10787 int i;
9c7f852e 10788
0a3fabe3
DH
10789 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
10790 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10791 pin = spec->autocfg.hp_pins[i];
10792 if (!pin)
10793 break;
10794 dac = spec->multiout.hp_nid;
10795 if (!dac)
10796 dac = spec->multiout.dac_nids[0]; /* to front */
10797 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10798 }
489008cd 10799 }
0a3fabe3
DH
10800
10801 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
10802 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10803 pin = spec->autocfg.speaker_pins[i];
10804 if (!pin)
10805 break;
10806 dac = spec->multiout.extra_out_nid[0];
10807 if (!dac)
10808 dac = spec->multiout.dac_nids[0]; /* to front */
10809 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10810 }
489008cd 10811 }
9c7f852e
TI
10812}
10813
4953550a 10814static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10815{
10816 struct alc_spec *spec = codec->spec;
66ceeb6b 10817 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10818 int i;
10819
66ceeb6b
TI
10820 for (i = 0; i < cfg->num_inputs; i++) {
10821 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10822 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10823 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10824 snd_hda_codec_write(codec, nid, 0,
10825 AC_VERB_SET_AMP_GAIN_MUTE,
10826 AMP_OUT_MUTE);
10827 }
10828}
10829
10830static void alc882_auto_init_input_src(struct hda_codec *codec)
10831{
10832 struct alc_spec *spec = codec->spec;
10833 int c;
10834
10835 for (c = 0; c < spec->num_adc_nids; c++) {
10836 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10837 hda_nid_t nid = spec->capsrc_nids[c];
10838 unsigned int mux_idx;
10839 const struct hda_input_mux *imux;
10840 int conns, mute, idx, item;
10841
10842 conns = snd_hda_get_connections(codec, nid, conn_list,
10843 ARRAY_SIZE(conn_list));
10844 if (conns < 0)
10845 continue;
10846 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10847 imux = &spec->input_mux[mux_idx];
5311114d
TI
10848 if (!imux->num_items && mux_idx > 0)
10849 imux = &spec->input_mux[0];
4953550a
TI
10850 for (idx = 0; idx < conns; idx++) {
10851 /* if the current connection is the selected one,
10852 * unmute it as default - otherwise mute it
10853 */
10854 mute = AMP_IN_MUTE(idx);
10855 for (item = 0; item < imux->num_items; item++) {
10856 if (imux->items[item].index == idx) {
10857 if (spec->cur_mux[c] == item)
10858 mute = AMP_IN_UNMUTE(idx);
10859 break;
10860 }
10861 }
10862 /* check if we have a selector or mixer
10863 * we could check for the widget type instead, but
10864 * just check for Amp-In presence (in case of mixer
10865 * without amp-in there is something wrong, this
10866 * function shouldn't be used or capsrc nid is wrong)
10867 */
10868 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10869 snd_hda_codec_write(codec, nid, 0,
10870 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10871 mute);
10872 else if (mute != AMP_IN_MUTE(idx))
10873 snd_hda_codec_write(codec, nid, 0,
10874 AC_VERB_SET_CONNECT_SEL,
10875 idx);
9c7f852e
TI
10876 }
10877 }
10878}
10879
4953550a
TI
10880/* add mic boosts if needed */
10881static int alc_auto_add_mic_boost(struct hda_codec *codec)
10882{
10883 struct alc_spec *spec = codec->spec;
66ceeb6b 10884 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10885 int i, err;
53e8c323 10886 int type_idx = 0;
4953550a 10887 hda_nid_t nid;
5322bf27 10888 const char *prev_label = NULL;
4953550a 10889
66ceeb6b 10890 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10891 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10892 break;
10893 nid = cfg->inputs[i].pin;
10894 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10895 const char *label;
10896 char boost_label[32];
10897
10898 label = hda_get_autocfg_input_label(codec, cfg, i);
10899 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10900 type_idx++;
10901 else
10902 type_idx = 0;
5322bf27
DH
10903 prev_label = label;
10904
10905 snprintf(boost_label, sizeof(boost_label),
10906 "%s Boost Volume", label);
10907 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10908 boost_label, type_idx,
4953550a 10909 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10910 if (err < 0)
10911 return err;
10912 }
4953550a
TI
10913 }
10914 return 0;
10915}
f511b01c 10916
9c7f852e 10917/* almost identical with ALC880 parser... */
4953550a 10918static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10919{
10920 struct alc_spec *spec = codec->spec;
05f5f477 10921 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10922 int err;
9c7f852e 10923
05f5f477
TI
10924 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10925 alc882_ignore);
9c7f852e
TI
10926 if (err < 0)
10927 return err;
05f5f477
TI
10928 if (!spec->autocfg.line_outs)
10929 return 0; /* can't find valid BIOS pin config */
776e184e 10930
05f5f477
TI
10931 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10932 if (err < 0)
10933 return err;
569ed348 10934 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10935 if (err < 0)
10936 return err;
10937 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10938 "Headphone");
05f5f477
TI
10939 if (err < 0)
10940 return err;
10941 err = alc880_auto_create_extra_out(spec,
10942 spec->autocfg.speaker_pins[0],
10943 "Speaker");
10944 if (err < 0)
10945 return err;
05f5f477 10946 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10947 if (err < 0)
10948 return err;
10949
05f5f477
TI
10950 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10951
757899ac 10952 alc_auto_parse_digital(codec);
05f5f477
TI
10953
10954 if (spec->kctls.list)
10955 add_mixer(spec, spec->kctls.list);
10956
10957 add_verb(spec, alc883_auto_init_verbs);
4953550a 10958 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10959 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10960 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10961
05f5f477
TI
10962 spec->num_mux_defs = 1;
10963 spec->input_mux = &spec->private_imux[0];
10964
6227cdce 10965 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10966
10967 err = alc_auto_add_mic_boost(codec);
10968 if (err < 0)
10969 return err;
61b9b9b1 10970
776e184e 10971 return 1; /* config found */
9c7f852e
TI
10972}
10973
10974/* additional initialization for auto-configuration model */
4953550a 10975static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10976{
f6c7e546 10977 struct alc_spec *spec = codec->spec;
4953550a
TI
10978 alc882_auto_init_multi_out(codec);
10979 alc882_auto_init_hp_out(codec);
10980 alc882_auto_init_analog_input(codec);
10981 alc882_auto_init_input_src(codec);
757899ac 10982 alc_auto_init_digital(codec);
f6c7e546 10983 if (spec->unsol_event)
7fb0d78f 10984 alc_inithook(codec);
9c7f852e
TI
10985}
10986
4953550a 10987static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10988{
10989 struct alc_spec *spec;
10990 int err, board_config;
10991
10992 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10993 if (spec == NULL)
10994 return -ENOMEM;
10995
10996 codec->spec = spec;
10997
4953550a
TI
10998 switch (codec->vendor_id) {
10999 case 0x10ec0882:
11000 case 0x10ec0885:
11001 break;
11002 default:
11003 /* ALC883 and variants */
11004 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11005 break;
11006 }
2c3bf9ab 11007
4953550a
TI
11008 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11009 alc882_models,
11010 alc882_cfg_tbl);
11011
11012 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11013 board_config = snd_hda_check_board_codec_sid_config(codec,
11014 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11015
11016 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11017 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11018 codec->chip_name);
11019 board_config = ALC882_AUTO;
9c7f852e
TI
11020 }
11021
b5bfbc67
TI
11022 if (board_config == ALC882_AUTO) {
11023 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11024 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11025 }
4953550a 11026
90622917
DH
11027 alc_auto_parse_customize_define(codec);
11028
4953550a 11029 if (board_config == ALC882_AUTO) {
9c7f852e 11030 /* automatic parse from the BIOS config */
4953550a 11031 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11032 if (err < 0) {
11033 alc_free(codec);
11034 return err;
f12ab1e0 11035 } else if (!err) {
9c7f852e
TI
11036 printk(KERN_INFO
11037 "hda_codec: Cannot set up configuration "
11038 "from BIOS. Using base mode...\n");
4953550a 11039 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11040 }
11041 }
11042
dc1eae25 11043 if (has_cdefine_beep(codec)) {
8af2591d
TI
11044 err = snd_hda_attach_beep_device(codec, 0x1);
11045 if (err < 0) {
11046 alc_free(codec);
11047 return err;
11048 }
680cd536
KK
11049 }
11050
4953550a 11051 if (board_config != ALC882_AUTO)
e9c364c0 11052 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11053
4953550a
TI
11054 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11055 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11056 /* FIXME: setup DAC5 */
11057 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11058 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11059
11060 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11061 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11062
4953550a 11063 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11064 int i, j;
4953550a
TI
11065 spec->num_adc_nids = 0;
11066 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11067 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11068 hda_nid_t cap;
d11f74c6 11069 hda_nid_t items[16];
4953550a
TI
11070 hda_nid_t nid = alc882_adc_nids[i];
11071 unsigned int wcap = get_wcaps(codec, nid);
11072 /* get type */
a22d543a 11073 wcap = get_wcaps_type(wcap);
4953550a
TI
11074 if (wcap != AC_WID_AUD_IN)
11075 continue;
11076 spec->private_adc_nids[spec->num_adc_nids] = nid;
11077 err = snd_hda_get_connections(codec, nid, &cap, 1);
11078 if (err < 0)
11079 continue;
d11f74c6
TI
11080 err = snd_hda_get_connections(codec, cap, items,
11081 ARRAY_SIZE(items));
11082 if (err < 0)
11083 continue;
11084 for (j = 0; j < imux->num_items; j++)
11085 if (imux->items[j].index >= err)
11086 break;
11087 if (j < imux->num_items)
11088 continue;
4953550a
TI
11089 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11090 spec->num_adc_nids++;
61b9b9b1 11091 }
4953550a
TI
11092 spec->adc_nids = spec->private_adc_nids;
11093 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11094 }
11095
b59bdf3b 11096 set_capture_mixer(codec);
da00c244 11097
dc1eae25 11098 if (has_cdefine_beep(codec))
da00c244 11099 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11100
b5bfbc67 11101 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11102
2134ea4f
TI
11103 spec->vmaster_nid = 0x0c;
11104
9c7f852e 11105 codec->patch_ops = alc_patch_ops;
4953550a
TI
11106 if (board_config == ALC882_AUTO)
11107 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11108
11109 alc_init_jacks(codec);
cb53c626
TI
11110#ifdef CONFIG_SND_HDA_POWER_SAVE
11111 if (!spec->loopback.amplist)
4953550a 11112 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11113#endif
9c7f852e
TI
11114
11115 return 0;
11116}
11117
4953550a 11118
9c7f852e
TI
11119/*
11120 * ALC262 support
11121 */
11122
11123#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11124#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11125
11126#define alc262_dac_nids alc260_dac_nids
11127#define alc262_adc_nids alc882_adc_nids
11128#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11129#define alc262_capsrc_nids alc882_capsrc_nids
11130#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11131
11132#define alc262_modes alc260_modes
11133#define alc262_capture_source alc882_capture_source
11134
4e555fe5
KY
11135static hda_nid_t alc262_dmic_adc_nids[1] = {
11136 /* ADC0 */
11137 0x09
11138};
11139
11140static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11141
9c7f852e
TI
11142static struct snd_kcontrol_new alc262_base_mixer[] = {
11143 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11144 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11145 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11146 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11147 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11148 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11151 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11152 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11153 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11154 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11155 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11156 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11157 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11158 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11159 { } /* end */
11160};
11161
ce875f07
TI
11162/* update HP, line and mono-out pins according to the master switch */
11163static void alc262_hp_master_update(struct hda_codec *codec)
11164{
11165 struct alc_spec *spec = codec->spec;
11166 int val = spec->master_sw;
11167
11168 /* HP & line-out */
11169 snd_hda_codec_write_cache(codec, 0x1b, 0,
11170 AC_VERB_SET_PIN_WIDGET_CONTROL,
11171 val ? PIN_HP : 0);
11172 snd_hda_codec_write_cache(codec, 0x15, 0,
11173 AC_VERB_SET_PIN_WIDGET_CONTROL,
11174 val ? PIN_HP : 0);
11175 /* mono (speaker) depending on the HP jack sense */
11176 val = val && !spec->jack_present;
11177 snd_hda_codec_write_cache(codec, 0x16, 0,
11178 AC_VERB_SET_PIN_WIDGET_CONTROL,
11179 val ? PIN_OUT : 0);
11180}
11181
11182static void alc262_hp_bpc_automute(struct hda_codec *codec)
11183{
11184 struct alc_spec *spec = codec->spec;
864f92be
WF
11185
11186 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11187 alc262_hp_master_update(codec);
11188}
11189
11190static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11191{
11192 if ((res >> 26) != ALC880_HP_EVENT)
11193 return;
11194 alc262_hp_bpc_automute(codec);
11195}
11196
11197static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11198{
11199 struct alc_spec *spec = codec->spec;
864f92be
WF
11200
11201 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11202 alc262_hp_master_update(codec);
11203}
11204
11205static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11206 unsigned int res)
11207{
11208 if ((res >> 26) != ALC880_HP_EVENT)
11209 return;
11210 alc262_hp_wildwest_automute(codec);
11211}
11212
b72519b5 11213#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11214
11215static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11216 struct snd_ctl_elem_value *ucontrol)
11217{
11218 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11219 struct alc_spec *spec = codec->spec;
11220 int val = !!*ucontrol->value.integer.value;
11221
11222 if (val == spec->master_sw)
11223 return 0;
11224 spec->master_sw = val;
11225 alc262_hp_master_update(codec);
11226 return 1;
11227}
11228
b72519b5
TI
11229#define ALC262_HP_MASTER_SWITCH \
11230 { \
11231 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11232 .name = "Master Playback Switch", \
11233 .info = snd_ctl_boolean_mono_info, \
11234 .get = alc262_hp_master_sw_get, \
11235 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11236 }, \
11237 { \
11238 .iface = NID_MAPPING, \
11239 .name = "Master Playback Switch", \
11240 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11241 }
11242
5b0cb1d8 11243
9c7f852e 11244static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11245 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11246 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11247 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11248 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11249 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11250 HDA_OUTPUT),
11251 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11252 HDA_OUTPUT),
9c7f852e
TI
11253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11254 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11255 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11256 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11257 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11258 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11259 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11260 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11261 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11262 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11263 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11264 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11265 { } /* end */
11266};
11267
cd7509a4 11268static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11269 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11270 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11271 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11272 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11273 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11274 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11275 HDA_OUTPUT),
11276 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11277 HDA_OUTPUT),
cd7509a4
KY
11278 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11279 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11280 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11281 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11282 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11283 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11284 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11285 { } /* end */
11286};
11287
11288static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11289 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11290 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11291 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11292 { } /* end */
11293};
11294
66d2a9d6 11295/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11296static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11297{
11298 struct alc_spec *spec = codec->spec;
66d2a9d6 11299
a9fd4f3f 11300 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11301 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11302}
11303
66d2a9d6 11304static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11305 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11306 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11307 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11308 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11309 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11310 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11311 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11312 { } /* end */
11313};
11314
11315static struct hda_verb alc262_hp_t5735_verbs[] = {
11316 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11317 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11318
11319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11320 { }
11321};
11322
8c427226 11323static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11324 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11325 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11327 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11328 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11329 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11330 { } /* end */
11331};
11332
11333static struct hda_verb alc262_hp_rp5700_verbs[] = {
11334 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11335 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11336 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11337 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11338 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11339 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11340 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11341 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11342 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11343 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11344 {}
11345};
11346
11347static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11348 .num_items = 1,
11349 .items = {
11350 { "Line", 0x1 },
11351 },
11352};
11353
42171c17
TI
11354/* bind hp and internal speaker mute (with plug check) as master switch */
11355static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11356{
42171c17
TI
11357 struct alc_spec *spec = codec->spec;
11358 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11359 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11360 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11361 unsigned int mute;
0724ea2a 11362
42171c17
TI
11363 /* HP */
11364 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11365 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11366 HDA_AMP_MUTE, mute);
11367 /* mute internal speaker per jack sense */
11368 if (spec->jack_present)
11369 mute = HDA_AMP_MUTE;
11370 if (line_nid)
11371 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11372 HDA_AMP_MUTE, mute);
11373 if (speaker_nid && speaker_nid != line_nid)
11374 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11375 HDA_AMP_MUTE, mute);
42171c17
TI
11376}
11377
11378#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11379
11380static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11381 struct snd_ctl_elem_value *ucontrol)
11382{
11383 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11384 struct alc_spec *spec = codec->spec;
11385 int val = !!*ucontrol->value.integer.value;
11386
11387 if (val == spec->master_sw)
11388 return 0;
11389 spec->master_sw = val;
11390 alc262_hippo_master_update(codec);
11391 return 1;
11392}
11393
11394#define ALC262_HIPPO_MASTER_SWITCH \
11395 { \
11396 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11397 .name = "Master Playback Switch", \
11398 .info = snd_ctl_boolean_mono_info, \
11399 .get = alc262_hippo_master_sw_get, \
11400 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11401 }, \
11402 { \
11403 .iface = NID_MAPPING, \
11404 .name = "Master Playback Switch", \
11405 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11406 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11407 }
42171c17
TI
11408
11409static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11410 ALC262_HIPPO_MASTER_SWITCH,
11411 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11412 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11413 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11417 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11418 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11419 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11420 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11421 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11422 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11423 { } /* end */
11424};
11425
11426static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11427 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11428 ALC262_HIPPO_MASTER_SWITCH,
11429 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11430 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11431 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11432 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11434 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11435 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11436 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11437 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11438 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11439 { } /* end */
11440};
11441
11442/* mute/unmute internal speaker according to the hp jack and mute state */
11443static void alc262_hippo_automute(struct hda_codec *codec)
11444{
11445 struct alc_spec *spec = codec->spec;
11446 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11447
864f92be 11448 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11449 alc262_hippo_master_update(codec);
0724ea2a 11450}
5b31954e 11451
42171c17
TI
11452static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11453{
11454 if ((res >> 26) != ALC880_HP_EVENT)
11455 return;
11456 alc262_hippo_automute(codec);
11457}
11458
4f5d1706 11459static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11460{
11461 struct alc_spec *spec = codec->spec;
11462
11463 spec->autocfg.hp_pins[0] = 0x15;
11464 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11465}
11466
4f5d1706 11467static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11468{
11469 struct alc_spec *spec = codec->spec;
11470
11471 spec->autocfg.hp_pins[0] = 0x1b;
11472 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11473}
11474
11475
272a527c 11476static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11477 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11478 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11479 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11480 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11481 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11482 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11483 { } /* end */
11484};
11485
83c34218 11486static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11487 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11488 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11489 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11492 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11493 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11494 { } /* end */
11495};
272a527c 11496
ba340e82
TV
11497static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11498 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11499 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11500 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11501 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11502 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11503 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11504 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11505 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11506 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11507 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11508 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11509 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11510 { } /* end */
11511};
11512
11513static struct hda_verb alc262_tyan_verbs[] = {
11514 /* Headphone automute */
11515 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11518
11519 /* P11 AUX_IN, white 4-pin connector */
11520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11521 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11522 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11523 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11524
11525 {}
11526};
11527
11528/* unsolicited event for HP jack sensing */
4f5d1706 11529static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11530{
a9fd4f3f 11531 struct alc_spec *spec = codec->spec;
ba340e82 11532
a9fd4f3f
TI
11533 spec->autocfg.hp_pins[0] = 0x1b;
11534 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11535}
11536
ba340e82 11537
9c7f852e
TI
11538#define alc262_capture_mixer alc882_capture_mixer
11539#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11540
11541/*
11542 * generic initialization of ADC, input mixers and output mixers
11543 */
11544static struct hda_verb alc262_init_verbs[] = {
11545 /*
11546 * Unmute ADC0-2 and set the default input to mic-in
11547 */
11548 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11550 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11551 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11552 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11553 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11554
cb53c626 11555 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11556 * mixer widget
f12ab1e0
TI
11557 * Note: PASD motherboards uses the Line In 2 as the input for
11558 * front panel mic (mic 2)
9c7f852e
TI
11559 */
11560 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11561 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11562 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11563 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11564 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11565 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11566
11567 /*
df694daa
KY
11568 * Set up output mixers (0x0c - 0x0e)
11569 */
11570 /* set vol=0 to output mixers */
11571 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11572 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11573 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11574 /* set up input amps for analog loopback */
11575 /* Amp Indices: DAC = 0, mixer = 1 */
11576 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11577 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11578 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11579 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11580 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11581 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11582
11583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11584 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11585 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11586 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11587 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11588 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11589
11590 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11591 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11592 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11593 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11594 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11595
df694daa
KY
11596 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11598
df694daa
KY
11599 /* FIXME: use matrix-type input source selection */
11600 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11601 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11602 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11603 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11604 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11605 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11606 /* Input mixer2 */
11607 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11608 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11609 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11610 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11611 /* Input mixer3 */
11612 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11613 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11614 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11615 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11616
11617 { }
11618};
1da177e4 11619
4e555fe5
KY
11620static struct hda_verb alc262_eapd_verbs[] = {
11621 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11622 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11623 { }
11624};
11625
ccc656ce
KY
11626static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11628 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11629 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11630
11631 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11632 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11633 {}
11634};
11635
272a527c
KY
11636static struct hda_verb alc262_sony_unsol_verbs[] = {
11637 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11638 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11639 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11640
11641 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11643 {}
272a527c
KY
11644};
11645
4e555fe5
KY
11646static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11647 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11648 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11649 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11650 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11651 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11652 { } /* end */
11653};
11654
11655static struct hda_verb alc262_toshiba_s06_verbs[] = {
11656 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11657 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11658 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11659 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11660 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11661 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11662 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11663 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11664 {}
11665};
11666
4f5d1706 11667static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11668{
a9fd4f3f
TI
11669 struct alc_spec *spec = codec->spec;
11670
11671 spec->autocfg.hp_pins[0] = 0x15;
11672 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11673 spec->ext_mic.pin = 0x18;
11674 spec->ext_mic.mux_idx = 0;
11675 spec->int_mic.pin = 0x12;
11676 spec->int_mic.mux_idx = 9;
11677 spec->auto_mic = 1;
4e555fe5
KY
11678}
11679
e8f9ae2a
PT
11680/*
11681 * nec model
11682 * 0x15 = headphone
11683 * 0x16 = internal speaker
11684 * 0x18 = external mic
11685 */
11686
11687static struct snd_kcontrol_new alc262_nec_mixer[] = {
11688 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11689 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11690
11691 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11693 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11694
11695 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11696 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11697 { } /* end */
11698};
11699
11700static struct hda_verb alc262_nec_verbs[] = {
11701 /* Unmute Speaker */
11702 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11703
11704 /* Headphone */
11705 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11706 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11707
11708 /* External mic to headphone */
11709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11710 /* External mic to speaker */
11711 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11712 {}
11713};
11714
834be88d
TI
11715/*
11716 * fujitsu model
5d9fab2d
TV
11717 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11718 * 0x1b = port replicator headphone out
834be88d
TI
11719 */
11720
11721#define ALC_HP_EVENT 0x37
11722
11723static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11724 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11725 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11726 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11727 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11728 {}
11729};
11730
0e31daf7
J
11731static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11732 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11733 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11734 {}
11735};
11736
e2595322
DC
11737static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11738 /* Front Mic pin: input vref at 50% */
11739 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11740 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11741 {}
11742};
11743
834be88d 11744static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11745 .num_items = 3,
834be88d
TI
11746 .items = {
11747 { "Mic", 0x0 },
28c4edb7 11748 { "Internal Mic", 0x1 },
834be88d
TI
11749 { "CD", 0x4 },
11750 },
11751};
11752
9c7f852e
TI
11753static struct hda_input_mux alc262_HP_capture_source = {
11754 .num_items = 5,
11755 .items = {
11756 { "Mic", 0x0 },
accbe498 11757 { "Front Mic", 0x1 },
9c7f852e
TI
11758 { "Line", 0x2 },
11759 { "CD", 0x4 },
11760 { "AUX IN", 0x6 },
11761 },
11762};
11763
accbe498 11764static struct hda_input_mux alc262_HP_D7000_capture_source = {
11765 .num_items = 4,
11766 .items = {
11767 { "Mic", 0x0 },
11768 { "Front Mic", 0x2 },
11769 { "Line", 0x1 },
11770 { "CD", 0x4 },
11771 },
11772};
11773
ebc7a406 11774/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11775static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11776{
11777 struct alc_spec *spec = codec->spec;
11778 unsigned int mute;
11779
f12ab1e0 11780 if (force || !spec->sense_updated) {
864f92be
WF
11781 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11782 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11783 spec->sense_updated = 1;
11784 }
ebc7a406
TI
11785 /* unmute internal speaker only if both HPs are unplugged and
11786 * master switch is on
11787 */
11788 if (spec->jack_present)
11789 mute = HDA_AMP_MUTE;
11790 else
834be88d 11791 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11792 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11793 HDA_AMP_MUTE, mute);
834be88d
TI
11794}
11795
11796/* unsolicited event for HP jack sensing */
11797static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11798 unsigned int res)
11799{
11800 if ((res >> 26) != ALC_HP_EVENT)
11801 return;
11802 alc262_fujitsu_automute(codec, 1);
11803}
11804
ebc7a406
TI
11805static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11806{
11807 alc262_fujitsu_automute(codec, 1);
11808}
11809
834be88d 11810/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11811static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11812 .ops = &snd_hda_bind_vol,
11813 .values = {
11814 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11815 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11816 0
11817 },
11818};
834be88d 11819
0e31daf7
J
11820/* mute/unmute internal speaker according to the hp jack and mute state */
11821static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11822{
11823 struct alc_spec *spec = codec->spec;
11824 unsigned int mute;
11825
11826 if (force || !spec->sense_updated) {
864f92be 11827 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11828 spec->sense_updated = 1;
11829 }
11830 if (spec->jack_present) {
11831 /* mute internal speaker */
11832 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11833 HDA_AMP_MUTE, HDA_AMP_MUTE);
11834 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11835 HDA_AMP_MUTE, HDA_AMP_MUTE);
11836 } else {
11837 /* unmute internal speaker if necessary */
11838 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11839 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11840 HDA_AMP_MUTE, mute);
11841 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11842 HDA_AMP_MUTE, mute);
11843 }
11844}
11845
11846/* unsolicited event for HP jack sensing */
11847static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11848 unsigned int res)
11849{
11850 if ((res >> 26) != ALC_HP_EVENT)
11851 return;
11852 alc262_lenovo_3000_automute(codec, 1);
11853}
11854
8de56b7d
TI
11855static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11856 int dir, int idx, long *valp)
11857{
11858 int i, change = 0;
11859
11860 for (i = 0; i < 2; i++, valp++)
11861 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11862 HDA_AMP_MUTE,
11863 *valp ? 0 : HDA_AMP_MUTE);
11864 return change;
11865}
11866
834be88d
TI
11867/* bind hp and internal speaker mute (with plug check) */
11868static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11869 struct snd_ctl_elem_value *ucontrol)
11870{
11871 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11872 long *valp = ucontrol->value.integer.value;
11873 int change;
11874
8de56b7d
TI
11875 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11876 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11877 if (change)
11878 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11879 return change;
11880}
11881
11882static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11883 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11884 {
11885 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11886 .name = "Master Playback Switch",
5e26dfd0 11887 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11888 .info = snd_hda_mixer_amp_switch_info,
11889 .get = snd_hda_mixer_amp_switch_get,
11890 .put = alc262_fujitsu_master_sw_put,
11891 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11892 },
5b0cb1d8
JK
11893 {
11894 .iface = NID_MAPPING,
11895 .name = "Master Playback Switch",
11896 .private_value = 0x1b,
11897 },
834be88d
TI
11898 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11899 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11900 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11901 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11903 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11904 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11905 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11906 { } /* end */
11907};
11908
0e31daf7
J
11909/* bind hp and internal speaker mute (with plug check) */
11910static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11911 struct snd_ctl_elem_value *ucontrol)
11912{
11913 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11914 long *valp = ucontrol->value.integer.value;
11915 int change;
11916
8de56b7d 11917 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11918 if (change)
11919 alc262_lenovo_3000_automute(codec, 0);
11920 return change;
11921}
11922
11923static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11924 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11925 {
11926 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11927 .name = "Master Playback Switch",
5e26dfd0 11928 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11929 .info = snd_hda_mixer_amp_switch_info,
11930 .get = snd_hda_mixer_amp_switch_get,
11931 .put = alc262_lenovo_3000_master_sw_put,
11932 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11933 },
11934 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11935 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11936 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11938 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11939 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11940 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11941 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11942 { } /* end */
11943};
11944
9f99a638
HM
11945static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11946 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11947 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11949 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11950 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11952 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11953 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11954 { } /* end */
11955};
11956
304dcaac
TI
11957/* additional init verbs for Benq laptops */
11958static struct hda_verb alc262_EAPD_verbs[] = {
11959 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11960 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11961 {}
11962};
11963
83c34218
KY
11964static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11965 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11966 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11967
11968 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11969 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11970 {}
11971};
11972
f651b50b
TD
11973/* Samsung Q1 Ultra Vista model setup */
11974static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11975 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11976 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11977 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11979 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11980 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11981 { } /* end */
11982};
11983
11984static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11985 /* output mixer */
11986 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11987 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11988 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11989 /* speaker */
11990 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11991 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11992 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11993 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11994 /* HP */
f651b50b 11995 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11996 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11997 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11998 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11999 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12000 /* internal mic */
12001 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12002 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12003 /* ADC, choose mic */
12004 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12005 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12006 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12007 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12008 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12009 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12010 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12011 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12012 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12014 {}
12015};
12016
f651b50b
TD
12017/* mute/unmute internal speaker according to the hp jack and mute state */
12018static void alc262_ultra_automute(struct hda_codec *codec)
12019{
12020 struct alc_spec *spec = codec->spec;
12021 unsigned int mute;
f651b50b 12022
bb9f76cd
TI
12023 mute = 0;
12024 /* auto-mute only when HP is used as HP */
12025 if (!spec->cur_mux[0]) {
864f92be 12026 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12027 if (spec->jack_present)
12028 mute = HDA_AMP_MUTE;
f651b50b 12029 }
bb9f76cd
TI
12030 /* mute/unmute internal speaker */
12031 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12032 HDA_AMP_MUTE, mute);
12033 /* mute/unmute HP */
12034 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12035 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12036}
12037
12038/* unsolicited event for HP jack sensing */
12039static void alc262_ultra_unsol_event(struct hda_codec *codec,
12040 unsigned int res)
12041{
12042 if ((res >> 26) != ALC880_HP_EVENT)
12043 return;
12044 alc262_ultra_automute(codec);
12045}
12046
bb9f76cd
TI
12047static struct hda_input_mux alc262_ultra_capture_source = {
12048 .num_items = 2,
12049 .items = {
12050 { "Mic", 0x1 },
12051 { "Headphone", 0x7 },
12052 },
12053};
12054
12055static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12056 struct snd_ctl_elem_value *ucontrol)
12057{
12058 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12059 struct alc_spec *spec = codec->spec;
12060 int ret;
12061
54cbc9ab 12062 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12063 if (!ret)
12064 return 0;
12065 /* reprogram the HP pin as mic or HP according to the input source */
12066 snd_hda_codec_write_cache(codec, 0x15, 0,
12067 AC_VERB_SET_PIN_WIDGET_CONTROL,
12068 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12069 alc262_ultra_automute(codec); /* mute/unmute HP */
12070 return ret;
12071}
12072
12073static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12074 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12075 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12076 {
12077 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12078 .name = "Capture Source",
54cbc9ab
TI
12079 .info = alc_mux_enum_info,
12080 .get = alc_mux_enum_get,
bb9f76cd
TI
12081 .put = alc262_ultra_mux_enum_put,
12082 },
5b0cb1d8
JK
12083 {
12084 .iface = NID_MAPPING,
12085 .name = "Capture Source",
12086 .private_value = 0x15,
12087 },
bb9f76cd
TI
12088 { } /* end */
12089};
12090
c3fc1f50
TI
12091/* We use two mixers depending on the output pin; 0x16 is a mono output
12092 * and thus it's bound with a different mixer.
12093 * This function returns which mixer amp should be used.
12094 */
12095static int alc262_check_volbit(hda_nid_t nid)
12096{
12097 if (!nid)
12098 return 0;
12099 else if (nid == 0x16)
12100 return 2;
12101 else
12102 return 1;
12103}
12104
12105static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12106 const char *pfx, int *vbits, int idx)
c3fc1f50 12107{
c3fc1f50
TI
12108 unsigned long val;
12109 int vbit;
12110
12111 vbit = alc262_check_volbit(nid);
12112 if (!vbit)
12113 return 0;
12114 if (*vbits & vbit) /* a volume control for this mixer already there */
12115 return 0;
12116 *vbits |= vbit;
c3fc1f50
TI
12117 if (vbit == 2)
12118 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12119 else
12120 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12121 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12122}
12123
12124static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12125 const char *pfx, int idx)
c3fc1f50 12126{
c3fc1f50
TI
12127 unsigned long val;
12128
12129 if (!nid)
12130 return 0;
c3fc1f50
TI
12131 if (nid == 0x16)
12132 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12133 else
12134 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12135 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12136}
12137
df694daa 12138/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12139static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12140 const struct auto_pin_cfg *cfg)
df694daa 12141{
c3fc1f50
TI
12142 const char *pfx;
12143 int vbits;
033688a5 12144 int i, err;
df694daa
KY
12145
12146 spec->multiout.num_dacs = 1; /* only use one dac */
12147 spec->multiout.dac_nids = spec->private_dac_nids;
12148 spec->multiout.dac_nids[0] = 2;
12149
bcb2f0f5
TI
12150 pfx = alc_get_line_out_pfx(cfg, true);
12151 if (!pfx)
c3fc1f50 12152 pfx = "Front";
033688a5
TI
12153 for (i = 0; i < 2; i++) {
12154 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12155 if (err < 0)
12156 return err;
12157 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12158 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12159 "Speaker", i);
12160 if (err < 0)
12161 return err;
12162 }
12163 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12164 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12165 "Headphone", i);
12166 if (err < 0)
12167 return err;
12168 }
12169 }
df694daa 12170
c3fc1f50
TI
12171 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12172 alc262_check_volbit(cfg->speaker_pins[0]) |
12173 alc262_check_volbit(cfg->hp_pins[0]);
12174 if (vbits == 1 || vbits == 2)
12175 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12176 vbits = 0;
033688a5
TI
12177 for (i = 0; i < 2; i++) {
12178 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12179 &vbits, i);
12180 if (err < 0)
12181 return err;
12182 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12183 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12184 "Speaker", &vbits, i);
12185 if (err < 0)
12186 return err;
12187 }
12188 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12189 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12190 "Headphone", &vbits, i);
12191 if (err < 0)
12192 return err;
12193 }
12194 }
f12ab1e0 12195 return 0;
df694daa
KY
12196}
12197
05f5f477 12198#define alc262_auto_create_input_ctls \
eaa9b3a7 12199 alc882_auto_create_input_ctls
df694daa
KY
12200
12201/*
12202 * generic initialization of ADC, input mixers and output mixers
12203 */
12204static struct hda_verb alc262_volume_init_verbs[] = {
12205 /*
12206 * Unmute ADC0-2 and set the default input to mic-in
12207 */
12208 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12209 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12210 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12211 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12212 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12213 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12214
cb53c626 12215 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12216 * mixer widget
f12ab1e0
TI
12217 * Note: PASD motherboards uses the Line In 2 as the input for
12218 * front panel mic (mic 2)
df694daa
KY
12219 */
12220 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12221 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12222 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12223 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12224 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12225 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12226
12227 /*
12228 * Set up output mixers (0x0c - 0x0f)
12229 */
12230 /* set vol=0 to output mixers */
12231 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12232 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12233 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12234
df694daa
KY
12235 /* set up input amps for analog loopback */
12236 /* Amp Indices: DAC = 0, mixer = 1 */
12237 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12238 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12239 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12240 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12241 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12242 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12243
12244 /* FIXME: use matrix-type input source selection */
12245 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12246 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12247 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12248 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12249 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12250 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12251 /* Input mixer2 */
12252 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12253 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12254 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12255 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12256 /* Input mixer3 */
12257 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12261
12262 { }
12263};
12264
9c7f852e
TI
12265static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12266 /*
12267 * Unmute ADC0-2 and set the default input to mic-in
12268 */
12269 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12271 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12272 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12273 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12274 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12275
cb53c626 12276 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12277 * mixer widget
f12ab1e0
TI
12278 * Note: PASD motherboards uses the Line In 2 as the input for
12279 * front panel mic (mic 2)
9c7f852e
TI
12280 */
12281 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12282 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12283 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12284 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12285 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12289
9c7f852e
TI
12290 /*
12291 * Set up output mixers (0x0c - 0x0e)
12292 */
12293 /* set vol=0 to output mixers */
12294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12295 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12296 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12297
12298 /* set up input amps for analog loopback */
12299 /* Amp Indices: DAC = 0, mixer = 1 */
12300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12302 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12303 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12304 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12305 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12306
ce875f07 12307 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12308 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12309 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12310
12311 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12312 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12313
12314 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12315 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12316
12317 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12318 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12319 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12320 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12321 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12322
0e4835c1 12323 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12324 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12325 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12326 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12327 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12328 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12329
12330
12331 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12332 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12333 /* Input mixer1: only unmute Mic */
9c7f852e 12334 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12335 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12336 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12337 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12338 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12339 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12340 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12341 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12342 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12343 /* Input mixer2 */
12344 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12345 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12346 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12347 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12348 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12349 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12350 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12351 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12352 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12353 /* Input mixer3 */
12354 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12355 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12356 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12357 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12358 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12360 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12361 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12362 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12363
ce875f07
TI
12364 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12365
9c7f852e
TI
12366 { }
12367};
12368
cd7509a4
KY
12369static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12370 /*
12371 * Unmute ADC0-2 and set the default input to mic-in
12372 */
12373 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12374 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12375 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12376 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12377 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12378 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12379
cb53c626 12380 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12381 * mixer widget
12382 * Note: PASD motherboards uses the Line In 2 as the input for front
12383 * panel mic (mic 2)
12384 */
12385 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12388 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12389 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12390 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12391 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12392 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12393 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12394 /*
12395 * Set up output mixers (0x0c - 0x0e)
12396 */
12397 /* set vol=0 to output mixers */
12398 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12399 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12400 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12401
12402 /* set up input amps for analog loopback */
12403 /* Amp Indices: DAC = 0, mixer = 1 */
12404 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12405 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12406 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12407 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12408 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12409 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12410
12411
12412 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12413 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12414 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12415 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12416 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12417 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12418 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12419
12420 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12422
12423 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12424 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12425
12426 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12427 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12428 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12429 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12430 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12431 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12432
12433 /* FIXME: use matrix-type input source selection */
12434 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12435 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12436 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12437 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12438 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12439 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12440 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12441 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12443 /* Input mixer2 */
12444 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12445 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12446 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12447 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12448 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12449 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12451 /* Input mixer3 */
12452 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12456 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12457 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12459
ce875f07
TI
12460 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12461
cd7509a4
KY
12462 { }
12463};
12464
9f99a638
HM
12465static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12466
12467 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12468 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12469 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12470
12471 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12472 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12473 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12474 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12475
12476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12478 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12479 {}
12480};
12481
18675e42
TI
12482/*
12483 * Pin config fixes
12484 */
12485enum {
12486 PINFIX_FSC_H270,
12487};
12488
12489static const struct alc_fixup alc262_fixups[] = {
12490 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12491 .type = ALC_FIXUP_PINS,
12492 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12493 { 0x14, 0x99130110 }, /* speaker */
12494 { 0x15, 0x0221142f }, /* front HP */
12495 { 0x1b, 0x0121141f }, /* rear HP */
12496 { }
12497 }
12498 },
18675e42
TI
12499};
12500
12501static struct snd_pci_quirk alc262_fixup_tbl[] = {
12502 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12503 {}
12504};
12505
9f99a638 12506
cb53c626
TI
12507#ifdef CONFIG_SND_HDA_POWER_SAVE
12508#define alc262_loopbacks alc880_loopbacks
12509#endif
12510
def319f9 12511/* pcm configuration: identical with ALC880 */
df694daa
KY
12512#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12513#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12514#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12515#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12516
12517/*
12518 * BIOS auto configuration
12519 */
12520static int alc262_parse_auto_config(struct hda_codec *codec)
12521{
12522 struct alc_spec *spec = codec->spec;
12523 int err;
12524 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12525
f12ab1e0
TI
12526 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12527 alc262_ignore);
12528 if (err < 0)
df694daa 12529 return err;
e64f14f4 12530 if (!spec->autocfg.line_outs) {
0852d7a6 12531 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12532 spec->multiout.max_channels = 2;
12533 spec->no_analog = 1;
12534 goto dig_only;
12535 }
df694daa 12536 return 0; /* can't find valid BIOS pin config */
e64f14f4 12537 }
f12ab1e0
TI
12538 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12539 if (err < 0)
12540 return err;
05f5f477 12541 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12542 if (err < 0)
df694daa
KY
12543 return err;
12544
12545 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12546
e64f14f4 12547 dig_only:
757899ac 12548 alc_auto_parse_digital(codec);
df694daa 12549
603c4019 12550 if (spec->kctls.list)
d88897ea 12551 add_mixer(spec, spec->kctls.list);
df694daa 12552
d88897ea 12553 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12554 spec->num_mux_defs = 1;
61b9b9b1 12555 spec->input_mux = &spec->private_imux[0];
df694daa 12556
776e184e
TI
12557 err = alc_auto_add_mic_boost(codec);
12558 if (err < 0)
12559 return err;
12560
6227cdce 12561 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12562
df694daa
KY
12563 return 1;
12564}
12565
12566#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12567#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12568#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12569#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12570
12571
12572/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12573static void alc262_auto_init(struct hda_codec *codec)
df694daa 12574{
f6c7e546 12575 struct alc_spec *spec = codec->spec;
df694daa
KY
12576 alc262_auto_init_multi_out(codec);
12577 alc262_auto_init_hp_out(codec);
12578 alc262_auto_init_analog_input(codec);
f511b01c 12579 alc262_auto_init_input_src(codec);
757899ac 12580 alc_auto_init_digital(codec);
f6c7e546 12581 if (spec->unsol_event)
7fb0d78f 12582 alc_inithook(codec);
df694daa
KY
12583}
12584
12585/*
12586 * configuration and preset
12587 */
ea734963 12588static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12589 [ALC262_BASIC] = "basic",
12590 [ALC262_HIPPO] = "hippo",
12591 [ALC262_HIPPO_1] = "hippo_1",
12592 [ALC262_FUJITSU] = "fujitsu",
12593 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12594 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12595 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12596 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12597 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12598 [ALC262_BENQ_T31] = "benq-t31",
12599 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12600 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12601 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12602 [ALC262_ULTRA] = "ultra",
0e31daf7 12603 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12604 [ALC262_NEC] = "nec",
ba340e82 12605 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12606 [ALC262_AUTO] = "auto",
12607};
12608
12609static struct snd_pci_quirk alc262_cfg_tbl[] = {
12610 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12611 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12612 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12613 ALC262_HP_BPC),
12614 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12615 ALC262_HP_BPC),
5734a07c
TI
12616 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12617 ALC262_HP_BPC),
53eff7e1
TI
12618 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12619 ALC262_HP_BPC),
cd7509a4 12620 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12621 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12622 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12623 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12624 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12625 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12626 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12627 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12628 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12629 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12630 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12631 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12632 ALC262_HP_TC_T5735),
8c427226 12633 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12634 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12635 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12636 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12637 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12638 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12639 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12640 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12641#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12642 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12643 ALC262_SONY_ASSAMD),
c5b5165c 12644#endif
36ca6e13 12645 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12646 ALC262_TOSHIBA_RX1),
80ffe869 12647 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12648 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12649 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12650 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12651 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12652 ALC262_ULTRA),
3e420e78 12653 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12654 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12655 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12656 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12657 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12658 {}
12659};
12660
12661static struct alc_config_preset alc262_presets[] = {
12662 [ALC262_BASIC] = {
12663 .mixers = { alc262_base_mixer },
12664 .init_verbs = { alc262_init_verbs },
12665 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12666 .dac_nids = alc262_dac_nids,
12667 .hp_nid = 0x03,
12668 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12669 .channel_mode = alc262_modes,
a3bcba38 12670 .input_mux = &alc262_capture_source,
df694daa 12671 },
ccc656ce 12672 [ALC262_HIPPO] = {
42171c17 12673 .mixers = { alc262_hippo_mixer },
6732bd0d 12674 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12675 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12676 .dac_nids = alc262_dac_nids,
12677 .hp_nid = 0x03,
12678 .dig_out_nid = ALC262_DIGOUT_NID,
12679 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12680 .channel_mode = alc262_modes,
12681 .input_mux = &alc262_capture_source,
12682 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12683 .setup = alc262_hippo_setup,
12684 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12685 },
12686 [ALC262_HIPPO_1] = {
12687 .mixers = { alc262_hippo1_mixer },
12688 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12689 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12690 .dac_nids = alc262_dac_nids,
12691 .hp_nid = 0x02,
12692 .dig_out_nid = ALC262_DIGOUT_NID,
12693 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12694 .channel_mode = alc262_modes,
12695 .input_mux = &alc262_capture_source,
42171c17 12696 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12697 .setup = alc262_hippo1_setup,
12698 .init_hook = alc262_hippo_automute,
ccc656ce 12699 },
834be88d
TI
12700 [ALC262_FUJITSU] = {
12701 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12702 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12703 alc262_fujitsu_unsol_verbs },
834be88d
TI
12704 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12705 .dac_nids = alc262_dac_nids,
12706 .hp_nid = 0x03,
12707 .dig_out_nid = ALC262_DIGOUT_NID,
12708 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12709 .channel_mode = alc262_modes,
12710 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12711 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12712 .init_hook = alc262_fujitsu_init_hook,
834be88d 12713 },
9c7f852e
TI
12714 [ALC262_HP_BPC] = {
12715 .mixers = { alc262_HP_BPC_mixer },
12716 .init_verbs = { alc262_HP_BPC_init_verbs },
12717 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12718 .dac_nids = alc262_dac_nids,
12719 .hp_nid = 0x03,
12720 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12721 .channel_mode = alc262_modes,
12722 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12723 .unsol_event = alc262_hp_bpc_unsol_event,
12724 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12725 },
cd7509a4
KY
12726 [ALC262_HP_BPC_D7000_WF] = {
12727 .mixers = { alc262_HP_BPC_WildWest_mixer },
12728 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12729 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12730 .dac_nids = alc262_dac_nids,
12731 .hp_nid = 0x03,
12732 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12733 .channel_mode = alc262_modes,
accbe498 12734 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12735 .unsol_event = alc262_hp_wildwest_unsol_event,
12736 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12737 },
cd7509a4
KY
12738 [ALC262_HP_BPC_D7000_WL] = {
12739 .mixers = { alc262_HP_BPC_WildWest_mixer,
12740 alc262_HP_BPC_WildWest_option_mixer },
12741 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12742 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12743 .dac_nids = alc262_dac_nids,
12744 .hp_nid = 0x03,
12745 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12746 .channel_mode = alc262_modes,
accbe498 12747 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12748 .unsol_event = alc262_hp_wildwest_unsol_event,
12749 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12750 },
66d2a9d6
KY
12751 [ALC262_HP_TC_T5735] = {
12752 .mixers = { alc262_hp_t5735_mixer },
12753 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12754 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12755 .dac_nids = alc262_dac_nids,
12756 .hp_nid = 0x03,
12757 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12758 .channel_mode = alc262_modes,
12759 .input_mux = &alc262_capture_source,
dc99be47 12760 .unsol_event = alc_sku_unsol_event,
4f5d1706 12761 .setup = alc262_hp_t5735_setup,
dc99be47 12762 .init_hook = alc_inithook,
8c427226
KY
12763 },
12764 [ALC262_HP_RP5700] = {
12765 .mixers = { alc262_hp_rp5700_mixer },
12766 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12767 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12768 .dac_nids = alc262_dac_nids,
12769 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12770 .channel_mode = alc262_modes,
12771 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12772 },
304dcaac
TI
12773 [ALC262_BENQ_ED8] = {
12774 .mixers = { alc262_base_mixer },
12775 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12776 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12777 .dac_nids = alc262_dac_nids,
12778 .hp_nid = 0x03,
12779 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12780 .channel_mode = alc262_modes,
12781 .input_mux = &alc262_capture_source,
f12ab1e0 12782 },
272a527c
KY
12783 [ALC262_SONY_ASSAMD] = {
12784 .mixers = { alc262_sony_mixer },
12785 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12786 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12787 .dac_nids = alc262_dac_nids,
12788 .hp_nid = 0x02,
12789 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12790 .channel_mode = alc262_modes,
12791 .input_mux = &alc262_capture_source,
12792 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12793 .setup = alc262_hippo_setup,
12794 .init_hook = alc262_hippo_automute,
83c34218
KY
12795 },
12796 [ALC262_BENQ_T31] = {
12797 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12798 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12799 alc_hp15_unsol_verbs },
83c34218
KY
12800 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12801 .dac_nids = alc262_dac_nids,
12802 .hp_nid = 0x03,
12803 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12804 .channel_mode = alc262_modes,
12805 .input_mux = &alc262_capture_source,
12806 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12807 .setup = alc262_hippo_setup,
12808 .init_hook = alc262_hippo_automute,
ea1fb29a 12809 },
f651b50b 12810 [ALC262_ULTRA] = {
f9e336f6
TI
12811 .mixers = { alc262_ultra_mixer },
12812 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12813 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12814 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12815 .dac_nids = alc262_dac_nids,
f651b50b
TD
12816 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12817 .channel_mode = alc262_modes,
12818 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12819 .adc_nids = alc262_adc_nids, /* ADC0 */
12820 .capsrc_nids = alc262_capsrc_nids,
12821 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12822 .unsol_event = alc262_ultra_unsol_event,
12823 .init_hook = alc262_ultra_automute,
12824 },
0e31daf7
J
12825 [ALC262_LENOVO_3000] = {
12826 .mixers = { alc262_lenovo_3000_mixer },
12827 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12828 alc262_lenovo_3000_unsol_verbs,
12829 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12830 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12831 .dac_nids = alc262_dac_nids,
12832 .hp_nid = 0x03,
12833 .dig_out_nid = ALC262_DIGOUT_NID,
12834 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12835 .channel_mode = alc262_modes,
12836 .input_mux = &alc262_fujitsu_capture_source,
12837 .unsol_event = alc262_lenovo_3000_unsol_event,
12838 },
e8f9ae2a
PT
12839 [ALC262_NEC] = {
12840 .mixers = { alc262_nec_mixer },
12841 .init_verbs = { alc262_nec_verbs },
12842 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12843 .dac_nids = alc262_dac_nids,
12844 .hp_nid = 0x03,
12845 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12846 .channel_mode = alc262_modes,
12847 .input_mux = &alc262_capture_source,
12848 },
4e555fe5
KY
12849 [ALC262_TOSHIBA_S06] = {
12850 .mixers = { alc262_toshiba_s06_mixer },
12851 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12852 alc262_eapd_verbs },
12853 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12854 .capsrc_nids = alc262_dmic_capsrc_nids,
12855 .dac_nids = alc262_dac_nids,
12856 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12857 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12858 .dig_out_nid = ALC262_DIGOUT_NID,
12859 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12860 .channel_mode = alc262_modes,
4f5d1706
TI
12861 .unsol_event = alc_sku_unsol_event,
12862 .setup = alc262_toshiba_s06_setup,
12863 .init_hook = alc_inithook,
4e555fe5 12864 },
9f99a638
HM
12865 [ALC262_TOSHIBA_RX1] = {
12866 .mixers = { alc262_toshiba_rx1_mixer },
12867 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12868 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12869 .dac_nids = alc262_dac_nids,
12870 .hp_nid = 0x03,
12871 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12872 .channel_mode = alc262_modes,
12873 .input_mux = &alc262_capture_source,
12874 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12875 .setup = alc262_hippo_setup,
12876 .init_hook = alc262_hippo_automute,
9f99a638 12877 },
ba340e82
TV
12878 [ALC262_TYAN] = {
12879 .mixers = { alc262_tyan_mixer },
12880 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12881 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12882 .dac_nids = alc262_dac_nids,
12883 .hp_nid = 0x02,
12884 .dig_out_nid = ALC262_DIGOUT_NID,
12885 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12886 .channel_mode = alc262_modes,
12887 .input_mux = &alc262_capture_source,
a9fd4f3f 12888 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12889 .setup = alc262_tyan_setup,
12890 .init_hook = alc_automute_amp,
ba340e82 12891 },
df694daa
KY
12892};
12893
12894static int patch_alc262(struct hda_codec *codec)
12895{
12896 struct alc_spec *spec;
12897 int board_config;
12898 int err;
12899
dc041e0b 12900 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12901 if (spec == NULL)
12902 return -ENOMEM;
12903
12904 codec->spec = spec;
12905#if 0
f12ab1e0
TI
12906 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12907 * under-run
12908 */
df694daa
KY
12909 {
12910 int tmp;
12911 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12912 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12913 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12914 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12915 }
12916#endif
da00c244 12917 alc_auto_parse_customize_define(codec);
df694daa 12918
2c3bf9ab
TI
12919 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12920
f5fcc13c
TI
12921 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12922 alc262_models,
12923 alc262_cfg_tbl);
cd7509a4 12924
f5fcc13c 12925 if (board_config < 0) {
9a11f1aa
TI
12926 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12927 codec->chip_name);
df694daa
KY
12928 board_config = ALC262_AUTO;
12929 }
12930
b5bfbc67
TI
12931 if (board_config == ALC262_AUTO) {
12932 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12933 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12934 }
18675e42 12935
df694daa
KY
12936 if (board_config == ALC262_AUTO) {
12937 /* automatic parse from the BIOS config */
12938 err = alc262_parse_auto_config(codec);
12939 if (err < 0) {
12940 alc_free(codec);
12941 return err;
f12ab1e0 12942 } else if (!err) {
9c7f852e
TI
12943 printk(KERN_INFO
12944 "hda_codec: Cannot set up configuration "
12945 "from BIOS. Using base mode...\n");
df694daa
KY
12946 board_config = ALC262_BASIC;
12947 }
12948 }
12949
dc1eae25 12950 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12951 err = snd_hda_attach_beep_device(codec, 0x1);
12952 if (err < 0) {
12953 alc_free(codec);
12954 return err;
12955 }
680cd536
KK
12956 }
12957
df694daa 12958 if (board_config != ALC262_AUTO)
e9c364c0 12959 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12960
df694daa
KY
12961 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12962 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12963
df694daa
KY
12964 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12965 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12966
f12ab1e0 12967 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12968 int i;
12969 /* check whether the digital-mic has to be supported */
12970 for (i = 0; i < spec->input_mux->num_items; i++) {
12971 if (spec->input_mux->items[i].index >= 9)
12972 break;
12973 }
12974 if (i < spec->input_mux->num_items) {
12975 /* use only ADC0 */
12976 spec->adc_nids = alc262_dmic_adc_nids;
12977 spec->num_adc_nids = 1;
12978 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12979 } else {
8c927b4a
TI
12980 /* all analog inputs */
12981 /* check whether NID 0x07 is valid */
12982 unsigned int wcap = get_wcaps(codec, 0x07);
12983
12984 /* get type */
a22d543a 12985 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12986 if (wcap != AC_WID_AUD_IN) {
12987 spec->adc_nids = alc262_adc_nids_alt;
12988 spec->num_adc_nids =
12989 ARRAY_SIZE(alc262_adc_nids_alt);
12990 spec->capsrc_nids = alc262_capsrc_nids_alt;
12991 } else {
12992 spec->adc_nids = alc262_adc_nids;
12993 spec->num_adc_nids =
12994 ARRAY_SIZE(alc262_adc_nids);
12995 spec->capsrc_nids = alc262_capsrc_nids;
12996 }
df694daa
KY
12997 }
12998 }
e64f14f4 12999 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13000 set_capture_mixer(codec);
dc1eae25 13001 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13002 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13003
b5bfbc67 13004 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13005
2134ea4f
TI
13006 spec->vmaster_nid = 0x0c;
13007
df694daa
KY
13008 codec->patch_ops = alc_patch_ops;
13009 if (board_config == ALC262_AUTO)
ae6b813a 13010 spec->init_hook = alc262_auto_init;
bf1b0225
KY
13011
13012 alc_init_jacks(codec);
cb53c626
TI
13013#ifdef CONFIG_SND_HDA_POWER_SAVE
13014 if (!spec->loopback.amplist)
13015 spec->loopback.amplist = alc262_loopbacks;
13016#endif
ea1fb29a 13017
df694daa
KY
13018 return 0;
13019}
13020
a361d84b
KY
13021/*
13022 * ALC268 channel source setting (2 channel)
13023 */
13024#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13025#define alc268_modes alc260_modes
ea1fb29a 13026
a361d84b
KY
13027static hda_nid_t alc268_dac_nids[2] = {
13028 /* front, hp */
13029 0x02, 0x03
13030};
13031
13032static hda_nid_t alc268_adc_nids[2] = {
13033 /* ADC0-1 */
13034 0x08, 0x07
13035};
13036
13037static hda_nid_t alc268_adc_nids_alt[1] = {
13038 /* ADC0 */
13039 0x08
13040};
13041
e1406348
TI
13042static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13043
a361d84b
KY
13044static struct snd_kcontrol_new alc268_base_mixer[] = {
13045 /* output mixer control */
13046 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13047 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13048 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13049 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13050 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13051 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13052 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13053 { }
13054};
13055
42171c17
TI
13056static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13057 /* output mixer control */
13058 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13059 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13060 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13061 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13062 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13063 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13064 { }
13065};
13066
aef9d318
TI
13067/* bind Beep switches of both NID 0x0f and 0x10 */
13068static struct hda_bind_ctls alc268_bind_beep_sw = {
13069 .ops = &snd_hda_bind_sw,
13070 .values = {
13071 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13072 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13073 0
13074 },
13075};
13076
13077static struct snd_kcontrol_new alc268_beep_mixer[] = {
13078 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13079 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13080 { }
13081};
13082
d1a991a6
KY
13083static struct hda_verb alc268_eapd_verbs[] = {
13084 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13085 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13086 { }
13087};
13088
d273809e 13089/* Toshiba specific */
d273809e
TI
13090static struct hda_verb alc268_toshiba_verbs[] = {
13091 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13092 { } /* end */
13093};
13094
13095/* Acer specific */
889c4395 13096/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13097static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13098 .ops = &snd_hda_bind_vol,
13099 .values = {
13100 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13101 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13102 0
13103 },
13104};
13105
889c4395
TI
13106/* mute/unmute internal speaker according to the hp jack and mute state */
13107static void alc268_acer_automute(struct hda_codec *codec, int force)
13108{
13109 struct alc_spec *spec = codec->spec;
13110 unsigned int mute;
13111
13112 if (force || !spec->sense_updated) {
864f92be 13113 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
13114 spec->sense_updated = 1;
13115 }
13116 if (spec->jack_present)
13117 mute = HDA_AMP_MUTE; /* mute internal speaker */
13118 else /* unmute internal speaker if necessary */
13119 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13120 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13121 HDA_AMP_MUTE, mute);
13122}
13123
13124
13125/* bind hp and internal speaker mute (with plug check) */
13126static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13127 struct snd_ctl_elem_value *ucontrol)
13128{
13129 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13130 long *valp = ucontrol->value.integer.value;
13131 int change;
13132
8de56b7d 13133 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13134 if (change)
13135 alc268_acer_automute(codec, 0);
13136 return change;
13137}
d273809e 13138
8ef355da
KY
13139static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13140 /* output mixer control */
13141 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13142 {
13143 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13144 .name = "Master Playback Switch",
5e26dfd0 13145 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13146 .info = snd_hda_mixer_amp_switch_info,
13147 .get = snd_hda_mixer_amp_switch_get,
13148 .put = alc268_acer_master_sw_put,
13149 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13150 },
13151 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13152 { }
13153};
13154
d273809e
TI
13155static struct snd_kcontrol_new alc268_acer_mixer[] = {
13156 /* output mixer control */
13157 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13158 {
13159 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13160 .name = "Master Playback Switch",
5e26dfd0 13161 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13162 .info = snd_hda_mixer_amp_switch_info,
13163 .get = snd_hda_mixer_amp_switch_get,
13164 .put = alc268_acer_master_sw_put,
13165 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13166 },
5f99f86a
DH
13167 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13168 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13169 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13170 { }
13171};
13172
c238b4f4
TI
13173static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13174 /* output mixer control */
13175 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13176 {
13177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13178 .name = "Master Playback Switch",
5e26dfd0 13179 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13180 .info = snd_hda_mixer_amp_switch_info,
13181 .get = snd_hda_mixer_amp_switch_get,
13182 .put = alc268_acer_master_sw_put,
13183 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13184 },
5f99f86a
DH
13185 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13186 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13187 { }
13188};
13189
8ef355da
KY
13190static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13191 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13192 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13193 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13194 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13195 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13196 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13197 { }
13198};
13199
d273809e 13200static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13201 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13202 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13203 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13205 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13206 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13207 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13208 { }
13209};
13210
13211/* unsolicited event for HP jack sensing */
42171c17 13212#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13213#define alc268_toshiba_setup alc262_hippo_setup
13214#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13215
13216static void alc268_acer_unsol_event(struct hda_codec *codec,
13217 unsigned int res)
13218{
889c4395 13219 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13220 return;
13221 alc268_acer_automute(codec, 1);
13222}
13223
889c4395
TI
13224static void alc268_acer_init_hook(struct hda_codec *codec)
13225{
13226 alc268_acer_automute(codec, 1);
13227}
13228
8ef355da
KY
13229/* toggle speaker-output according to the hp-jack state */
13230static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13231{
13232 unsigned int present;
13233 unsigned char bits;
13234
864f92be 13235 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13236 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13237 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13238 HDA_AMP_MUTE, bits);
8ef355da 13239 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13240 HDA_AMP_MUTE, bits);
8ef355da
KY
13241}
13242
8ef355da
KY
13243static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13244 unsigned int res)
13245{
4f5d1706
TI
13246 switch (res >> 26) {
13247 case ALC880_HP_EVENT:
8ef355da 13248 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13249 break;
13250 case ALC880_MIC_EVENT:
13251 alc_mic_automute(codec);
13252 break;
13253 }
13254}
13255
13256static void alc268_acer_lc_setup(struct hda_codec *codec)
13257{
13258 struct alc_spec *spec = codec->spec;
13259 spec->ext_mic.pin = 0x18;
13260 spec->ext_mic.mux_idx = 0;
13261 spec->int_mic.pin = 0x12;
13262 spec->int_mic.mux_idx = 6;
13263 spec->auto_mic = 1;
8ef355da
KY
13264}
13265
13266static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13267{
13268 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13269 alc_mic_automute(codec);
8ef355da
KY
13270}
13271
3866f0b0
TI
13272static struct snd_kcontrol_new alc268_dell_mixer[] = {
13273 /* output mixer control */
13274 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13275 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13276 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13277 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13278 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13279 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13280 { }
13281};
13282
13283static struct hda_verb alc268_dell_verbs[] = {
13284 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13285 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13286 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13287 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13288 { }
13289};
13290
13291/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13292static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13293{
a9fd4f3f 13294 struct alc_spec *spec = codec->spec;
3866f0b0 13295
a9fd4f3f
TI
13296 spec->autocfg.hp_pins[0] = 0x15;
13297 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13298 spec->ext_mic.pin = 0x18;
13299 spec->ext_mic.mux_idx = 0;
13300 spec->int_mic.pin = 0x19;
13301 spec->int_mic.mux_idx = 1;
13302 spec->auto_mic = 1;
3866f0b0
TI
13303}
13304
eb5a6621
HRK
13305static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13306 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13307 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13308 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13310 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13311 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13312 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13313 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13314 { }
13315};
13316
13317static struct hda_verb alc267_quanta_il1_verbs[] = {
13318 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13319 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13320 { }
13321};
13322
4f5d1706 13323static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13324{
a9fd4f3f 13325 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13326 spec->autocfg.hp_pins[0] = 0x15;
13327 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13328 spec->ext_mic.pin = 0x18;
13329 spec->ext_mic.mux_idx = 0;
13330 spec->int_mic.pin = 0x19;
13331 spec->int_mic.mux_idx = 1;
13332 spec->auto_mic = 1;
eb5a6621
HRK
13333}
13334
a361d84b
KY
13335/*
13336 * generic initialization of ADC, input mixers and output mixers
13337 */
13338static struct hda_verb alc268_base_init_verbs[] = {
13339 /* Unmute DAC0-1 and set vol = 0 */
13340 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13341 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13342
13343 /*
13344 * Set up output mixers (0x0c - 0x0e)
13345 */
13346 /* set vol=0 to output mixers */
13347 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13348 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13349
13350 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13351 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13352
13353 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13354 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13355 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13356 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13357 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13358 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13359 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13360 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13361
13362 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13363 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13364 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13365 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13366 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13367
13368 /* set PCBEEP vol = 0, mute connections */
13369 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13370 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13371 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13372
a9b3aa8a 13373 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13374
a9b3aa8a
JZ
13375 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13376 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13377 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13379
a361d84b
KY
13380 { }
13381};
13382
13383/*
13384 * generic initialization of ADC, input mixers and output mixers
13385 */
13386static struct hda_verb alc268_volume_init_verbs[] = {
13387 /* set output DAC */
4cfb91c6
TI
13388 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13389 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13390
13391 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13392 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13393 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13394 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13395 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13396
a361d84b 13397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13398 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13399 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13400
13401 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13402 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13403
aef9d318
TI
13404 /* set PCBEEP vol = 0, mute connections */
13405 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13406 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13407 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13408
13409 { }
13410};
13411
fdbc6626
TI
13412static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13413 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13414 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13415 { } /* end */
13416};
13417
a361d84b
KY
13418static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13419 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13420 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13421 _DEFINE_CAPSRC(1),
a361d84b
KY
13422 { } /* end */
13423};
13424
13425static struct snd_kcontrol_new alc268_capture_mixer[] = {
13426 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13427 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13428 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13429 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13430 _DEFINE_CAPSRC(2),
a361d84b
KY
13431 { } /* end */
13432};
13433
13434static struct hda_input_mux alc268_capture_source = {
13435 .num_items = 4,
13436 .items = {
13437 { "Mic", 0x0 },
13438 { "Front Mic", 0x1 },
13439 { "Line", 0x2 },
13440 { "CD", 0x3 },
13441 },
13442};
13443
0ccb541c 13444static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13445 .num_items = 3,
13446 .items = {
13447 { "Mic", 0x0 },
13448 { "Internal Mic", 0x1 },
13449 { "Line", 0x2 },
13450 },
13451};
13452
13453static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13454 .num_items = 3,
13455 .items = {
13456 { "Mic", 0x0 },
13457 { "Internal Mic", 0x6 },
13458 { "Line", 0x2 },
13459 },
13460};
13461
86c53bd2
JW
13462#ifdef CONFIG_SND_DEBUG
13463static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13464 /* Volume widgets */
13465 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13466 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13467 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13468 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13469 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13470 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13471 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13472 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13473 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13474 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13475 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13476 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13477 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13478 /* The below appears problematic on some hardwares */
13479 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13480 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13481 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13482 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13483 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13484
13485 /* Modes for retasking pin widgets */
13486 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13487 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13488 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13489 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13490
13491 /* Controls for GPIO pins, assuming they are configured as outputs */
13492 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13493 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13494 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13495 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13496
13497 /* Switches to allow the digital SPDIF output pin to be enabled.
13498 * The ALC268 does not have an SPDIF input.
13499 */
13500 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13501
13502 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13503 * this output to turn on an external amplifier.
13504 */
13505 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13506 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13507
13508 { } /* end */
13509};
13510#endif
13511
a361d84b
KY
13512/* create input playback/capture controls for the given pin */
13513static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13514 const char *ctlname, int idx)
13515{
3f3b7c1a 13516 hda_nid_t dac;
a361d84b
KY
13517 int err;
13518
3f3b7c1a
TI
13519 switch (nid) {
13520 case 0x14:
13521 case 0x16:
13522 dac = 0x02;
13523 break;
13524 case 0x15:
b08b1637
TI
13525 case 0x1a: /* ALC259/269 only */
13526 case 0x1b: /* ALC259/269 only */
531d8791 13527 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13528 dac = 0x03;
13529 break;
13530 default:
c7a9434d
TI
13531 snd_printd(KERN_WARNING "hda_codec: "
13532 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13533 return 0;
13534 }
13535 if (spec->multiout.dac_nids[0] != dac &&
13536 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13537 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13538 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13539 HDA_OUTPUT));
13540 if (err < 0)
13541 return err;
3f3b7c1a
TI
13542 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13543 }
13544
3f3b7c1a 13545 if (nid != 0x16)
0afe5f89 13546 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13547 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13548 else /* mono */
0afe5f89 13549 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13550 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13551 if (err < 0)
13552 return err;
13553 return 0;
13554}
13555
13556/* add playback controls from the parsed DAC table */
13557static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13558 const struct auto_pin_cfg *cfg)
13559{
13560 hda_nid_t nid;
13561 int err;
13562
a361d84b 13563 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13564
13565 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13566 if (nid) {
13567 const char *name;
13568 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13569 name = "Speaker";
13570 else
13571 name = "Front";
13572 err = alc268_new_analog_output(spec, nid, name, 0);
13573 if (err < 0)
13574 return err;
13575 }
a361d84b
KY
13576
13577 nid = cfg->speaker_pins[0];
13578 if (nid == 0x1d) {
0afe5f89 13579 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13580 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13581 if (err < 0)
13582 return err;
7bfb9c03 13583 } else if (nid) {
3f3b7c1a
TI
13584 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13585 if (err < 0)
13586 return err;
a361d84b
KY
13587 }
13588 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13589 if (nid) {
13590 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13591 if (err < 0)
13592 return err;
13593 }
a361d84b
KY
13594
13595 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13596 if (nid == 0x16) {
0afe5f89 13597 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13598 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13599 if (err < 0)
13600 return err;
13601 }
ea1fb29a 13602 return 0;
a361d84b
KY
13603}
13604
13605/* create playback/capture controls for input pins */
05f5f477 13606static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13607 const struct auto_pin_cfg *cfg)
13608{
05f5f477 13609 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13610}
13611
e9af4f36
TI
13612static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13613 hda_nid_t nid, int pin_type)
13614{
13615 int idx;
13616
13617 alc_set_pin_output(codec, nid, pin_type);
13618 if (nid == 0x14 || nid == 0x16)
13619 idx = 0;
13620 else
13621 idx = 1;
13622 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13623}
13624
13625static void alc268_auto_init_multi_out(struct hda_codec *codec)
13626{
13627 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13628 int i;
13629
13630 for (i = 0; i < spec->autocfg.line_outs; i++) {
13631 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13632 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13633 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13634 }
13635}
13636
13637static void alc268_auto_init_hp_out(struct hda_codec *codec)
13638{
13639 struct alc_spec *spec = codec->spec;
13640 hda_nid_t pin;
e1ca7b4e 13641 int i;
e9af4f36 13642
e1ca7b4e
TI
13643 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13644 pin = spec->autocfg.hp_pins[i];
e9af4f36 13645 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13646 }
13647 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13648 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13649 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13650 }
13651 if (spec->autocfg.mono_out_pin)
13652 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13653 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13654}
13655
a361d84b
KY
13656static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13657{
13658 struct alc_spec *spec = codec->spec;
13659 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13660 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13661 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13662 unsigned int dac_vol1, dac_vol2;
13663
e9af4f36 13664 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13665 snd_hda_codec_write(codec, speaker_nid, 0,
13666 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13667 /* mute mixer inputs from 0x1d */
a361d84b
KY
13668 snd_hda_codec_write(codec, 0x0f, 0,
13669 AC_VERB_SET_AMP_GAIN_MUTE,
13670 AMP_IN_UNMUTE(1));
13671 snd_hda_codec_write(codec, 0x10, 0,
13672 AC_VERB_SET_AMP_GAIN_MUTE,
13673 AMP_IN_UNMUTE(1));
13674 } else {
e9af4f36 13675 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13676 snd_hda_codec_write(codec, 0x0f, 0,
13677 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13678 snd_hda_codec_write(codec, 0x10, 0,
13679 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13680 }
13681
13682 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13683 if (line_nid == 0x14)
a361d84b
KY
13684 dac_vol2 = AMP_OUT_ZERO;
13685 else if (line_nid == 0x15)
13686 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13687 if (hp_nid == 0x14)
a361d84b
KY
13688 dac_vol2 = AMP_OUT_ZERO;
13689 else if (hp_nid == 0x15)
13690 dac_vol1 = AMP_OUT_ZERO;
13691 if (line_nid != 0x16 || hp_nid != 0x16 ||
13692 spec->autocfg.line_out_pins[1] != 0x16 ||
13693 spec->autocfg.line_out_pins[2] != 0x16)
13694 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13695
13696 snd_hda_codec_write(codec, 0x02, 0,
13697 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13698 snd_hda_codec_write(codec, 0x03, 0,
13699 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13700}
13701
def319f9 13702/* pcm configuration: identical with ALC880 */
a361d84b
KY
13703#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13704#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13705#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13706#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13707
13708/*
13709 * BIOS auto configuration
13710 */
13711static int alc268_parse_auto_config(struct hda_codec *codec)
13712{
13713 struct alc_spec *spec = codec->spec;
13714 int err;
13715 static hda_nid_t alc268_ignore[] = { 0 };
13716
13717 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13718 alc268_ignore);
13719 if (err < 0)
13720 return err;
7e0e44d4
TI
13721 if (!spec->autocfg.line_outs) {
13722 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13723 spec->multiout.max_channels = 2;
13724 spec->no_analog = 1;
13725 goto dig_only;
13726 }
a361d84b 13727 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13728 }
a361d84b
KY
13729 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13730 if (err < 0)
13731 return err;
05f5f477 13732 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13733 if (err < 0)
13734 return err;
13735
13736 spec->multiout.max_channels = 2;
13737
7e0e44d4 13738 dig_only:
a361d84b 13739 /* digital only support output */
757899ac 13740 alc_auto_parse_digital(codec);
603c4019 13741 if (spec->kctls.list)
d88897ea 13742 add_mixer(spec, spec->kctls.list);
a361d84b 13743
892981ff 13744 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13745 add_mixer(spec, alc268_beep_mixer);
aef9d318 13746
d88897ea 13747 add_verb(spec, alc268_volume_init_verbs);
5908589f 13748 spec->num_mux_defs = 2;
61b9b9b1 13749 spec->input_mux = &spec->private_imux[0];
a361d84b 13750
776e184e
TI
13751 err = alc_auto_add_mic_boost(codec);
13752 if (err < 0)
13753 return err;
13754
6227cdce 13755 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13756
a361d84b
KY
13757 return 1;
13758}
13759
a361d84b
KY
13760#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13761
13762/* init callback for auto-configuration model -- overriding the default init */
13763static void alc268_auto_init(struct hda_codec *codec)
13764{
f6c7e546 13765 struct alc_spec *spec = codec->spec;
a361d84b
KY
13766 alc268_auto_init_multi_out(codec);
13767 alc268_auto_init_hp_out(codec);
13768 alc268_auto_init_mono_speaker_out(codec);
13769 alc268_auto_init_analog_input(codec);
757899ac 13770 alc_auto_init_digital(codec);
f6c7e546 13771 if (spec->unsol_event)
7fb0d78f 13772 alc_inithook(codec);
a361d84b
KY
13773}
13774
13775/*
13776 * configuration and preset
13777 */
ea734963 13778static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13779 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13780 [ALC268_3ST] = "3stack",
983f8ae4 13781 [ALC268_TOSHIBA] = "toshiba",
d273809e 13782 [ALC268_ACER] = "acer",
c238b4f4 13783 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13784 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13785 [ALC268_DELL] = "dell",
f12462c5 13786 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13787#ifdef CONFIG_SND_DEBUG
13788 [ALC268_TEST] = "test",
13789#endif
a361d84b
KY
13790 [ALC268_AUTO] = "auto",
13791};
13792
13793static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13794 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13795 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13796 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13797 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13798 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13799 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13800 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13801 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13802 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13803 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13804 /* almost compatible with toshiba but with optional digital outs;
13805 * auto-probing seems working fine
13806 */
8871e5b9 13807 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13808 ALC268_AUTO),
a361d84b 13809 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13810 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13811 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13812 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13813 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13814 {}
13815};
13816
3abf2f36
TI
13817/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13818static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13819 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13820 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13821 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13822 ALC268_TOSHIBA),
13823 {}
13824};
13825
a361d84b 13826static struct alc_config_preset alc268_presets[] = {
eb5a6621 13827 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13828 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13829 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13830 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13831 alc267_quanta_il1_verbs },
13832 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13833 .dac_nids = alc268_dac_nids,
13834 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13835 .adc_nids = alc268_adc_nids_alt,
13836 .hp_nid = 0x03,
13837 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13838 .channel_mode = alc268_modes,
4f5d1706
TI
13839 .unsol_event = alc_sku_unsol_event,
13840 .setup = alc267_quanta_il1_setup,
13841 .init_hook = alc_inithook,
eb5a6621 13842 },
a361d84b 13843 [ALC268_3ST] = {
aef9d318
TI
13844 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13845 alc268_beep_mixer },
a361d84b
KY
13846 .init_verbs = { alc268_base_init_verbs },
13847 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13848 .dac_nids = alc268_dac_nids,
13849 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13850 .adc_nids = alc268_adc_nids_alt,
e1406348 13851 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13852 .hp_nid = 0x03,
13853 .dig_out_nid = ALC268_DIGOUT_NID,
13854 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13855 .channel_mode = alc268_modes,
13856 .input_mux = &alc268_capture_source,
13857 },
d1a991a6 13858 [ALC268_TOSHIBA] = {
42171c17 13859 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13860 alc268_beep_mixer },
d273809e
TI
13861 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13862 alc268_toshiba_verbs },
d1a991a6
KY
13863 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13864 .dac_nids = alc268_dac_nids,
13865 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13866 .adc_nids = alc268_adc_nids_alt,
e1406348 13867 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13868 .hp_nid = 0x03,
13869 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13870 .channel_mode = alc268_modes,
13871 .input_mux = &alc268_capture_source,
d273809e 13872 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13873 .setup = alc268_toshiba_setup,
13874 .init_hook = alc268_toshiba_automute,
d273809e
TI
13875 },
13876 [ALC268_ACER] = {
432fd133 13877 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13878 alc268_beep_mixer },
d273809e
TI
13879 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13880 alc268_acer_verbs },
13881 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13882 .dac_nids = alc268_dac_nids,
13883 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13884 .adc_nids = alc268_adc_nids_alt,
e1406348 13885 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13886 .hp_nid = 0x02,
13887 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13888 .channel_mode = alc268_modes,
0ccb541c 13889 .input_mux = &alc268_acer_capture_source,
d273809e 13890 .unsol_event = alc268_acer_unsol_event,
889c4395 13891 .init_hook = alc268_acer_init_hook,
d1a991a6 13892 },
c238b4f4
TI
13893 [ALC268_ACER_DMIC] = {
13894 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13895 alc268_beep_mixer },
13896 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13897 alc268_acer_verbs },
13898 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13899 .dac_nids = alc268_dac_nids,
13900 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13901 .adc_nids = alc268_adc_nids_alt,
13902 .capsrc_nids = alc268_capsrc_nids,
13903 .hp_nid = 0x02,
13904 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13905 .channel_mode = alc268_modes,
13906 .input_mux = &alc268_acer_dmic_capture_source,
13907 .unsol_event = alc268_acer_unsol_event,
13908 .init_hook = alc268_acer_init_hook,
13909 },
8ef355da
KY
13910 [ALC268_ACER_ASPIRE_ONE] = {
13911 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13912 alc268_beep_mixer,
fdbc6626 13913 alc268_capture_nosrc_mixer },
8ef355da
KY
13914 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13915 alc268_acer_aspire_one_verbs },
13916 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13917 .dac_nids = alc268_dac_nids,
13918 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13919 .adc_nids = alc268_adc_nids_alt,
13920 .capsrc_nids = alc268_capsrc_nids,
13921 .hp_nid = 0x03,
13922 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13923 .channel_mode = alc268_modes,
8ef355da 13924 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13925 .setup = alc268_acer_lc_setup,
8ef355da
KY
13926 .init_hook = alc268_acer_lc_init_hook,
13927 },
3866f0b0 13928 [ALC268_DELL] = {
fdbc6626
TI
13929 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13930 alc268_capture_nosrc_mixer },
3866f0b0
TI
13931 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13932 alc268_dell_verbs },
13933 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13934 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13935 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13936 .adc_nids = alc268_adc_nids_alt,
13937 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13938 .hp_nid = 0x02,
13939 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13940 .channel_mode = alc268_modes,
a9fd4f3f 13941 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13942 .setup = alc268_dell_setup,
13943 .init_hook = alc_inithook,
3866f0b0 13944 },
f12462c5 13945 [ALC268_ZEPTO] = {
aef9d318
TI
13946 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13947 alc268_beep_mixer },
f12462c5
MT
13948 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13949 alc268_toshiba_verbs },
13950 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13951 .dac_nids = alc268_dac_nids,
13952 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13953 .adc_nids = alc268_adc_nids_alt,
e1406348 13954 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13955 .hp_nid = 0x03,
13956 .dig_out_nid = ALC268_DIGOUT_NID,
13957 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13958 .channel_mode = alc268_modes,
13959 .input_mux = &alc268_capture_source,
4f5d1706
TI
13960 .setup = alc268_toshiba_setup,
13961 .init_hook = alc268_toshiba_automute,
f12462c5 13962 },
86c53bd2
JW
13963#ifdef CONFIG_SND_DEBUG
13964 [ALC268_TEST] = {
13965 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13966 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13967 alc268_volume_init_verbs },
13968 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13969 .dac_nids = alc268_dac_nids,
13970 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13971 .adc_nids = alc268_adc_nids_alt,
e1406348 13972 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13973 .hp_nid = 0x03,
13974 .dig_out_nid = ALC268_DIGOUT_NID,
13975 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13976 .channel_mode = alc268_modes,
13977 .input_mux = &alc268_capture_source,
13978 },
13979#endif
a361d84b
KY
13980};
13981
13982static int patch_alc268(struct hda_codec *codec)
13983{
13984 struct alc_spec *spec;
13985 int board_config;
22971e3a 13986 int i, has_beep, err;
a361d84b 13987
ef86f581 13988 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13989 if (spec == NULL)
13990 return -ENOMEM;
13991
13992 codec->spec = spec;
13993
13994 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13995 alc268_models,
13996 alc268_cfg_tbl);
13997
3abf2f36
TI
13998 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13999 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 14000 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 14001
a361d84b 14002 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
14003 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14004 codec->chip_name);
a361d84b
KY
14005 board_config = ALC268_AUTO;
14006 }
14007
14008 if (board_config == ALC268_AUTO) {
14009 /* automatic parse from the BIOS config */
14010 err = alc268_parse_auto_config(codec);
14011 if (err < 0) {
14012 alc_free(codec);
14013 return err;
14014 } else if (!err) {
14015 printk(KERN_INFO
14016 "hda_codec: Cannot set up configuration "
14017 "from BIOS. Using base mode...\n");
14018 board_config = ALC268_3ST;
14019 }
14020 }
14021
14022 if (board_config != ALC268_AUTO)
e9c364c0 14023 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14024
a361d84b
KY
14025 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14026 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14027 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14028
a361d84b
KY
14029 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14030
22971e3a
TI
14031 has_beep = 0;
14032 for (i = 0; i < spec->num_mixers; i++) {
14033 if (spec->mixers[i] == alc268_beep_mixer) {
14034 has_beep = 1;
14035 break;
14036 }
14037 }
14038
14039 if (has_beep) {
14040 err = snd_hda_attach_beep_device(codec, 0x1);
14041 if (err < 0) {
14042 alc_free(codec);
14043 return err;
14044 }
14045 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14046 /* override the amp caps for beep generator */
14047 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14048 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14049 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14050 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14051 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14052 }
aef9d318 14053
7e0e44d4 14054 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14055 /* check whether NID 0x07 is valid */
14056 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 14057 int i;
3866f0b0 14058
defb5ab2 14059 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14060 /* get type */
a22d543a 14061 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14062 if (spec->auto_mic ||
14063 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14064 spec->adc_nids = alc268_adc_nids_alt;
14065 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14066 if (spec->auto_mic)
14067 fixup_automic_adc(codec);
fdbc6626
TI
14068 if (spec->auto_mic || spec->input_mux->num_items == 1)
14069 add_mixer(spec, alc268_capture_nosrc_mixer);
14070 else
14071 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14072 } else {
14073 spec->adc_nids = alc268_adc_nids;
14074 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14075 add_mixer(spec, alc268_capture_mixer);
a361d84b 14076 }
85860c06
TI
14077 /* set default input source */
14078 for (i = 0; i < spec->num_adc_nids; i++)
14079 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14080 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
14081 i < spec->num_mux_defs ?
14082 spec->input_mux[i].items[0].index :
85860c06 14083 spec->input_mux->items[0].index);
a361d84b 14084 }
2134ea4f
TI
14085
14086 spec->vmaster_nid = 0x02;
14087
a361d84b
KY
14088 codec->patch_ops = alc_patch_ops;
14089 if (board_config == ALC268_AUTO)
14090 spec->init_hook = alc268_auto_init;
ea1fb29a 14091
bf1b0225
KY
14092 alc_init_jacks(codec);
14093
a361d84b
KY
14094 return 0;
14095}
14096
f6a92248
KY
14097/*
14098 * ALC269 channel source setting (2 channel)
14099 */
14100#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14101
14102#define alc269_dac_nids alc260_dac_nids
14103
14104static hda_nid_t alc269_adc_nids[1] = {
14105 /* ADC1 */
f53281e6
KY
14106 0x08,
14107};
14108
e01bf509
TI
14109static hda_nid_t alc269_capsrc_nids[1] = {
14110 0x23,
14111};
14112
84898e87
KY
14113static hda_nid_t alc269vb_adc_nids[1] = {
14114 /* ADC1 */
14115 0x09,
14116};
14117
14118static hda_nid_t alc269vb_capsrc_nids[1] = {
14119 0x22,
14120};
14121
6694635d
TI
14122static hda_nid_t alc269_adc_candidates[] = {
14123 0x08, 0x09, 0x07,
14124};
e01bf509 14125
f6a92248
KY
14126#define alc269_modes alc260_modes
14127#define alc269_capture_source alc880_lg_lw_capture_source
14128
14129static struct snd_kcontrol_new alc269_base_mixer[] = {
14130 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14131 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14132 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14133 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14134 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14135 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14136 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14137 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14138 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14139 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14141 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14142 { } /* end */
14143};
14144
60db6b53
KY
14145static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14146 /* output mixer control */
14147 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14148 {
14149 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14150 .name = "Master Playback Switch",
5e26dfd0 14151 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14152 .info = snd_hda_mixer_amp_switch_info,
14153 .get = snd_hda_mixer_amp_switch_get,
14154 .put = alc268_acer_master_sw_put,
14155 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14156 },
14157 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14159 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14160 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14161 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14162 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14163 { }
14164};
14165
64154835
TV
14166static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14167 /* output mixer control */
14168 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14169 {
14170 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14171 .name = "Master Playback Switch",
5e26dfd0 14172 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14173 .info = snd_hda_mixer_amp_switch_info,
14174 .get = snd_hda_mixer_amp_switch_get,
14175 .put = alc268_acer_master_sw_put,
14176 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14177 },
14178 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14179 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14180 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14181 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14182 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14183 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14184 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14185 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14186 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14187 { }
14188};
14189
84898e87 14190static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14191 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14192 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14194 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14195 { } /* end */
14196};
14197
84898e87
KY
14198static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14199 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14200 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14201 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14202 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14203 { } /* end */
14204};
14205
fe3eb0a7
KY
14206static struct snd_kcontrol_new alc269_asus_mixer[] = {
14207 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14208 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14209 { } /* end */
14210};
14211
f53281e6 14212/* capture mixer elements */
84898e87
KY
14213static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14214 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14215 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14216 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14217 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14218 { } /* end */
14219};
14220
14221static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14222 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14223 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14224 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14225 { } /* end */
14226};
14227
84898e87
KY
14228static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14229 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14230 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14231 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14232 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14233 { } /* end */
14234};
14235
14236static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14237 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14238 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14239 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14240 { } /* end */
14241};
14242
26f5df26 14243/* FSC amilo */
84898e87 14244#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14245
60db6b53
KY
14246static struct hda_verb alc269_quanta_fl1_verbs[] = {
14247 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14248 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14249 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14250 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14251 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14252 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14253 { }
14254};
f6a92248 14255
64154835
TV
14256static struct hda_verb alc269_lifebook_verbs[] = {
14257 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14258 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14259 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14260 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14261 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14262 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14263 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14264 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14265 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14266 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14267 { }
14268};
14269
60db6b53
KY
14270/* toggle speaker-output according to the hp-jack state */
14271static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14272{
14273 unsigned int present;
14274 unsigned char bits;
f6a92248 14275
864f92be 14276 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14277 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14278 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14279 HDA_AMP_MUTE, bits);
60db6b53 14280 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14281 HDA_AMP_MUTE, bits);
f6a92248 14282
60db6b53
KY
14283 snd_hda_codec_write(codec, 0x20, 0,
14284 AC_VERB_SET_COEF_INDEX, 0x0c);
14285 snd_hda_codec_write(codec, 0x20, 0,
14286 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14287
60db6b53
KY
14288 snd_hda_codec_write(codec, 0x20, 0,
14289 AC_VERB_SET_COEF_INDEX, 0x0c);
14290 snd_hda_codec_write(codec, 0x20, 0,
14291 AC_VERB_SET_PROC_COEF, 0x480);
14292}
f6a92248 14293
64154835
TV
14294/* toggle speaker-output according to the hp-jacks state */
14295static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14296{
14297 unsigned int present;
14298 unsigned char bits;
14299
14300 /* Check laptop headphone socket */
864f92be 14301 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14302
14303 /* Check port replicator headphone socket */
864f92be 14304 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14305
5dbd5ec6 14306 bits = present ? HDA_AMP_MUTE : 0;
64154835 14307 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14308 HDA_AMP_MUTE, bits);
64154835 14309 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14310 HDA_AMP_MUTE, bits);
64154835
TV
14311
14312 snd_hda_codec_write(codec, 0x20, 0,
14313 AC_VERB_SET_COEF_INDEX, 0x0c);
14314 snd_hda_codec_write(codec, 0x20, 0,
14315 AC_VERB_SET_PROC_COEF, 0x680);
14316
14317 snd_hda_codec_write(codec, 0x20, 0,
14318 AC_VERB_SET_COEF_INDEX, 0x0c);
14319 snd_hda_codec_write(codec, 0x20, 0,
14320 AC_VERB_SET_PROC_COEF, 0x480);
14321}
14322
64154835
TV
14323static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14324{
14325 unsigned int present_laptop;
14326 unsigned int present_dock;
14327
864f92be
WF
14328 present_laptop = snd_hda_jack_detect(codec, 0x18);
14329 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14330
14331 /* Laptop mic port overrides dock mic port, design decision */
14332 if (present_dock)
14333 snd_hda_codec_write(codec, 0x23, 0,
14334 AC_VERB_SET_CONNECT_SEL, 0x3);
14335 if (present_laptop)
14336 snd_hda_codec_write(codec, 0x23, 0,
14337 AC_VERB_SET_CONNECT_SEL, 0x0);
14338 if (!present_dock && !present_laptop)
14339 snd_hda_codec_write(codec, 0x23, 0,
14340 AC_VERB_SET_CONNECT_SEL, 0x1);
14341}
14342
60db6b53
KY
14343static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14344 unsigned int res)
14345{
4f5d1706
TI
14346 switch (res >> 26) {
14347 case ALC880_HP_EVENT:
60db6b53 14348 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14349 break;
14350 case ALC880_MIC_EVENT:
14351 alc_mic_automute(codec);
14352 break;
14353 }
60db6b53 14354}
f6a92248 14355
64154835
TV
14356static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14357 unsigned int res)
14358{
14359 if ((res >> 26) == ALC880_HP_EVENT)
14360 alc269_lifebook_speaker_automute(codec);
14361 if ((res >> 26) == ALC880_MIC_EVENT)
14362 alc269_lifebook_mic_autoswitch(codec);
14363}
14364
4f5d1706
TI
14365static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14366{
14367 struct alc_spec *spec = codec->spec;
20645d70
TI
14368 spec->autocfg.hp_pins[0] = 0x15;
14369 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14370 spec->ext_mic.pin = 0x18;
14371 spec->ext_mic.mux_idx = 0;
14372 spec->int_mic.pin = 0x19;
14373 spec->int_mic.mux_idx = 1;
14374 spec->auto_mic = 1;
14375}
14376
60db6b53
KY
14377static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14378{
14379 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14380 alc_mic_automute(codec);
60db6b53 14381}
f6a92248 14382
64154835
TV
14383static void alc269_lifebook_init_hook(struct hda_codec *codec)
14384{
14385 alc269_lifebook_speaker_automute(codec);
14386 alc269_lifebook_mic_autoswitch(codec);
14387}
14388
84898e87 14389static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14390 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14391 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14392 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14393 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14394 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14395 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14396 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14397 {}
14398};
14399
84898e87 14400static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14401 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14402 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14403 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14404 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14405 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14406 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14407 {}
14408};
14409
84898e87
KY
14410static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14411 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14412 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14413 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14414 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14415 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14416 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14417 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14418 {}
14419};
14420
14421static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14422 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14423 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14424 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14425 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14426 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14427 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14428 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14429 {}
14430};
14431
fe3eb0a7
KY
14432static struct hda_verb alc271_acer_dmic_verbs[] = {
14433 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14434 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14435 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14436 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14437 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14438 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14439 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14440 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14441 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14442 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14443 { }
14444};
14445
f53281e6
KY
14446/* toggle speaker-output according to the hp-jack state */
14447static void alc269_speaker_automute(struct hda_codec *codec)
14448{
ebb83eeb
KY
14449 struct alc_spec *spec = codec->spec;
14450 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14451 unsigned int present;
60db6b53 14452 unsigned char bits;
f53281e6 14453
ebb83eeb 14454 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14455 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14456 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14457 HDA_AMP_MUTE, bits);
f53281e6 14458 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14459 HDA_AMP_MUTE, bits);
cd372fb3 14460 snd_hda_input_jack_report(codec, nid);
f53281e6
KY
14461}
14462
f53281e6 14463/* unsolicited event for HP jack sensing */
84898e87 14464static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14465 unsigned int res)
f53281e6 14466{
4f5d1706
TI
14467 switch (res >> 26) {
14468 case ALC880_HP_EVENT:
f53281e6 14469 alc269_speaker_automute(codec);
4f5d1706
TI
14470 break;
14471 case ALC880_MIC_EVENT:
14472 alc_mic_automute(codec);
14473 break;
14474 }
f53281e6
KY
14475}
14476
226b1ec8 14477static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14478{
4f5d1706 14479 struct alc_spec *spec = codec->spec;
20645d70
TI
14480 spec->autocfg.hp_pins[0] = 0x15;
14481 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14482 spec->ext_mic.pin = 0x18;
14483 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14484 spec->int_mic.pin = 0x19;
14485 spec->int_mic.mux_idx = 1;
4f5d1706 14486 spec->auto_mic = 1;
f53281e6
KY
14487}
14488
226b1ec8 14489static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14490{
14491 struct alc_spec *spec = codec->spec;
20645d70
TI
14492 spec->autocfg.hp_pins[0] = 0x15;
14493 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14494 spec->ext_mic.pin = 0x18;
14495 spec->ext_mic.mux_idx = 0;
14496 spec->int_mic.pin = 0x12;
226b1ec8 14497 spec->int_mic.mux_idx = 5;
84898e87
KY
14498 spec->auto_mic = 1;
14499}
14500
226b1ec8 14501static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14502{
4f5d1706 14503 struct alc_spec *spec = codec->spec;
226b1ec8 14504 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14505 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14506 spec->ext_mic.pin = 0x18;
14507 spec->ext_mic.mux_idx = 0;
14508 spec->int_mic.pin = 0x19;
14509 spec->int_mic.mux_idx = 1;
14510 spec->auto_mic = 1;
f53281e6
KY
14511}
14512
226b1ec8
KY
14513static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14514{
14515 struct alc_spec *spec = codec->spec;
14516 spec->autocfg.hp_pins[0] = 0x21;
14517 spec->autocfg.speaker_pins[0] = 0x14;
14518 spec->ext_mic.pin = 0x18;
14519 spec->ext_mic.mux_idx = 0;
14520 spec->int_mic.pin = 0x12;
14521 spec->int_mic.mux_idx = 6;
14522 spec->auto_mic = 1;
14523}
14524
84898e87 14525static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14526{
14527 alc269_speaker_automute(codec);
4f5d1706 14528 alc_mic_automute(codec);
f53281e6
KY
14529}
14530
60db6b53
KY
14531/*
14532 * generic initialization of ADC, input mixers and output mixers
14533 */
14534static struct hda_verb alc269_init_verbs[] = {
14535 /*
14536 * Unmute ADC0 and set the default input to mic-in
14537 */
84898e87 14538 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14539
14540 /*
84898e87 14541 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14542 */
14543 /* set vol=0 to output mixers */
14544 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14545 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14546
14547 /* set up input amps for analog loopback */
14548 /* Amp Indices: DAC = 0, mixer = 1 */
14549 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14551 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14552 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14553 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14554 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14555
14556 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14557 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14558 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14559 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14560 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14561 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14562 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14563
14564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14565 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14566
84898e87
KY
14567 /* FIXME: use Mux-type input source selection */
14568 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14569 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14570 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14571
84898e87
KY
14572 /* set EAPD */
14573 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14574 { }
14575};
14576
14577static struct hda_verb alc269vb_init_verbs[] = {
14578 /*
14579 * Unmute ADC0 and set the default input to mic-in
14580 */
14581 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14582
14583 /*
14584 * Set up output mixers (0x02 - 0x03)
14585 */
14586 /* set vol=0 to output mixers */
14587 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14588 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14589
14590 /* set up input amps for analog loopback */
14591 /* Amp Indices: DAC = 0, mixer = 1 */
14592 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14593 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14594 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14595 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14596 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14597 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14598
14599 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14600 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14601 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14602 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14603 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14604 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14605 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14606
14607 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14608 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14609
14610 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14611 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14612 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14613 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14614
14615 /* set EAPD */
14616 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14617 { }
14618};
14619
9d0b71b1
TI
14620#define alc269_auto_create_multi_out_ctls \
14621 alc268_auto_create_multi_out_ctls
05f5f477
TI
14622#define alc269_auto_create_input_ctls \
14623 alc268_auto_create_input_ctls
f6a92248
KY
14624
14625#ifdef CONFIG_SND_HDA_POWER_SAVE
14626#define alc269_loopbacks alc880_loopbacks
14627#endif
14628
def319f9 14629/* pcm configuration: identical with ALC880 */
f6a92248
KY
14630#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14631#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14632#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14633#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14634
f03d3115
TI
14635static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14636 .substreams = 1,
14637 .channels_min = 2,
14638 .channels_max = 8,
14639 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14640 /* NID is set in alc_build_pcms */
14641 .ops = {
14642 .open = alc880_playback_pcm_open,
14643 .prepare = alc880_playback_pcm_prepare,
14644 .cleanup = alc880_playback_pcm_cleanup
14645 },
14646};
14647
14648static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14649 .substreams = 1,
14650 .channels_min = 2,
14651 .channels_max = 2,
14652 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14653 /* NID is set in alc_build_pcms */
14654};
14655
ad35879a
TI
14656#ifdef CONFIG_SND_HDA_POWER_SAVE
14657static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14658{
14659 switch (codec->subsystem_id) {
14660 case 0x103c1586:
14661 return 1;
14662 }
14663 return 0;
14664}
14665
14666static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14667{
14668 /* update mute-LED according to the speaker mute state */
14669 if (nid == 0x01 || nid == 0x14) {
14670 int pinval;
14671 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14672 HDA_AMP_MUTE)
14673 pinval = 0x24;
14674 else
14675 pinval = 0x20;
14676 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14677 snd_hda_codec_update_cache(codec, 0x19, 0,
14678 AC_VERB_SET_PIN_WIDGET_CONTROL,
14679 pinval);
ad35879a
TI
14680 }
14681 return alc_check_power_status(codec, nid);
14682}
14683#endif /* CONFIG_SND_HDA_POWER_SAVE */
14684
840b64c0
TI
14685static int alc275_setup_dual_adc(struct hda_codec *codec)
14686{
14687 struct alc_spec *spec = codec->spec;
14688
14689 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14690 return 0;
14691 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14692 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14693 if (spec->ext_mic.pin <= 0x12) {
14694 spec->private_adc_nids[0] = 0x08;
14695 spec->private_adc_nids[1] = 0x11;
14696 spec->private_capsrc_nids[0] = 0x23;
14697 spec->private_capsrc_nids[1] = 0x22;
14698 } else {
14699 spec->private_adc_nids[0] = 0x11;
14700 spec->private_adc_nids[1] = 0x08;
14701 spec->private_capsrc_nids[0] = 0x22;
14702 spec->private_capsrc_nids[1] = 0x23;
14703 }
14704 spec->adc_nids = spec->private_adc_nids;
14705 spec->capsrc_nids = spec->private_capsrc_nids;
14706 spec->num_adc_nids = 2;
14707 spec->dual_adc_switch = 1;
14708 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14709 spec->adc_nids[0], spec->adc_nids[1]);
14710 return 1;
14711 }
14712 return 0;
14713}
14714
d433a678
TI
14715/* different alc269-variants */
14716enum {
14717 ALC269_TYPE_NORMAL,
48c88e82 14718 ALC269_TYPE_ALC258,
d433a678 14719 ALC269_TYPE_ALC259,
48c88e82
KY
14720 ALC269_TYPE_ALC269VB,
14721 ALC269_TYPE_ALC270,
d433a678
TI
14722 ALC269_TYPE_ALC271X,
14723};
14724
f6a92248
KY
14725/*
14726 * BIOS auto configuration
14727 */
14728static int alc269_parse_auto_config(struct hda_codec *codec)
14729{
14730 struct alc_spec *spec = codec->spec;
cfb9fb55 14731 int err;
f6a92248
KY
14732 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14733
14734 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14735 alc269_ignore);
14736 if (err < 0)
14737 return err;
14738
14739 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14740 if (err < 0)
14741 return err;
f3550d1b
TI
14742 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14743 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14744 else
14745 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14746 0x22, 0);
f6a92248
KY
14747 if (err < 0)
14748 return err;
14749
14750 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14751
757899ac 14752 alc_auto_parse_digital(codec);
f6a92248 14753
603c4019 14754 if (spec->kctls.list)
d88897ea 14755 add_mixer(spec, spec->kctls.list);
f6a92248 14756
d433a678 14757 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14758 add_verb(spec, alc269vb_init_verbs);
6227cdce 14759 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14760 } else {
14761 add_verb(spec, alc269_init_verbs);
6227cdce 14762 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14763 }
14764
f6a92248 14765 spec->num_mux_defs = 1;
61b9b9b1 14766 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14767
14768 if (!alc275_setup_dual_adc(codec))
14769 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14770 sizeof(alc269_adc_candidates));
6694635d 14771
e01bf509 14772 /* set default input source */
840b64c0 14773 if (!spec->dual_adc_switch)
748cce43
TI
14774 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14775 spec->input_mux->items[0].index);
f6a92248
KY
14776
14777 err = alc_auto_add_mic_boost(codec);
14778 if (err < 0)
14779 return err;
14780
7e0e44d4 14781 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14782 set_capture_mixer(codec);
f53281e6 14783
f6a92248
KY
14784 return 1;
14785}
14786
e9af4f36
TI
14787#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14788#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14789#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14790
14791
14792/* init callback for auto-configuration model -- overriding the default init */
14793static void alc269_auto_init(struct hda_codec *codec)
14794{
f6c7e546 14795 struct alc_spec *spec = codec->spec;
f6a92248
KY
14796 alc269_auto_init_multi_out(codec);
14797 alc269_auto_init_hp_out(codec);
14798 alc269_auto_init_analog_input(codec);
757899ac 14799 alc_auto_init_digital(codec);
f6c7e546 14800 if (spec->unsol_event)
7fb0d78f 14801 alc_inithook(codec);
f6a92248
KY
14802}
14803
0ec33d1f
TI
14804#ifdef SND_HDA_NEEDS_RESUME
14805static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14806{
14807 int val = alc_read_coef_idx(codec, 0x04);
14808 if (power_up)
14809 val |= 1 << 11;
14810 else
14811 val &= ~(1 << 11);
14812 alc_write_coef_idx(codec, 0x04, val);
14813}
14814
977ddd6b
KY
14815#ifdef CONFIG_SND_HDA_POWER_SAVE
14816static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14817{
14818 struct alc_spec *spec = codec->spec;
977ddd6b 14819
0ec33d1f
TI
14820 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14821 alc269_toggle_power_output(codec, 0);
977ddd6b 14822 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14823 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14824 msleep(150);
14825 }
14826
14827 alc_shutup(codec);
14828 if (spec && spec->power_hook)
14829 spec->power_hook(codec);
14830 return 0;
14831}
0ec33d1f
TI
14832#endif /* CONFIG_SND_HDA_POWER_SAVE */
14833
977ddd6b
KY
14834static int alc269_resume(struct hda_codec *codec)
14835{
977ddd6b 14836 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14837 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14838 msleep(150);
14839 }
14840
14841 codec->patch_ops.init(codec);
14842
14843 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14844 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14845 msleep(200);
14846 }
14847
0ec33d1f
TI
14848 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14849 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14850
14851 snd_hda_codec_resume_amp(codec);
14852 snd_hda_codec_resume_cache(codec);
9e5341b9 14853 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14854 return 0;
14855}
0ec33d1f 14856#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14857
1a99d4a4 14858static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14859 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14860{
14861 int coef;
14862
58701120 14863 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14864 return;
1a99d4a4
KY
14865 coef = alc_read_coef_idx(codec, 0x1e);
14866 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14867}
14868
ff818c24
TI
14869enum {
14870 ALC269_FIXUP_SONY_VAIO,
74dc8909 14871 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14872 ALC269_FIXUP_DELL_M101Z,
022c92be 14873 ALC269_FIXUP_SKU_IGNORE,
ac612407 14874 ALC269_FIXUP_ASUS_G73JW,
357f915e 14875 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14876 ALC275_FIXUP_SONY_HWEQ,
ff818c24
TI
14877};
14878
ff818c24
TI
14879static const struct alc_fixup alc269_fixups[] = {
14880 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14881 .type = ALC_FIXUP_VERBS,
14882 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14883 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14884 {}
14885 }
ff818c24 14886 },
74dc8909 14887 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14888 .type = ALC_FIXUP_VERBS,
14889 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14890 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14891 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14892 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14893 { }
b5bfbc67
TI
14894 },
14895 .chained = true,
14896 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14897 },
145a902b 14898 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14899 .type = ALC_FIXUP_VERBS,
14900 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14901 /* Enables internal speaker */
14902 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14903 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14904 {}
14905 }
14906 },
022c92be 14907 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14908 .type = ALC_FIXUP_SKU,
14909 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14910 },
ac612407 14911 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14912 .type = ALC_FIXUP_PINS,
14913 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14914 { 0x17, 0x99130111 }, /* subwoofer */
14915 { }
14916 }
14917 },
357f915e 14918 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14919 .type = ALC_FIXUP_VERBS,
14920 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14921 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14922 {}
14923 }
14924 },
1a99d4a4 14925 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14926 .type = ALC_FIXUP_FUNC,
14927 .v.func = alc269_fixup_hweq,
14928 .chained = true,
14929 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
1a99d4a4 14930 }
ff818c24
TI
14931};
14932
14933static struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14934 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14935 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14936 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14937 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14938 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
022c92be 14939 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14940 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14941 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14942 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14943 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14944 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14945 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14946 {}
14947};
14948
14949
f6a92248
KY
14950/*
14951 * configuration and preset
14952 */
ea734963 14953static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14954 [ALC269_BASIC] = "basic",
2922c9af 14955 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14956 [ALC269_AMIC] = "laptop-amic",
14957 [ALC269_DMIC] = "laptop-dmic",
64154835 14958 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14959 [ALC269_LIFEBOOK] = "lifebook",
14960 [ALC269_AUTO] = "auto",
f6a92248
KY
14961};
14962
14963static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14964 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14965 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14966 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14967 ALC269_AMIC),
14968 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14969 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14970 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14971 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14972 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14973 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14974 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14975 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14976 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14977 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14978 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14979 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14980 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14981 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14982 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14983 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14984 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14985 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14986 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14987 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14988 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14989 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14990 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14991 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14992 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14993 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14994 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14995 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14996 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14997 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14998 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14999 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15000 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15001 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15002 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15003 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 15004 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 15005 ALC269_DMIC),
60db6b53 15006 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
15007 ALC269_DMIC),
15008 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15009 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 15010 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 15011 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
15012 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15013 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15014 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15015 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15016 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15017 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
15018 {}
15019};
15020
15021static struct alc_config_preset alc269_presets[] = {
15022 [ALC269_BASIC] = {
f9e336f6 15023 .mixers = { alc269_base_mixer },
f6a92248
KY
15024 .init_verbs = { alc269_init_verbs },
15025 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15026 .dac_nids = alc269_dac_nids,
15027 .hp_nid = 0x03,
15028 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15029 .channel_mode = alc269_modes,
15030 .input_mux = &alc269_capture_source,
15031 },
60db6b53
KY
15032 [ALC269_QUANTA_FL1] = {
15033 .mixers = { alc269_quanta_fl1_mixer },
15034 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15035 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15036 .dac_nids = alc269_dac_nids,
15037 .hp_nid = 0x03,
15038 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15039 .channel_mode = alc269_modes,
15040 .input_mux = &alc269_capture_source,
15041 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15042 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15043 .init_hook = alc269_quanta_fl1_init_hook,
15044 },
84898e87
KY
15045 [ALC269_AMIC] = {
15046 .mixers = { alc269_laptop_mixer },
15047 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15048 .init_verbs = { alc269_init_verbs,
84898e87 15049 alc269_laptop_amic_init_verbs },
f53281e6
KY
15050 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15051 .dac_nids = alc269_dac_nids,
15052 .hp_nid = 0x03,
15053 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15054 .channel_mode = alc269_modes,
84898e87
KY
15055 .unsol_event = alc269_laptop_unsol_event,
15056 .setup = alc269_laptop_amic_setup,
15057 .init_hook = alc269_laptop_inithook,
f53281e6 15058 },
84898e87
KY
15059 [ALC269_DMIC] = {
15060 .mixers = { alc269_laptop_mixer },
15061 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15062 .init_verbs = { alc269_init_verbs,
84898e87
KY
15063 alc269_laptop_dmic_init_verbs },
15064 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15065 .dac_nids = alc269_dac_nids,
15066 .hp_nid = 0x03,
15067 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15068 .channel_mode = alc269_modes,
15069 .unsol_event = alc269_laptop_unsol_event,
15070 .setup = alc269_laptop_dmic_setup,
15071 .init_hook = alc269_laptop_inithook,
15072 },
15073 [ALC269VB_AMIC] = {
15074 .mixers = { alc269vb_laptop_mixer },
15075 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15076 .init_verbs = { alc269vb_init_verbs,
15077 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15078 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15079 .dac_nids = alc269_dac_nids,
15080 .hp_nid = 0x03,
15081 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15082 .channel_mode = alc269_modes,
84898e87 15083 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 15084 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
15085 .init_hook = alc269_laptop_inithook,
15086 },
15087 [ALC269VB_DMIC] = {
15088 .mixers = { alc269vb_laptop_mixer },
15089 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15090 .init_verbs = { alc269vb_init_verbs,
15091 alc269vb_laptop_dmic_init_verbs },
15092 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15093 .dac_nids = alc269_dac_nids,
15094 .hp_nid = 0x03,
15095 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15096 .channel_mode = alc269_modes,
15097 .unsol_event = alc269_laptop_unsol_event,
15098 .setup = alc269vb_laptop_dmic_setup,
15099 .init_hook = alc269_laptop_inithook,
f53281e6 15100 },
26f5df26 15101 [ALC269_FUJITSU] = {
45bdd1c1 15102 .mixers = { alc269_fujitsu_mixer },
84898e87 15103 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15104 .init_verbs = { alc269_init_verbs,
84898e87 15105 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15106 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15107 .dac_nids = alc269_dac_nids,
15108 .hp_nid = 0x03,
15109 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15110 .channel_mode = alc269_modes,
84898e87
KY
15111 .unsol_event = alc269_laptop_unsol_event,
15112 .setup = alc269_laptop_dmic_setup,
15113 .init_hook = alc269_laptop_inithook,
26f5df26 15114 },
64154835
TV
15115 [ALC269_LIFEBOOK] = {
15116 .mixers = { alc269_lifebook_mixer },
15117 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15118 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15119 .dac_nids = alc269_dac_nids,
15120 .hp_nid = 0x03,
15121 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15122 .channel_mode = alc269_modes,
15123 .input_mux = &alc269_capture_source,
15124 .unsol_event = alc269_lifebook_unsol_event,
15125 .init_hook = alc269_lifebook_init_hook,
15126 },
fe3eb0a7
KY
15127 [ALC271_ACER] = {
15128 .mixers = { alc269_asus_mixer },
15129 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15130 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15131 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15132 .dac_nids = alc269_dac_nids,
15133 .adc_nids = alc262_dmic_adc_nids,
15134 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15135 .capsrc_nids = alc262_dmic_capsrc_nids,
15136 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15137 .channel_mode = alc269_modes,
15138 .input_mux = &alc269_capture_source,
15139 .dig_out_nid = ALC880_DIGOUT_NID,
15140 .unsol_event = alc_sku_unsol_event,
15141 .setup = alc269vb_laptop_dmic_setup,
15142 .init_hook = alc_inithook,
15143 },
f6a92248
KY
15144};
15145
977ddd6b
KY
15146static int alc269_fill_coef(struct hda_codec *codec)
15147{
15148 int val;
15149
15150 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15151 alc_write_coef_idx(codec, 0xf, 0x960b);
15152 alc_write_coef_idx(codec, 0xe, 0x8817);
15153 }
15154
15155 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15156 alc_write_coef_idx(codec, 0xf, 0x960b);
15157 alc_write_coef_idx(codec, 0xe, 0x8814);
15158 }
15159
15160 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15161 val = alc_read_coef_idx(codec, 0x04);
15162 /* Power up output pin */
15163 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15164 }
15165
15166 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15167 val = alc_read_coef_idx(codec, 0xd);
15168 if ((val & 0x0c00) >> 10 != 0x1) {
15169 /* Capless ramp up clock control */
15170 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15171 }
15172 val = alc_read_coef_idx(codec, 0x17);
15173 if ((val & 0x01c0) >> 6 != 0x4) {
15174 /* Class D power on reset */
15175 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15176 }
15177 }
15178 return 0;
15179}
15180
f6a92248
KY
15181static int patch_alc269(struct hda_codec *codec)
15182{
15183 struct alc_spec *spec;
48c88e82 15184 int board_config, coef;
f6a92248
KY
15185 int err;
15186
15187 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15188 if (spec == NULL)
15189 return -ENOMEM;
15190
15191 codec->spec = spec;
15192
da00c244
KY
15193 alc_auto_parse_customize_define(codec);
15194
c793bec5
KY
15195 if (codec->vendor_id == 0x10ec0269) {
15196 coef = alc_read_coef_idx(codec, 0);
15197 if ((coef & 0x00f0) == 0x0010) {
15198 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15199 spec->cdefine.platform_type == 1) {
15200 alc_codec_rename(codec, "ALC271X");
15201 spec->codec_variant = ALC269_TYPE_ALC271X;
15202 } else if ((coef & 0xf000) == 0x1000) {
15203 spec->codec_variant = ALC269_TYPE_ALC270;
15204 } else if ((coef & 0xf000) == 0x2000) {
15205 alc_codec_rename(codec, "ALC259");
15206 spec->codec_variant = ALC269_TYPE_ALC259;
15207 } else if ((coef & 0xf000) == 0x3000) {
15208 alc_codec_rename(codec, "ALC258");
15209 spec->codec_variant = ALC269_TYPE_ALC258;
15210 } else {
15211 alc_codec_rename(codec, "ALC269VB");
15212 spec->codec_variant = ALC269_TYPE_ALC269VB;
15213 }
15214 } else
15215 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15216 alc269_fill_coef(codec);
15217 }
977ddd6b 15218
f6a92248
KY
15219 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15220 alc269_models,
15221 alc269_cfg_tbl);
15222
15223 if (board_config < 0) {
9a11f1aa
TI
15224 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15225 codec->chip_name);
f6a92248
KY
15226 board_config = ALC269_AUTO;
15227 }
15228
b5bfbc67
TI
15229 if (board_config == ALC269_AUTO) {
15230 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15231 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15232 }
ff818c24 15233
f6a92248
KY
15234 if (board_config == ALC269_AUTO) {
15235 /* automatic parse from the BIOS config */
15236 err = alc269_parse_auto_config(codec);
15237 if (err < 0) {
15238 alc_free(codec);
15239 return err;
15240 } else if (!err) {
15241 printk(KERN_INFO
15242 "hda_codec: Cannot set up configuration "
15243 "from BIOS. Using base mode...\n");
15244 board_config = ALC269_BASIC;
15245 }
15246 }
15247
dc1eae25 15248 if (has_cdefine_beep(codec)) {
8af2591d
TI
15249 err = snd_hda_attach_beep_device(codec, 0x1);
15250 if (err < 0) {
15251 alc_free(codec);
15252 return err;
15253 }
680cd536
KK
15254 }
15255
f6a92248 15256 if (board_config != ALC269_AUTO)
e9c364c0 15257 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15258
84898e87 15259 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15260 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15261 * fix the sample rate of analog I/O to 44.1kHz
15262 */
15263 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15264 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15265 } else if (spec->dual_adc_switch) {
15266 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15267 /* switch ADC dynamically */
15268 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15269 } else {
15270 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15271 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15272 }
f6a92248
KY
15273 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15274 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15275
6694635d 15276 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15277 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15278 spec->adc_nids = alc269_adc_nids;
15279 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15280 spec->capsrc_nids = alc269_capsrc_nids;
15281 } else {
15282 spec->adc_nids = alc269vb_adc_nids;
15283 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15284 spec->capsrc_nids = alc269vb_capsrc_nids;
15285 }
84898e87
KY
15286 }
15287
f9e336f6 15288 if (!spec->cap_mixer)
b59bdf3b 15289 set_capture_mixer(codec);
dc1eae25 15290 if (has_cdefine_beep(codec))
da00c244 15291 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15292
b5bfbc67 15293 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15294
100d5eb3
TI
15295 spec->vmaster_nid = 0x02;
15296
f6a92248 15297 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15298#ifdef CONFIG_SND_HDA_POWER_SAVE
15299 codec->patch_ops.suspend = alc269_suspend;
15300#endif
15301#ifdef SND_HDA_NEEDS_RESUME
15302 codec->patch_ops.resume = alc269_resume;
15303#endif
f6a92248
KY
15304 if (board_config == ALC269_AUTO)
15305 spec->init_hook = alc269_auto_init;
bf1b0225
KY
15306
15307 alc_init_jacks(codec);
f6a92248
KY
15308#ifdef CONFIG_SND_HDA_POWER_SAVE
15309 if (!spec->loopback.amplist)
15310 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15311 if (alc269_mic2_for_mute_led(codec))
15312 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15313#endif
15314
15315 return 0;
15316}
15317
df694daa
KY
15318/*
15319 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15320 */
15321
15322/*
15323 * set the path ways for 2 channel output
15324 * need to set the codec line out and mic 1 pin widgets to inputs
15325 */
15326static struct hda_verb alc861_threestack_ch2_init[] = {
15327 /* set pin widget 1Ah (line in) for input */
15328 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15329 /* set pin widget 18h (mic1/2) for input, for mic also enable
15330 * the vref
15331 */
df694daa
KY
15332 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15333
9c7f852e
TI
15334 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15335#if 0
15336 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15337 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15338#endif
df694daa
KY
15339 { } /* end */
15340};
15341/*
15342 * 6ch mode
15343 * need to set the codec line out and mic 1 pin widgets to outputs
15344 */
15345static struct hda_verb alc861_threestack_ch6_init[] = {
15346 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15347 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15348 /* set pin widget 18h (mic1) for output (CLFE)*/
15349 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15350
15351 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15352 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15353
9c7f852e
TI
15354 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15355#if 0
15356 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15357 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15358#endif
df694daa
KY
15359 { } /* end */
15360};
15361
15362static struct hda_channel_mode alc861_threestack_modes[2] = {
15363 { 2, alc861_threestack_ch2_init },
15364 { 6, alc861_threestack_ch6_init },
15365};
22309c3e
TI
15366/* Set mic1 as input and unmute the mixer */
15367static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15368 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15369 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15370 { } /* end */
15371};
15372/* Set mic1 as output and mute mixer */
15373static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15374 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15375 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15376 { } /* end */
15377};
15378
15379static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15380 { 2, alc861_uniwill_m31_ch2_init },
15381 { 4, alc861_uniwill_m31_ch4_init },
15382};
df694daa 15383
7cdbff94
MD
15384/* Set mic1 and line-in as input and unmute the mixer */
15385static struct hda_verb alc861_asus_ch2_init[] = {
15386 /* set pin widget 1Ah (line in) for input */
15387 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15388 /* set pin widget 18h (mic1/2) for input, for mic also enable
15389 * the vref
15390 */
7cdbff94
MD
15391 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15392
15393 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15394#if 0
15395 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15396 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15397#endif
15398 { } /* end */
15399};
15400/* Set mic1 nad line-in as output and mute mixer */
15401static struct hda_verb alc861_asus_ch6_init[] = {
15402 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15403 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15404 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15405 /* set pin widget 18h (mic1) for output (CLFE)*/
15406 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15407 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15408 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15409 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15410
15411 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15412#if 0
15413 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15414 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15415#endif
15416 { } /* end */
15417};
15418
15419static struct hda_channel_mode alc861_asus_modes[2] = {
15420 { 2, alc861_asus_ch2_init },
15421 { 6, alc861_asus_ch6_init },
15422};
15423
df694daa
KY
15424/* patch-ALC861 */
15425
15426static struct snd_kcontrol_new alc861_base_mixer[] = {
15427 /* output mixer control */
15428 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15429 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15430 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15431 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15432 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15433
15434 /*Input mixer control */
15435 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15436 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15437 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15438 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15439 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15440 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15441 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15442 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15443 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15444 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15445
df694daa
KY
15446 { } /* end */
15447};
15448
15449static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15450 /* output mixer control */
15451 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15452 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15453 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15454 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15455 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15456
15457 /* Input mixer control */
15458 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15459 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15460 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15461 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15462 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15463 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15465 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15466 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15467 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15468
df694daa
KY
15469 {
15470 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15471 .name = "Channel Mode",
15472 .info = alc_ch_mode_info,
15473 .get = alc_ch_mode_get,
15474 .put = alc_ch_mode_put,
15475 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15476 },
15477 { } /* end */
a53d1aec
TD
15478};
15479
d1d985f0 15480static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15481 /* output mixer control */
15482 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15484 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15485
a53d1aec 15486 { } /* end */
f12ab1e0 15487};
a53d1aec 15488
22309c3e
TI
15489static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15490 /* output mixer control */
15491 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15492 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15493 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15494 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15495 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15496
15497 /* Input mixer control */
15498 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15499 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15500 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15501 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15502 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15503 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15504 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15505 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15506 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15508
22309c3e
TI
15509 {
15510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15511 .name = "Channel Mode",
15512 .info = alc_ch_mode_info,
15513 .get = alc_ch_mode_get,
15514 .put = alc_ch_mode_put,
15515 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15516 },
15517 { } /* end */
f12ab1e0 15518};
7cdbff94
MD
15519
15520static struct snd_kcontrol_new alc861_asus_mixer[] = {
15521 /* output mixer control */
15522 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15523 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15524 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15525 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15526 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15527
15528 /* Input mixer control */
15529 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15530 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15531 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15532 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15533 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15534 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15536 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15537 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15538 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15539
7cdbff94
MD
15540 {
15541 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15542 .name = "Channel Mode",
15543 .info = alc_ch_mode_info,
15544 .get = alc_ch_mode_get,
15545 .put = alc_ch_mode_put,
15546 .private_value = ARRAY_SIZE(alc861_asus_modes),
15547 },
15548 { }
56bb0cab
TI
15549};
15550
15551/* additional mixer */
d1d985f0 15552static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15553 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15554 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15555 { }
15556};
7cdbff94 15557
df694daa
KY
15558/*
15559 * generic initialization of ADC, input mixers and output mixers
15560 */
15561static struct hda_verb alc861_base_init_verbs[] = {
15562 /*
15563 * Unmute ADC0 and set the default input to mic-in
15564 */
15565 /* port-A for surround (rear panel) */
15566 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15567 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15568 /* port-B for mic-in (rear panel) with vref */
15569 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15570 /* port-C for line-in (rear panel) */
15571 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15572 /* port-D for Front */
15573 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15574 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15575 /* port-E for HP out (front panel) */
15576 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15577 /* route front PCM to HP */
9dece1d7 15578 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15579 /* port-F for mic-in (front panel) with vref */
15580 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15581 /* port-G for CLFE (rear panel) */
15582 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15583 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15584 /* port-H for side (rear panel) */
15585 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15586 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15587 /* CD-in */
15588 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15589 /* route front mic to ADC1*/
15590 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15591 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15592
df694daa
KY
15593 /* Unmute DAC0~3 & spdif out*/
15594 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15595 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15596 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15597 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15598 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15599
df694daa
KY
15600 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15601 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15602 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15603 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15604 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15605
df694daa
KY
15606 /* Unmute Stereo Mixer 15 */
15607 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15608 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15611
15612 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15613 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15614 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15615 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15616 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15617 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15618 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15619 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15620 /* hp used DAC 3 (Front) */
15621 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15622 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15623
15624 { }
15625};
15626
15627static struct hda_verb alc861_threestack_init_verbs[] = {
15628 /*
15629 * Unmute ADC0 and set the default input to mic-in
15630 */
15631 /* port-A for surround (rear panel) */
15632 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15633 /* port-B for mic-in (rear panel) with vref */
15634 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15635 /* port-C for line-in (rear panel) */
15636 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15637 /* port-D for Front */
15638 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15639 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15640 /* port-E for HP out (front panel) */
15641 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15642 /* route front PCM to HP */
9dece1d7 15643 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15644 /* port-F for mic-in (front panel) with vref */
15645 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15646 /* port-G for CLFE (rear panel) */
15647 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15648 /* port-H for side (rear panel) */
15649 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15650 /* CD-in */
15651 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15652 /* route front mic to ADC1*/
15653 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15654 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15655 /* Unmute DAC0~3 & spdif out*/
15656 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15657 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15658 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15659 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15660 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15661
df694daa
KY
15662 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15663 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15664 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15665 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15666 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15667
df694daa
KY
15668 /* Unmute Stereo Mixer 15 */
15669 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15670 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15671 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15672 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15673
15674 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15675 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15676 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15677 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15678 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15679 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15680 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15681 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15682 /* hp used DAC 3 (Front) */
15683 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15684 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15685 { }
15686};
22309c3e
TI
15687
15688static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15689 /*
15690 * Unmute ADC0 and set the default input to mic-in
15691 */
15692 /* port-A for surround (rear panel) */
15693 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15694 /* port-B for mic-in (rear panel) with vref */
15695 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15696 /* port-C for line-in (rear panel) */
15697 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15698 /* port-D for Front */
15699 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15700 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15701 /* port-E for HP out (front panel) */
f12ab1e0
TI
15702 /* this has to be set to VREF80 */
15703 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15704 /* route front PCM to HP */
9dece1d7 15705 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15706 /* port-F for mic-in (front panel) with vref */
15707 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15708 /* port-G for CLFE (rear panel) */
15709 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15710 /* port-H for side (rear panel) */
15711 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15712 /* CD-in */
15713 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15714 /* route front mic to ADC1*/
15715 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15716 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15717 /* Unmute DAC0~3 & spdif out*/
15718 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15719 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15720 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15721 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15722 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15723
22309c3e
TI
15724 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15725 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15726 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15727 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15728 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15729
22309c3e
TI
15730 /* Unmute Stereo Mixer 15 */
15731 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15732 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15735
15736 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15737 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15738 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15739 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15740 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15741 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15742 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15743 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15744 /* hp used DAC 3 (Front) */
15745 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15746 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15747 { }
15748};
15749
7cdbff94
MD
15750static struct hda_verb alc861_asus_init_verbs[] = {
15751 /*
15752 * Unmute ADC0 and set the default input to mic-in
15753 */
f12ab1e0
TI
15754 /* port-A for surround (rear panel)
15755 * according to codec#0 this is the HP jack
15756 */
7cdbff94
MD
15757 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15758 /* route front PCM to HP */
15759 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15760 /* port-B for mic-in (rear panel) with vref */
15761 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15762 /* port-C for line-in (rear panel) */
15763 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15764 /* port-D for Front */
15765 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15766 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15767 /* port-E for HP out (front panel) */
f12ab1e0
TI
15768 /* this has to be set to VREF80 */
15769 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15770 /* route front PCM to HP */
9dece1d7 15771 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15772 /* port-F for mic-in (front panel) with vref */
15773 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15774 /* port-G for CLFE (rear panel) */
15775 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15776 /* port-H for side (rear panel) */
15777 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15778 /* CD-in */
15779 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15780 /* route front mic to ADC1*/
15781 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15782 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15783 /* Unmute DAC0~3 & spdif out*/
15784 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15785 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15786 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15787 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15788 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15789 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15790 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15791 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15792 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15793 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15794
7cdbff94
MD
15795 /* Unmute Stereo Mixer 15 */
15796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15797 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15799 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15800
15801 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15802 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15803 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15804 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15805 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15806 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15807 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15808 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15809 /* hp used DAC 3 (Front) */
15810 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15811 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15812 { }
15813};
15814
56bb0cab
TI
15815/* additional init verbs for ASUS laptops */
15816static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15817 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15818 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15819 { }
15820};
7cdbff94 15821
df694daa
KY
15822/*
15823 * generic initialization of ADC, input mixers and output mixers
15824 */
15825static struct hda_verb alc861_auto_init_verbs[] = {
15826 /*
15827 * Unmute ADC0 and set the default input to mic-in
15828 */
f12ab1e0 15829 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15830 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15831
df694daa
KY
15832 /* Unmute DAC0~3 & spdif out*/
15833 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15834 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15835 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15836 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15837 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15838
df694daa
KY
15839 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15840 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15841 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15842 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15843 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15844
df694daa
KY
15845 /* Unmute Stereo Mixer 15 */
15846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15847 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15849 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15850
1c20930a
TI
15851 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15852 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15853 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15854 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15855 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15856 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15857 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15858 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15859
15860 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15861 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15862 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15863 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15864 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15865 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15866 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15867 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15868
f12ab1e0 15869 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15870
15871 { }
15872};
15873
a53d1aec
TD
15874static struct hda_verb alc861_toshiba_init_verbs[] = {
15875 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15876
a53d1aec
TD
15877 { }
15878};
15879
15880/* toggle speaker-output according to the hp-jack state */
15881static void alc861_toshiba_automute(struct hda_codec *codec)
15882{
864f92be 15883 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15884
47fd830a
TI
15885 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15886 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15887 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15888 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15889}
15890
15891static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15892 unsigned int res)
15893{
a53d1aec
TD
15894 if ((res >> 26) == ALC880_HP_EVENT)
15895 alc861_toshiba_automute(codec);
15896}
15897
def319f9 15898/* pcm configuration: identical with ALC880 */
df694daa
KY
15899#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15900#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15901#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15902#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15903
15904
15905#define ALC861_DIGOUT_NID 0x07
15906
15907static struct hda_channel_mode alc861_8ch_modes[1] = {
15908 { 8, NULL }
15909};
15910
15911static hda_nid_t alc861_dac_nids[4] = {
15912 /* front, surround, clfe, side */
15913 0x03, 0x06, 0x05, 0x04
15914};
15915
9c7f852e
TI
15916static hda_nid_t alc660_dac_nids[3] = {
15917 /* front, clfe, surround */
15918 0x03, 0x05, 0x06
15919};
15920
df694daa
KY
15921static hda_nid_t alc861_adc_nids[1] = {
15922 /* ADC0-2 */
15923 0x08,
15924};
15925
15926static struct hda_input_mux alc861_capture_source = {
15927 .num_items = 5,
15928 .items = {
15929 { "Mic", 0x0 },
15930 { "Front Mic", 0x3 },
15931 { "Line", 0x1 },
15932 { "CD", 0x4 },
15933 { "Mixer", 0x5 },
15934 },
15935};
15936
1c20930a
TI
15937static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15938{
15939 struct alc_spec *spec = codec->spec;
15940 hda_nid_t mix, srcs[5];
15941 int i, j, num;
15942
15943 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15944 return 0;
15945 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15946 if (num < 0)
15947 return 0;
15948 for (i = 0; i < num; i++) {
15949 unsigned int type;
a22d543a 15950 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15951 if (type != AC_WID_AUD_OUT)
15952 continue;
15953 for (j = 0; j < spec->multiout.num_dacs; j++)
15954 if (spec->multiout.dac_nids[j] == srcs[i])
15955 break;
15956 if (j >= spec->multiout.num_dacs)
15957 return srcs[i];
15958 }
15959 return 0;
15960}
15961
df694daa 15962/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15963static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15964 const struct auto_pin_cfg *cfg)
df694daa 15965{
1c20930a 15966 struct alc_spec *spec = codec->spec;
df694daa 15967 int i;
1c20930a 15968 hda_nid_t nid, dac;
df694daa
KY
15969
15970 spec->multiout.dac_nids = spec->private_dac_nids;
15971 for (i = 0; i < cfg->line_outs; i++) {
15972 nid = cfg->line_out_pins[i];
1c20930a
TI
15973 dac = alc861_look_for_dac(codec, nid);
15974 if (!dac)
15975 continue;
15976 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15977 }
df694daa
KY
15978 return 0;
15979}
15980
bcb2f0f5
TI
15981static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15982 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15983{
bcb2f0f5 15984 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15985 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15986}
15987
bcb2f0f5
TI
15988#define alc861_create_out_sw(codec, pfx, nid, chs) \
15989 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15990
df694daa 15991/* add playback controls from the parsed DAC table */
1c20930a 15992static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15993 const struct auto_pin_cfg *cfg)
15994{
1c20930a 15995 struct alc_spec *spec = codec->spec;
ea734963 15996 static const char * const chname[4] = {
f12ab1e0
TI
15997 "Front", "Surround", NULL /*CLFE*/, "Side"
15998 };
bcb2f0f5 15999 const char *pfx = alc_get_line_out_pfx(cfg, true);
df694daa 16000 hda_nid_t nid;
1c20930a
TI
16001 int i, err;
16002
df694daa
KY
16003 for (i = 0; i < cfg->line_outs; i++) {
16004 nid = spec->multiout.dac_nids[i];
f12ab1e0 16005 if (!nid)
df694daa 16006 continue;
bcb2f0f5 16007 if (!pfx && i == 2) {
df694daa 16008 /* Center/LFE */
1c20930a 16009 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 16010 if (err < 0)
df694daa 16011 return err;
1c20930a 16012 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 16013 if (err < 0)
df694daa
KY
16014 return err;
16015 } else {
bcb2f0f5
TI
16016 const char *name = pfx;
16017 if (!name)
16018 name = chname[i];
16019 err = __alc861_create_out_sw(codec, name, nid, i, 3);
f12ab1e0 16020 if (err < 0)
df694daa
KY
16021 return err;
16022 }
16023 }
16024 return 0;
16025}
16026
1c20930a 16027static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16028{
1c20930a 16029 struct alc_spec *spec = codec->spec;
df694daa
KY
16030 int err;
16031 hda_nid_t nid;
16032
f12ab1e0 16033 if (!pin)
df694daa
KY
16034 return 0;
16035
16036 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16037 nid = alc861_look_for_dac(codec, pin);
16038 if (nid) {
16039 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16040 if (err < 0)
16041 return err;
16042 spec->multiout.hp_nid = nid;
16043 }
df694daa
KY
16044 }
16045 return 0;
16046}
16047
16048/* create playback/capture controls for input pins */
05f5f477 16049static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16050 const struct auto_pin_cfg *cfg)
df694daa 16051{
05f5f477 16052 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16053}
16054
f12ab1e0
TI
16055static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16056 hda_nid_t nid,
1c20930a 16057 int pin_type, hda_nid_t dac)
df694daa 16058{
1c20930a
TI
16059 hda_nid_t mix, srcs[5];
16060 int i, num;
16061
564c5bea
JL
16062 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16063 pin_type);
1c20930a 16064 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16065 AMP_OUT_UNMUTE);
1c20930a
TI
16066 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16067 return;
16068 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16069 if (num < 0)
16070 return;
16071 for (i = 0; i < num; i++) {
16072 unsigned int mute;
16073 if (srcs[i] == dac || srcs[i] == 0x15)
16074 mute = AMP_IN_UNMUTE(i);
16075 else
16076 mute = AMP_IN_MUTE(i);
16077 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16078 mute);
16079 }
df694daa
KY
16080}
16081
16082static void alc861_auto_init_multi_out(struct hda_codec *codec)
16083{
16084 struct alc_spec *spec = codec->spec;
16085 int i;
16086
16087 for (i = 0; i < spec->autocfg.line_outs; i++) {
16088 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16089 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16090 if (nid)
baba8ee9 16091 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16092 spec->multiout.dac_nids[i]);
df694daa
KY
16093 }
16094}
16095
16096static void alc861_auto_init_hp_out(struct hda_codec *codec)
16097{
16098 struct alc_spec *spec = codec->spec;
df694daa 16099
15870f05
TI
16100 if (spec->autocfg.hp_outs)
16101 alc861_auto_set_output_and_unmute(codec,
16102 spec->autocfg.hp_pins[0],
16103 PIN_HP,
1c20930a 16104 spec->multiout.hp_nid);
15870f05
TI
16105 if (spec->autocfg.speaker_outs)
16106 alc861_auto_set_output_and_unmute(codec,
16107 spec->autocfg.speaker_pins[0],
16108 PIN_OUT,
1c20930a 16109 spec->multiout.dac_nids[0]);
df694daa
KY
16110}
16111
16112static void alc861_auto_init_analog_input(struct hda_codec *codec)
16113{
16114 struct alc_spec *spec = codec->spec;
66ceeb6b 16115 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16116 int i;
16117
66ceeb6b
TI
16118 for (i = 0; i < cfg->num_inputs; i++) {
16119 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16120 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16121 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16122 }
16123}
16124
16125/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16126/* return 1 if successful, 0 if the proper config is not found,
16127 * or a negative error code
16128 */
df694daa
KY
16129static int alc861_parse_auto_config(struct hda_codec *codec)
16130{
16131 struct alc_spec *spec = codec->spec;
16132 int err;
16133 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16134
f12ab1e0
TI
16135 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16136 alc861_ignore);
16137 if (err < 0)
df694daa 16138 return err;
f12ab1e0 16139 if (!spec->autocfg.line_outs)
df694daa
KY
16140 return 0; /* can't find valid BIOS pin config */
16141
1c20930a 16142 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
16143 if (err < 0)
16144 return err;
1c20930a 16145 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16146 if (err < 0)
16147 return err;
1c20930a 16148 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16149 if (err < 0)
16150 return err;
05f5f477 16151 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16152 if (err < 0)
df694daa
KY
16153 return err;
16154
16155 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16156
757899ac 16157 alc_auto_parse_digital(codec);
df694daa 16158
603c4019 16159 if (spec->kctls.list)
d88897ea 16160 add_mixer(spec, spec->kctls.list);
df694daa 16161
d88897ea 16162 add_verb(spec, alc861_auto_init_verbs);
df694daa 16163
a1e8d2da 16164 spec->num_mux_defs = 1;
61b9b9b1 16165 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16166
16167 spec->adc_nids = alc861_adc_nids;
16168 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16169 set_capture_mixer(codec);
df694daa 16170
6227cdce 16171 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16172
df694daa
KY
16173 return 1;
16174}
16175
ae6b813a
TI
16176/* additional initialization for auto-configuration model */
16177static void alc861_auto_init(struct hda_codec *codec)
df694daa 16178{
f6c7e546 16179 struct alc_spec *spec = codec->spec;
df694daa
KY
16180 alc861_auto_init_multi_out(codec);
16181 alc861_auto_init_hp_out(codec);
16182 alc861_auto_init_analog_input(codec);
757899ac 16183 alc_auto_init_digital(codec);
f6c7e546 16184 if (spec->unsol_event)
7fb0d78f 16185 alc_inithook(codec);
df694daa
KY
16186}
16187
cb53c626
TI
16188#ifdef CONFIG_SND_HDA_POWER_SAVE
16189static struct hda_amp_list alc861_loopbacks[] = {
16190 { 0x15, HDA_INPUT, 0 },
16191 { 0x15, HDA_INPUT, 1 },
16192 { 0x15, HDA_INPUT, 2 },
16193 { 0x15, HDA_INPUT, 3 },
16194 { } /* end */
16195};
16196#endif
16197
df694daa
KY
16198
16199/*
16200 * configuration and preset
16201 */
ea734963 16202static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16203 [ALC861_3ST] = "3stack",
16204 [ALC660_3ST] = "3stack-660",
16205 [ALC861_3ST_DIG] = "3stack-dig",
16206 [ALC861_6ST_DIG] = "6stack-dig",
16207 [ALC861_UNIWILL_M31] = "uniwill-m31",
16208 [ALC861_TOSHIBA] = "toshiba",
16209 [ALC861_ASUS] = "asus",
16210 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16211 [ALC861_AUTO] = "auto",
16212};
16213
16214static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16215 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16216 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16217 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16218 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16219 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16220 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16221 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16222 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16223 * Any other models that need this preset?
16224 */
16225 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16226 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16227 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16228 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16229 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16230 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16231 /* FIXME: the below seems conflict */
16232 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16233 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16234 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16235 {}
16236};
16237
16238static struct alc_config_preset alc861_presets[] = {
16239 [ALC861_3ST] = {
16240 .mixers = { alc861_3ST_mixer },
16241 .init_verbs = { alc861_threestack_init_verbs },
16242 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16243 .dac_nids = alc861_dac_nids,
16244 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16245 .channel_mode = alc861_threestack_modes,
4e195a7b 16246 .need_dac_fix = 1,
df694daa
KY
16247 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16248 .adc_nids = alc861_adc_nids,
16249 .input_mux = &alc861_capture_source,
16250 },
16251 [ALC861_3ST_DIG] = {
16252 .mixers = { alc861_base_mixer },
16253 .init_verbs = { alc861_threestack_init_verbs },
16254 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16255 .dac_nids = alc861_dac_nids,
16256 .dig_out_nid = ALC861_DIGOUT_NID,
16257 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16258 .channel_mode = alc861_threestack_modes,
4e195a7b 16259 .need_dac_fix = 1,
df694daa
KY
16260 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16261 .adc_nids = alc861_adc_nids,
16262 .input_mux = &alc861_capture_source,
16263 },
16264 [ALC861_6ST_DIG] = {
16265 .mixers = { alc861_base_mixer },
16266 .init_verbs = { alc861_base_init_verbs },
16267 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16268 .dac_nids = alc861_dac_nids,
16269 .dig_out_nid = ALC861_DIGOUT_NID,
16270 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16271 .channel_mode = alc861_8ch_modes,
16272 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16273 .adc_nids = alc861_adc_nids,
16274 .input_mux = &alc861_capture_source,
16275 },
9c7f852e
TI
16276 [ALC660_3ST] = {
16277 .mixers = { alc861_3ST_mixer },
16278 .init_verbs = { alc861_threestack_init_verbs },
16279 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16280 .dac_nids = alc660_dac_nids,
16281 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16282 .channel_mode = alc861_threestack_modes,
4e195a7b 16283 .need_dac_fix = 1,
9c7f852e
TI
16284 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16285 .adc_nids = alc861_adc_nids,
16286 .input_mux = &alc861_capture_source,
16287 },
22309c3e
TI
16288 [ALC861_UNIWILL_M31] = {
16289 .mixers = { alc861_uniwill_m31_mixer },
16290 .init_verbs = { alc861_uniwill_m31_init_verbs },
16291 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16292 .dac_nids = alc861_dac_nids,
16293 .dig_out_nid = ALC861_DIGOUT_NID,
16294 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16295 .channel_mode = alc861_uniwill_m31_modes,
16296 .need_dac_fix = 1,
16297 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16298 .adc_nids = alc861_adc_nids,
16299 .input_mux = &alc861_capture_source,
16300 },
a53d1aec
TD
16301 [ALC861_TOSHIBA] = {
16302 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16303 .init_verbs = { alc861_base_init_verbs,
16304 alc861_toshiba_init_verbs },
a53d1aec
TD
16305 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16306 .dac_nids = alc861_dac_nids,
16307 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16308 .channel_mode = alc883_3ST_2ch_modes,
16309 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16310 .adc_nids = alc861_adc_nids,
16311 .input_mux = &alc861_capture_source,
16312 .unsol_event = alc861_toshiba_unsol_event,
16313 .init_hook = alc861_toshiba_automute,
16314 },
7cdbff94
MD
16315 [ALC861_ASUS] = {
16316 .mixers = { alc861_asus_mixer },
16317 .init_verbs = { alc861_asus_init_verbs },
16318 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16319 .dac_nids = alc861_dac_nids,
16320 .dig_out_nid = ALC861_DIGOUT_NID,
16321 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16322 .channel_mode = alc861_asus_modes,
16323 .need_dac_fix = 1,
16324 .hp_nid = 0x06,
16325 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16326 .adc_nids = alc861_adc_nids,
16327 .input_mux = &alc861_capture_source,
16328 },
56bb0cab
TI
16329 [ALC861_ASUS_LAPTOP] = {
16330 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16331 .init_verbs = { alc861_asus_init_verbs,
16332 alc861_asus_laptop_init_verbs },
16333 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16334 .dac_nids = alc861_dac_nids,
16335 .dig_out_nid = ALC861_DIGOUT_NID,
16336 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16337 .channel_mode = alc883_3ST_2ch_modes,
16338 .need_dac_fix = 1,
16339 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16340 .adc_nids = alc861_adc_nids,
16341 .input_mux = &alc861_capture_source,
16342 },
16343};
df694daa 16344
cfc9b06f
TI
16345/* Pin config fixes */
16346enum {
16347 PINFIX_FSC_AMILO_PI1505,
16348};
16349
cfc9b06f
TI
16350static const struct alc_fixup alc861_fixups[] = {
16351 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16352 .type = ALC_FIXUP_PINS,
16353 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16354 { 0x0b, 0x0221101f }, /* HP */
16355 { 0x0f, 0x90170310 }, /* speaker */
16356 { }
16357 }
cfc9b06f
TI
16358 },
16359};
16360
16361static struct snd_pci_quirk alc861_fixup_tbl[] = {
16362 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16363 {}
16364};
df694daa
KY
16365
16366static int patch_alc861(struct hda_codec *codec)
16367{
16368 struct alc_spec *spec;
16369 int board_config;
16370 int err;
16371
dc041e0b 16372 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16373 if (spec == NULL)
16374 return -ENOMEM;
16375
f12ab1e0 16376 codec->spec = spec;
df694daa 16377
f5fcc13c
TI
16378 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16379 alc861_models,
16380 alc861_cfg_tbl);
9c7f852e 16381
f5fcc13c 16382 if (board_config < 0) {
9a11f1aa
TI
16383 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16384 codec->chip_name);
df694daa
KY
16385 board_config = ALC861_AUTO;
16386 }
16387
b5bfbc67
TI
16388 if (board_config == ALC861_AUTO) {
16389 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16390 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16391 }
cfc9b06f 16392
df694daa
KY
16393 if (board_config == ALC861_AUTO) {
16394 /* automatic parse from the BIOS config */
16395 err = alc861_parse_auto_config(codec);
16396 if (err < 0) {
16397 alc_free(codec);
16398 return err;
f12ab1e0 16399 } else if (!err) {
9c7f852e
TI
16400 printk(KERN_INFO
16401 "hda_codec: Cannot set up configuration "
16402 "from BIOS. Using base mode...\n");
df694daa
KY
16403 board_config = ALC861_3ST_DIG;
16404 }
16405 }
16406
680cd536
KK
16407 err = snd_hda_attach_beep_device(codec, 0x23);
16408 if (err < 0) {
16409 alc_free(codec);
16410 return err;
16411 }
16412
df694daa 16413 if (board_config != ALC861_AUTO)
e9c364c0 16414 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16415
df694daa
KY
16416 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16417 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16418
df694daa
KY
16419 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16420 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16421
c7a8eb10
TI
16422 if (!spec->cap_mixer)
16423 set_capture_mixer(codec);
45bdd1c1
TI
16424 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16425
2134ea4f
TI
16426 spec->vmaster_nid = 0x03;
16427
b5bfbc67 16428 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16429
df694daa 16430 codec->patch_ops = alc_patch_ops;
c97259df 16431 if (board_config == ALC861_AUTO) {
ae6b813a 16432 spec->init_hook = alc861_auto_init;
c97259df
DC
16433#ifdef CONFIG_SND_HDA_POWER_SAVE
16434 spec->power_hook = alc_power_eapd;
16435#endif
16436 }
cb53c626
TI
16437#ifdef CONFIG_SND_HDA_POWER_SAVE
16438 if (!spec->loopback.amplist)
16439 spec->loopback.amplist = alc861_loopbacks;
16440#endif
ea1fb29a 16441
1da177e4
LT
16442 return 0;
16443}
16444
f32610ed
JS
16445/*
16446 * ALC861-VD support
16447 *
16448 * Based on ALC882
16449 *
16450 * In addition, an independent DAC
16451 */
16452#define ALC861VD_DIGOUT_NID 0x06
16453
16454static hda_nid_t alc861vd_dac_nids[4] = {
16455 /* front, surr, clfe, side surr */
16456 0x02, 0x03, 0x04, 0x05
16457};
16458
16459/* dac_nids for ALC660vd are in a different order - according to
16460 * Realtek's driver.
def319f9 16461 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16462 * of ALC660vd codecs, but for now there is only 3stack mixer
16463 * - and it is the same as in 861vd.
16464 * adc_nids in ALC660vd are (is) the same as in 861vd
16465 */
16466static hda_nid_t alc660vd_dac_nids[3] = {
16467 /* front, rear, clfe, rear_surr */
16468 0x02, 0x04, 0x03
16469};
16470
16471static hda_nid_t alc861vd_adc_nids[1] = {
16472 /* ADC0 */
16473 0x09,
16474};
16475
e1406348
TI
16476static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16477
f32610ed
JS
16478/* input MUX */
16479/* FIXME: should be a matrix-type input source selection */
16480static struct hda_input_mux alc861vd_capture_source = {
16481 .num_items = 4,
16482 .items = {
16483 { "Mic", 0x0 },
16484 { "Front Mic", 0x1 },
16485 { "Line", 0x2 },
16486 { "CD", 0x4 },
16487 },
16488};
16489
272a527c 16490static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16491 .num_items = 2,
272a527c 16492 .items = {
8607f7c4 16493 { "Mic", 0x0 },
28c4edb7 16494 { "Internal Mic", 0x1 },
272a527c
KY
16495 },
16496};
16497
d1a991a6
KY
16498static struct hda_input_mux alc861vd_hp_capture_source = {
16499 .num_items = 2,
16500 .items = {
16501 { "Front Mic", 0x0 },
16502 { "ATAPI Mic", 0x1 },
16503 },
16504};
16505
f32610ed
JS
16506/*
16507 * 2ch mode
16508 */
16509static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16510 { 2, NULL }
16511};
16512
16513/*
16514 * 6ch mode
16515 */
16516static struct hda_verb alc861vd_6stack_ch6_init[] = {
16517 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16518 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16519 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16520 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16521 { } /* end */
16522};
16523
16524/*
16525 * 8ch mode
16526 */
16527static struct hda_verb alc861vd_6stack_ch8_init[] = {
16528 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16529 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16530 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16531 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16532 { } /* end */
16533};
16534
16535static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16536 { 6, alc861vd_6stack_ch6_init },
16537 { 8, alc861vd_6stack_ch8_init },
16538};
16539
16540static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16541 {
16542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16543 .name = "Channel Mode",
16544 .info = alc_ch_mode_info,
16545 .get = alc_ch_mode_get,
16546 .put = alc_ch_mode_put,
16547 },
16548 { } /* end */
16549};
16550
f32610ed
JS
16551/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16552 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16553 */
16554static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16555 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16556 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16557
16558 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16559 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16560
16561 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16562 HDA_OUTPUT),
16563 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16564 HDA_OUTPUT),
16565 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16566 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16567
16568 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16569 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16570
16571 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16572
5f99f86a 16573 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16575 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16576
5f99f86a 16577 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16578 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16579 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16580
16581 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16582 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16583
16584 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16585 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16586
f32610ed
JS
16587 { } /* end */
16588};
16589
16590static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16591 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16592 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16593
16594 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16595
5f99f86a 16596 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16597 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16598 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16599
5f99f86a 16600 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16601 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16602 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16603
16604 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16605 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16606
16607 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16608 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16609
f32610ed
JS
16610 { } /* end */
16611};
16612
bdd148a3
KY
16613static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16614 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16615 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16616 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16617
16618 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16619
5f99f86a 16620 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16622 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16623
5f99f86a 16624 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16625 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16626 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16627
16628 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16629 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16630
16631 { } /* end */
16632};
16633
b419f346 16634/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16635 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16636 */
16637static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16638 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16639 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16640 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16641 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16642 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16643 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16644 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16645 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16646 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16647 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16648 { } /* end */
16649};
16650
d1a991a6
KY
16651/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16652 * Front Mic=0x18, ATAPI Mic = 0x19,
16653 */
16654static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16655 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16656 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16657 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16658 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16659 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16660 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16661 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16662 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16663
d1a991a6
KY
16664 { } /* end */
16665};
16666
f32610ed
JS
16667/*
16668 * generic initialization of ADC, input mixers and output mixers
16669 */
16670static struct hda_verb alc861vd_volume_init_verbs[] = {
16671 /*
16672 * Unmute ADC0 and set the default input to mic-in
16673 */
16674 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16675 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16676
16677 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16678 * the analog-loopback mixer widget
16679 */
16680 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16681 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16682 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16683 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16684 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16686
16687 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16688 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16689 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16690 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16691 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16692
16693 /*
16694 * Set up output mixers (0x02 - 0x05)
16695 */
16696 /* set vol=0 to output mixers */
16697 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16698 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16699 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16700 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16701
16702 /* set up input amps for analog loopback */
16703 /* Amp Indices: DAC = 0, mixer = 1 */
16704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16706 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16707 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16708 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16709 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16710 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16711 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16712
16713 { }
16714};
16715
16716/*
16717 * 3-stack pin configuration:
16718 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16719 */
16720static struct hda_verb alc861vd_3stack_init_verbs[] = {
16721 /*
16722 * Set pin mode and muting
16723 */
16724 /* set front pin widgets 0x14 for output */
16725 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16726 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16727 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16728
16729 /* Mic (rear) pin: input vref at 80% */
16730 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16731 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16732 /* Front Mic pin: input vref at 80% */
16733 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16734 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16735 /* Line In pin: input */
16736 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16737 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16738 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16739 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16740 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16741 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16742 /* CD pin widget for input */
16743 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16744
16745 { }
16746};
16747
16748/*
16749 * 6-stack pin configuration:
16750 */
16751static struct hda_verb alc861vd_6stack_init_verbs[] = {
16752 /*
16753 * Set pin mode and muting
16754 */
16755 /* set front pin widgets 0x14 for output */
16756 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16757 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16758 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16759
16760 /* Rear Pin: output 1 (0x0d) */
16761 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16763 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16764 /* CLFE Pin: output 2 (0x0e) */
16765 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16766 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16767 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16768 /* Side Pin: output 3 (0x0f) */
16769 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16770 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16771 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16772
16773 /* Mic (rear) pin: input vref at 80% */
16774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16775 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16776 /* Front Mic pin: input vref at 80% */
16777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16779 /* Line In pin: input */
16780 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16781 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16782 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16783 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16784 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16785 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16786 /* CD pin widget for input */
16787 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16788
16789 { }
16790};
16791
bdd148a3
KY
16792static struct hda_verb alc861vd_eapd_verbs[] = {
16793 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16794 { }
16795};
16796
f9423e7a
KY
16797static struct hda_verb alc660vd_eapd_verbs[] = {
16798 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16799 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16800 { }
16801};
16802
bdd148a3
KY
16803static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16804 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16806 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16807 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16808 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16809 {}
16810};
16811
4f5d1706 16812static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16813{
a9fd4f3f 16814 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16815 spec->autocfg.hp_pins[0] = 0x1b;
16816 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16817}
16818
16819static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16820{
a9fd4f3f 16821 alc_automute_amp(codec);
eeb43387 16822 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16823}
16824
16825static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16826 unsigned int res)
16827{
16828 switch (res >> 26) {
bdd148a3 16829 case ALC880_MIC_EVENT:
eeb43387 16830 alc88x_simple_mic_automute(codec);
bdd148a3 16831 break;
a9fd4f3f
TI
16832 default:
16833 alc_automute_amp_unsol_event(codec, res);
16834 break;
bdd148a3
KY
16835 }
16836}
16837
272a527c
KY
16838static struct hda_verb alc861vd_dallas_verbs[] = {
16839 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16840 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16841 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16842 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16843
16844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16846 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16847 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16848 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16849 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16850 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16851 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16852
272a527c
KY
16853 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16854 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16855 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16857 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16858 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16859 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16860 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16861
16862 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16863 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16865 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16866 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16867 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16868 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16869 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16870
16871 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16872 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16873 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16875
16876 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16877 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16878 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16879
16880 { } /* end */
16881};
16882
16883/* toggle speaker-output according to the hp-jack state */
4f5d1706 16884static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16885{
a9fd4f3f 16886 struct alc_spec *spec = codec->spec;
272a527c 16887
a9fd4f3f
TI
16888 spec->autocfg.hp_pins[0] = 0x15;
16889 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16890}
16891
cb53c626
TI
16892#ifdef CONFIG_SND_HDA_POWER_SAVE
16893#define alc861vd_loopbacks alc880_loopbacks
16894#endif
16895
def319f9 16896/* pcm configuration: identical with ALC880 */
f32610ed
JS
16897#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16898#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16899#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16900#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16901
16902/*
16903 * configuration and preset
16904 */
ea734963 16905static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16906 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16907 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16908 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16909 [ALC861VD_3ST] = "3stack",
16910 [ALC861VD_3ST_DIG] = "3stack-digout",
16911 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16912 [ALC861VD_LENOVO] = "lenovo",
272a527c 16913 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16914 [ALC861VD_HP] = "hp",
f32610ed
JS
16915 [ALC861VD_AUTO] = "auto",
16916};
16917
16918static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16919 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16920 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16921 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16922 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16923 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16924 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16925 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16926 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16927 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16928 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16929 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16930 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16931 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16932 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16933 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16934 {}
16935};
16936
16937static struct alc_config_preset alc861vd_presets[] = {
16938 [ALC660VD_3ST] = {
16939 .mixers = { alc861vd_3st_mixer },
16940 .init_verbs = { alc861vd_volume_init_verbs,
16941 alc861vd_3stack_init_verbs },
16942 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16943 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16944 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16945 .channel_mode = alc861vd_3stack_2ch_modes,
16946 .input_mux = &alc861vd_capture_source,
16947 },
6963f84c
MC
16948 [ALC660VD_3ST_DIG] = {
16949 .mixers = { alc861vd_3st_mixer },
16950 .init_verbs = { alc861vd_volume_init_verbs,
16951 alc861vd_3stack_init_verbs },
16952 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16953 .dac_nids = alc660vd_dac_nids,
16954 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16955 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16956 .channel_mode = alc861vd_3stack_2ch_modes,
16957 .input_mux = &alc861vd_capture_source,
16958 },
f32610ed
JS
16959 [ALC861VD_3ST] = {
16960 .mixers = { alc861vd_3st_mixer },
16961 .init_verbs = { alc861vd_volume_init_verbs,
16962 alc861vd_3stack_init_verbs },
16963 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16964 .dac_nids = alc861vd_dac_nids,
16965 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16966 .channel_mode = alc861vd_3stack_2ch_modes,
16967 .input_mux = &alc861vd_capture_source,
16968 },
16969 [ALC861VD_3ST_DIG] = {
16970 .mixers = { alc861vd_3st_mixer },
16971 .init_verbs = { alc861vd_volume_init_verbs,
16972 alc861vd_3stack_init_verbs },
16973 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16974 .dac_nids = alc861vd_dac_nids,
16975 .dig_out_nid = ALC861VD_DIGOUT_NID,
16976 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16977 .channel_mode = alc861vd_3stack_2ch_modes,
16978 .input_mux = &alc861vd_capture_source,
16979 },
16980 [ALC861VD_6ST_DIG] = {
16981 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16982 .init_verbs = { alc861vd_volume_init_verbs,
16983 alc861vd_6stack_init_verbs },
16984 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16985 .dac_nids = alc861vd_dac_nids,
16986 .dig_out_nid = ALC861VD_DIGOUT_NID,
16987 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16988 .channel_mode = alc861vd_6stack_modes,
16989 .input_mux = &alc861vd_capture_source,
16990 },
bdd148a3
KY
16991 [ALC861VD_LENOVO] = {
16992 .mixers = { alc861vd_lenovo_mixer },
16993 .init_verbs = { alc861vd_volume_init_verbs,
16994 alc861vd_3stack_init_verbs,
16995 alc861vd_eapd_verbs,
16996 alc861vd_lenovo_unsol_verbs },
16997 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16998 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16999 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17000 .channel_mode = alc861vd_3stack_2ch_modes,
17001 .input_mux = &alc861vd_capture_source,
17002 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17003 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17004 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 17005 },
272a527c
KY
17006 [ALC861VD_DALLAS] = {
17007 .mixers = { alc861vd_dallas_mixer },
17008 .init_verbs = { alc861vd_dallas_verbs },
17009 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17010 .dac_nids = alc861vd_dac_nids,
272a527c
KY
17011 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17012 .channel_mode = alc861vd_3stack_2ch_modes,
17013 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 17014 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
17015 .setup = alc861vd_dallas_setup,
17016 .init_hook = alc_automute_amp,
d1a991a6
KY
17017 },
17018 [ALC861VD_HP] = {
17019 .mixers = { alc861vd_hp_mixer },
17020 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17021 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17022 .dac_nids = alc861vd_dac_nids,
d1a991a6 17023 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17024 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17025 .channel_mode = alc861vd_3stack_2ch_modes,
17026 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 17027 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
17028 .setup = alc861vd_dallas_setup,
17029 .init_hook = alc_automute_amp,
ea1fb29a 17030 },
13c94744
TI
17031 [ALC660VD_ASUS_V1S] = {
17032 .mixers = { alc861vd_lenovo_mixer },
17033 .init_verbs = { alc861vd_volume_init_verbs,
17034 alc861vd_3stack_init_verbs,
17035 alc861vd_eapd_verbs,
17036 alc861vd_lenovo_unsol_verbs },
17037 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17038 .dac_nids = alc660vd_dac_nids,
17039 .dig_out_nid = ALC861VD_DIGOUT_NID,
17040 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17041 .channel_mode = alc861vd_3stack_2ch_modes,
17042 .input_mux = &alc861vd_capture_source,
17043 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17044 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17045 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17046 },
f32610ed
JS
17047};
17048
17049/*
17050 * BIOS auto configuration
17051 */
05f5f477
TI
17052static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17053 const struct auto_pin_cfg *cfg)
17054{
7167594a 17055 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17056}
17057
17058
f32610ed
JS
17059static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17060 hda_nid_t nid, int pin_type, int dac_idx)
17061{
f6c7e546 17062 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17063}
17064
17065static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17066{
17067 struct alc_spec *spec = codec->spec;
17068 int i;
17069
17070 for (i = 0; i <= HDA_SIDE; i++) {
17071 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17072 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17073 if (nid)
17074 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17075 pin_type, i);
f32610ed
JS
17076 }
17077}
17078
17079
17080static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17081{
17082 struct alc_spec *spec = codec->spec;
17083 hda_nid_t pin;
17084
17085 pin = spec->autocfg.hp_pins[0];
def319f9 17086 if (pin) /* connect to front and use dac 0 */
f32610ed 17087 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17088 pin = spec->autocfg.speaker_pins[0];
17089 if (pin)
17090 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17091}
17092
f32610ed
JS
17093#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17094
17095static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17096{
17097 struct alc_spec *spec = codec->spec;
66ceeb6b 17098 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17099 int i;
17100
66ceeb6b
TI
17101 for (i = 0; i < cfg->num_inputs; i++) {
17102 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17103 if (alc_is_input_pin(codec, nid)) {
30ea098f 17104 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17105 if (nid != ALC861VD_PIN_CD_NID &&
17106 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17107 snd_hda_codec_write(codec, nid, 0,
17108 AC_VERB_SET_AMP_GAIN_MUTE,
17109 AMP_OUT_MUTE);
17110 }
17111 }
17112}
17113
f511b01c
TI
17114#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17115
f32610ed
JS
17116#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17117#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17118
17119/* add playback controls from the parsed DAC table */
569ed348 17120/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17121 * different NIDs for mute/unmute switch and volume control */
17122static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17123 const struct auto_pin_cfg *cfg)
17124{
ea734963
TI
17125 static const char * const chname[4] = {
17126 "Front", "Surround", "CLFE", "Side"
17127 };
bcb2f0f5 17128 const char *pfx = alc_get_line_out_pfx(cfg, true);
f32610ed
JS
17129 hda_nid_t nid_v, nid_s;
17130 int i, err;
17131
17132 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 17133 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17134 continue;
17135 nid_v = alc861vd_idx_to_mixer_vol(
17136 alc880_dac_to_idx(
17137 spec->multiout.dac_nids[i]));
17138 nid_s = alc861vd_idx_to_mixer_switch(
17139 alc880_dac_to_idx(
17140 spec->multiout.dac_nids[i]));
17141
bcb2f0f5 17142 if (!pfx && i == 2) {
f32610ed 17143 /* Center/LFE */
0afe5f89
TI
17144 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17145 "Center",
f12ab1e0
TI
17146 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17147 HDA_OUTPUT));
17148 if (err < 0)
f32610ed 17149 return err;
0afe5f89
TI
17150 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17151 "LFE",
f12ab1e0
TI
17152 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17153 HDA_OUTPUT));
17154 if (err < 0)
f32610ed 17155 return err;
0afe5f89
TI
17156 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17157 "Center",
f12ab1e0
TI
17158 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17159 HDA_INPUT));
17160 if (err < 0)
f32610ed 17161 return err;
0afe5f89
TI
17162 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17163 "LFE",
f12ab1e0
TI
17164 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17165 HDA_INPUT));
17166 if (err < 0)
f32610ed
JS
17167 return err;
17168 } else {
bcb2f0f5
TI
17169 const char *name = pfx;
17170 if (!name)
17171 name = chname[i];
17172 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17173 name, i,
f12ab1e0
TI
17174 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17175 HDA_OUTPUT));
17176 if (err < 0)
f32610ed 17177 return err;
bcb2f0f5
TI
17178 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17179 name, i,
bdd148a3 17180 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17181 HDA_INPUT));
17182 if (err < 0)
f32610ed
JS
17183 return err;
17184 }
17185 }
17186 return 0;
17187}
17188
17189/* add playback controls for speaker and HP outputs */
17190/* Based on ALC880 version. But ALC861VD has separate,
17191 * different NIDs for mute/unmute switch and volume control */
17192static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17193 hda_nid_t pin, const char *pfx)
17194{
17195 hda_nid_t nid_v, nid_s;
17196 int err;
f32610ed 17197
f12ab1e0 17198 if (!pin)
f32610ed
JS
17199 return 0;
17200
17201 if (alc880_is_fixed_pin(pin)) {
17202 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17203 /* specify the DAC as the extra output */
f12ab1e0 17204 if (!spec->multiout.hp_nid)
f32610ed
JS
17205 spec->multiout.hp_nid = nid_v;
17206 else
17207 spec->multiout.extra_out_nid[0] = nid_v;
17208 /* control HP volume/switch on the output mixer amp */
17209 nid_v = alc861vd_idx_to_mixer_vol(
17210 alc880_fixed_pin_idx(pin));
17211 nid_s = alc861vd_idx_to_mixer_switch(
17212 alc880_fixed_pin_idx(pin));
17213
0afe5f89 17214 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17215 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17216 if (err < 0)
f32610ed 17217 return err;
0afe5f89 17218 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17219 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17220 if (err < 0)
f32610ed
JS
17221 return err;
17222 } else if (alc880_is_multi_pin(pin)) {
17223 /* set manual connection */
17224 /* we have only a switch on HP-out PIN */
0afe5f89 17225 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17226 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17227 if (err < 0)
f32610ed
JS
17228 return err;
17229 }
17230 return 0;
17231}
17232
17233/* parse the BIOS configuration and set up the alc_spec
17234 * return 1 if successful, 0 if the proper config is not found,
17235 * or a negative error code
17236 * Based on ALC880 version - had to change it to override
17237 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17238static int alc861vd_parse_auto_config(struct hda_codec *codec)
17239{
17240 struct alc_spec *spec = codec->spec;
17241 int err;
17242 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17243
f12ab1e0
TI
17244 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17245 alc861vd_ignore);
17246 if (err < 0)
f32610ed 17247 return err;
f12ab1e0 17248 if (!spec->autocfg.line_outs)
f32610ed
JS
17249 return 0; /* can't find valid BIOS pin config */
17250
f12ab1e0
TI
17251 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17252 if (err < 0)
17253 return err;
17254 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17255 if (err < 0)
17256 return err;
17257 err = alc861vd_auto_create_extra_out(spec,
17258 spec->autocfg.speaker_pins[0],
17259 "Speaker");
17260 if (err < 0)
17261 return err;
17262 err = alc861vd_auto_create_extra_out(spec,
17263 spec->autocfg.hp_pins[0],
17264 "Headphone");
17265 if (err < 0)
17266 return err;
05f5f477 17267 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17268 if (err < 0)
f32610ed
JS
17269 return err;
17270
17271 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17272
757899ac 17273 alc_auto_parse_digital(codec);
f32610ed 17274
603c4019 17275 if (spec->kctls.list)
d88897ea 17276 add_mixer(spec, spec->kctls.list);
f32610ed 17277
d88897ea 17278 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17279
17280 spec->num_mux_defs = 1;
61b9b9b1 17281 spec->input_mux = &spec->private_imux[0];
f32610ed 17282
776e184e
TI
17283 err = alc_auto_add_mic_boost(codec);
17284 if (err < 0)
17285 return err;
17286
6227cdce 17287 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17288
f32610ed
JS
17289 return 1;
17290}
17291
17292/* additional initialization for auto-configuration model */
17293static void alc861vd_auto_init(struct hda_codec *codec)
17294{
f6c7e546 17295 struct alc_spec *spec = codec->spec;
f32610ed
JS
17296 alc861vd_auto_init_multi_out(codec);
17297 alc861vd_auto_init_hp_out(codec);
17298 alc861vd_auto_init_analog_input(codec);
f511b01c 17299 alc861vd_auto_init_input_src(codec);
757899ac 17300 alc_auto_init_digital(codec);
f6c7e546 17301 if (spec->unsol_event)
7fb0d78f 17302 alc_inithook(codec);
f32610ed
JS
17303}
17304
f8f25ba3
TI
17305enum {
17306 ALC660VD_FIX_ASUS_GPIO1
17307};
17308
17309/* reset GPIO1 */
f8f25ba3
TI
17310static const struct alc_fixup alc861vd_fixups[] = {
17311 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17312 .type = ALC_FIXUP_VERBS,
17313 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17314 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17315 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17316 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17317 { }
17318 }
f8f25ba3
TI
17319 },
17320};
17321
17322static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17323 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17324 {}
17325};
17326
f32610ed
JS
17327static int patch_alc861vd(struct hda_codec *codec)
17328{
17329 struct alc_spec *spec;
17330 int err, board_config;
17331
17332 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17333 if (spec == NULL)
17334 return -ENOMEM;
17335
17336 codec->spec = spec;
17337
17338 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17339 alc861vd_models,
17340 alc861vd_cfg_tbl);
17341
17342 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17343 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17344 codec->chip_name);
f32610ed
JS
17345 board_config = ALC861VD_AUTO;
17346 }
17347
b5bfbc67
TI
17348 if (board_config == ALC861VD_AUTO) {
17349 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17350 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17351 }
f8f25ba3 17352
f32610ed
JS
17353 if (board_config == ALC861VD_AUTO) {
17354 /* automatic parse from the BIOS config */
17355 err = alc861vd_parse_auto_config(codec);
17356 if (err < 0) {
17357 alc_free(codec);
17358 return err;
f12ab1e0 17359 } else if (!err) {
f32610ed
JS
17360 printk(KERN_INFO
17361 "hda_codec: Cannot set up configuration "
17362 "from BIOS. Using base mode...\n");
17363 board_config = ALC861VD_3ST;
17364 }
17365 }
17366
680cd536
KK
17367 err = snd_hda_attach_beep_device(codec, 0x23);
17368 if (err < 0) {
17369 alc_free(codec);
17370 return err;
17371 }
17372
f32610ed 17373 if (board_config != ALC861VD_AUTO)
e9c364c0 17374 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17375
2f893286 17376 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17377 /* always turn on EAPD */
d88897ea 17378 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17379 }
17380
f32610ed
JS
17381 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17382 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17383
f32610ed
JS
17384 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17385 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17386
dd704698
TI
17387 if (!spec->adc_nids) {
17388 spec->adc_nids = alc861vd_adc_nids;
17389 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17390 }
17391 if (!spec->capsrc_nids)
17392 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17393
b59bdf3b 17394 set_capture_mixer(codec);
45bdd1c1 17395 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17396
2134ea4f
TI
17397 spec->vmaster_nid = 0x02;
17398
b5bfbc67 17399 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17400
f32610ed
JS
17401 codec->patch_ops = alc_patch_ops;
17402
17403 if (board_config == ALC861VD_AUTO)
17404 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17405#ifdef CONFIG_SND_HDA_POWER_SAVE
17406 if (!spec->loopback.amplist)
17407 spec->loopback.amplist = alc861vd_loopbacks;
17408#endif
f32610ed
JS
17409
17410 return 0;
17411}
17412
bc9f98a9
KY
17413/*
17414 * ALC662 support
17415 *
17416 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17417 * configuration. Each pin widget can choose any input DACs and a mixer.
17418 * Each ADC is connected from a mixer of all inputs. This makes possible
17419 * 6-channel independent captures.
17420 *
17421 * In addition, an independent DAC for the multi-playback (not used in this
17422 * driver yet).
17423 */
17424#define ALC662_DIGOUT_NID 0x06
17425#define ALC662_DIGIN_NID 0x0a
17426
17427static hda_nid_t alc662_dac_nids[4] = {
17428 /* front, rear, clfe, rear_surr */
17429 0x02, 0x03, 0x04
17430};
17431
622e84cd
KY
17432static hda_nid_t alc272_dac_nids[2] = {
17433 0x02, 0x03
17434};
17435
b59bdf3b 17436static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17437 /* ADC1-2 */
b59bdf3b 17438 0x09, 0x08
bc9f98a9 17439};
e1406348 17440
622e84cd
KY
17441static hda_nid_t alc272_adc_nids[1] = {
17442 /* ADC1-2 */
17443 0x08,
17444};
17445
b59bdf3b 17446static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17447static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17448
e1406348 17449
bc9f98a9
KY
17450/* input MUX */
17451/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17452static struct hda_input_mux alc662_capture_source = {
17453 .num_items = 4,
17454 .items = {
17455 { "Mic", 0x0 },
17456 { "Front Mic", 0x1 },
17457 { "Line", 0x2 },
17458 { "CD", 0x4 },
17459 },
17460};
17461
17462static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17463 .num_items = 2,
17464 .items = {
17465 { "Mic", 0x1 },
17466 { "Line", 0x2 },
17467 },
17468};
291702f0 17469
6dda9f4a
KY
17470static struct hda_input_mux alc663_capture_source = {
17471 .num_items = 3,
17472 .items = {
17473 { "Mic", 0x0 },
17474 { "Front Mic", 0x1 },
17475 { "Line", 0x2 },
17476 },
17477};
17478
4f5d1706 17479#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17480static struct hda_input_mux alc272_nc10_capture_source = {
17481 .num_items = 16,
17482 .items = {
17483 { "Autoselect Mic", 0x0 },
17484 { "Internal Mic", 0x1 },
17485 { "In-0x02", 0x2 },
17486 { "In-0x03", 0x3 },
17487 { "In-0x04", 0x4 },
17488 { "In-0x05", 0x5 },
17489 { "In-0x06", 0x6 },
17490 { "In-0x07", 0x7 },
17491 { "In-0x08", 0x8 },
17492 { "In-0x09", 0x9 },
17493 { "In-0x0a", 0x0a },
17494 { "In-0x0b", 0x0b },
17495 { "In-0x0c", 0x0c },
17496 { "In-0x0d", 0x0d },
17497 { "In-0x0e", 0x0e },
17498 { "In-0x0f", 0x0f },
17499 },
17500};
17501#endif
17502
bc9f98a9
KY
17503/*
17504 * 2ch mode
17505 */
17506static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17507 { 2, NULL }
17508};
17509
17510/*
17511 * 2ch mode
17512 */
17513static struct hda_verb alc662_3ST_ch2_init[] = {
17514 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17515 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17516 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17517 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17518 { } /* end */
17519};
17520
17521/*
17522 * 6ch mode
17523 */
17524static struct hda_verb alc662_3ST_ch6_init[] = {
17525 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17526 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17527 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17528 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17529 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17530 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17531 { } /* end */
17532};
17533
17534static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17535 { 2, alc662_3ST_ch2_init },
17536 { 6, alc662_3ST_ch6_init },
17537};
17538
17539/*
17540 * 2ch mode
17541 */
17542static struct hda_verb alc662_sixstack_ch6_init[] = {
17543 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17544 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17545 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17546 { } /* end */
17547};
17548
17549/*
17550 * 6ch mode
17551 */
17552static struct hda_verb alc662_sixstack_ch8_init[] = {
17553 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17554 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17555 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17556 { } /* end */
17557};
17558
17559static struct hda_channel_mode alc662_5stack_modes[2] = {
17560 { 2, alc662_sixstack_ch6_init },
17561 { 6, alc662_sixstack_ch8_init },
17562};
17563
17564/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17565 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17566 */
17567
17568static struct snd_kcontrol_new alc662_base_mixer[] = {
17569 /* output mixer control */
17570 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17571 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17572 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17573 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17574 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17575 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17576 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17577 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17578 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17579
17580 /*Input mixer control */
17581 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17582 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17583 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17584 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17585 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17586 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17587 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17588 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17589 { } /* end */
17590};
17591
17592static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17593 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17594 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17595 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17596 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17597 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17598 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17599 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17602 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17603 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17604 { } /* end */
17605};
17606
17607static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17608 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17609 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17610 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17611 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17612 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17613 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17614 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17615 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17617 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17618 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17620 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17622 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17623 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17624 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17625 { } /* end */
17626};
17627
17628static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17629 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17630 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17631 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17632 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17633 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17634 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17635 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17636 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17637 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17638 { } /* end */
17639};
17640
291702f0 17641static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17642 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17643 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17644
5f99f86a 17645 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17647 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17648
5f99f86a 17649 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17650 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17651 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17652 { } /* end */
17653};
17654
8c427226 17655static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17656 ALC262_HIPPO_MASTER_SWITCH,
17657 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17658 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17659 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17660 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17661 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17662 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17663 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17664 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17665 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17666 { } /* end */
17667};
17668
f1d4e28b
KY
17669static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17670 .ops = &snd_hda_bind_vol,
17671 .values = {
17672 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17673 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17674 0
17675 },
17676};
17677
17678static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17679 .ops = &snd_hda_bind_sw,
17680 .values = {
17681 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17682 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17683 0
17684 },
17685};
17686
6dda9f4a 17687static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17688 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17689 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17691 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17692 { } /* end */
17693};
17694
17695static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17696 .ops = &snd_hda_bind_sw,
17697 .values = {
17698 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17699 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17700 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17701 0
17702 },
17703};
17704
17705static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17706 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17707 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17710 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17711 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17712
17713 { } /* end */
17714};
17715
17716static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17717 .ops = &snd_hda_bind_sw,
17718 .values = {
17719 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17720 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17721 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17722 0
17723 },
17724};
17725
17726static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17727 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17728 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17729 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17731 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17732 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17733 { } /* end */
17734};
17735
17736static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17737 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17738 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17739 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17740 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17741 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17742 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17743 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17744 { } /* end */
17745};
17746
17747static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17748 .ops = &snd_hda_bind_vol,
17749 .values = {
17750 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17751 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17752 0
17753 },
17754};
17755
17756static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17757 .ops = &snd_hda_bind_sw,
17758 .values = {
17759 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17760 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17761 0
17762 },
17763};
17764
17765static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17766 HDA_BIND_VOL("Master Playback Volume",
17767 &alc663_asus_two_bind_master_vol),
17768 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17769 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17770 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17771 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17772 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17773 { } /* end */
17774};
17775
17776static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17777 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17778 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17779 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17780 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17782 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17783 { } /* end */
17784};
17785
17786static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17787 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17788 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17789 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17790 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17791 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17792
17793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17795 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17796 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17797 { } /* end */
17798};
17799
17800static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17801 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17802 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17804
17805 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17806 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17807 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17808 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17809 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17810 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17811 { } /* end */
17812};
17813
ebb83eeb
KY
17814static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17815 .ops = &snd_hda_bind_sw,
17816 .values = {
17817 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17818 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17819 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17820 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17821 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17822 0
17823 },
17824};
17825
17826static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17827 .ops = &snd_hda_bind_sw,
17828 .values = {
17829 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17830 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17831 0
17832 },
17833};
17834
17835static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17836 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17837 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17838 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17839 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17840 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17841 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17842 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17843 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17844 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17845 { } /* end */
17846};
17847
17848static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17849 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17850 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17851 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17852 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17853 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17854 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17856 { } /* end */
17857};
17858
17859
bc9f98a9
KY
17860static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17861 {
17862 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17863 .name = "Channel Mode",
17864 .info = alc_ch_mode_info,
17865 .get = alc_ch_mode_get,
17866 .put = alc_ch_mode_put,
17867 },
17868 { } /* end */
17869};
17870
17871static struct hda_verb alc662_init_verbs[] = {
17872 /* ADC: mute amp left and right */
17873 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17874 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17875
b60dd394
KY
17876 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17877 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17878 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17879 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17880 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17881 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17882
17883 /* Front Pin: output 0 (0x0c) */
17884 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17885 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17886
17887 /* Rear Pin: output 1 (0x0d) */
17888 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17889 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17890
17891 /* CLFE Pin: output 2 (0x0e) */
17892 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17893 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17894
17895 /* Mic (rear) pin: input vref at 80% */
17896 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17897 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17898 /* Front Mic pin: input vref at 80% */
17899 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17900 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17901 /* Line In pin: input */
17902 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17903 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17904 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17905 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17906 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17907 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17908 /* CD pin widget for input */
17909 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17910
17911 /* FIXME: use matrix-type input source selection */
17912 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17913 /* Input mixer */
17914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17915 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17916
17917 /* always trun on EAPD */
17918 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17919 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17920
bc9f98a9
KY
17921 { }
17922};
17923
cec27c89
KY
17924static struct hda_verb alc663_init_verbs[] = {
17925 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17926 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17927 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17928 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17929 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17930 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17931 { }
17932};
17933
17934static struct hda_verb alc272_init_verbs[] = {
17935 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17936 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17937 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17938 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17939 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17940 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17941 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17942 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17943 { }
17944};
17945
bc9f98a9
KY
17946static struct hda_verb alc662_sue_init_verbs[] = {
17947 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17948 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17949 {}
17950};
17951
17952static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17953 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17954 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17955 {}
bc9f98a9
KY
17956};
17957
8c427226
KY
17958/* Set Unsolicited Event*/
17959static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17960 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17961 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17962 {}
17963};
17964
6dda9f4a 17965static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17966 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17967 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17968 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17969 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17970 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17971 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17972 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17973 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17974 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17975 {}
17976};
17977
17978static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17979 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17980 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17981 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17982 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17983 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17984 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17985 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17986 {}
17987};
17988
17989static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17990 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17991 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17992 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17993 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17994 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17995 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17996 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17997 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17998 {}
17999};
6dda9f4a 18000
f1d4e28b
KY
18001static struct hda_verb alc663_15jd_amic_init_verbs[] = {
18002 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18003 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18004 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18007 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18008 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18009 {}
18010};
6dda9f4a 18011
f1d4e28b
KY
18012static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18013 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18014 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18015 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18016 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18018 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18019 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18020 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18021 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18022 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18023 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18024 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18025 {}
18026};
18027
18028static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18029 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18030 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18031 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18032 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18033 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18034 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18035 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18037 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18038 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18039 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18040 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18041 {}
18042};
18043
18044static struct hda_verb alc663_g71v_init_verbs[] = {
18045 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18046 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18047 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18048
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, 0x00}, /* Headphone */
18052
18053 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
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 alc663_g50v_init_verbs[] = {
18060 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18061 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18062 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18063
18064 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18065 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18066 {}
18067};
18068
f1d4e28b
KY
18069static struct hda_verb alc662_ecs_init_verbs[] = {
18070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18072 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18073 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18074 {}
18075};
18076
622e84cd
KY
18077static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18078 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18079 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18080 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18081 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
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 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18088 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18089 {}
18090};
18091
18092static struct hda_verb alc272_dell_init_verbs[] = {
18093 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18094 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18095 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18096 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18097 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18098 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18099 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18100 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18101 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18102 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18103 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18104 {}
18105};
18106
ebb83eeb
KY
18107static struct hda_verb alc663_mode7_init_verbs[] = {
18108 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18109 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18110 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18111 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18112 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18113 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18114 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18115 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18116 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18117 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18120 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18121 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18122 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18123 {}
18124};
18125
18126static struct hda_verb alc663_mode8_init_verbs[] = {
18127 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18128 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18129 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18130 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18131 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18132 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18133 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18134 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18135 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18136 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18137 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18138 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18139 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18140 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18141 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18142 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18143 {}
18144};
18145
f1d4e28b
KY
18146static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18147 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18148 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18149 { } /* end */
18150};
18151
622e84cd
KY
18152static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18153 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18154 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18155 { } /* end */
18156};
18157
bc9f98a9
KY
18158static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18159{
18160 unsigned int present;
f12ab1e0 18161 unsigned char bits;
bc9f98a9 18162
864f92be 18163 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 18164 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18165
47fd830a
TI
18166 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18167 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18168}
18169
18170static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18171{
18172 unsigned int present;
f12ab1e0 18173 unsigned char bits;
bc9f98a9 18174
864f92be 18175 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 18176 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18177
47fd830a
TI
18178 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18179 HDA_AMP_MUTE, bits);
18180 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18181 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18182}
18183
18184static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18185 unsigned int res)
18186{
18187 if ((res >> 26) == ALC880_HP_EVENT)
18188 alc662_lenovo_101e_all_automute(codec);
18189 if ((res >> 26) == ALC880_FRONT_EVENT)
18190 alc662_lenovo_101e_ispeaker_automute(codec);
18191}
18192
291702f0
KY
18193/* unsolicited event for HP jack sensing */
18194static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18195 unsigned int res)
18196{
291702f0 18197 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18198 alc_mic_automute(codec);
42171c17
TI
18199 else
18200 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18201}
18202
4f5d1706
TI
18203static void alc662_eeepc_setup(struct hda_codec *codec)
18204{
18205 struct alc_spec *spec = codec->spec;
18206
18207 alc262_hippo1_setup(codec);
18208 spec->ext_mic.pin = 0x18;
18209 spec->ext_mic.mux_idx = 0;
18210 spec->int_mic.pin = 0x19;
18211 spec->int_mic.mux_idx = 1;
18212 spec->auto_mic = 1;
18213}
18214
291702f0
KY
18215static void alc662_eeepc_inithook(struct hda_codec *codec)
18216{
4f5d1706
TI
18217 alc262_hippo_automute(codec);
18218 alc_mic_automute(codec);
291702f0
KY
18219}
18220
4f5d1706 18221static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18222{
42171c17
TI
18223 struct alc_spec *spec = codec->spec;
18224
18225 spec->autocfg.hp_pins[0] = 0x14;
18226 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18227}
18228
4f5d1706
TI
18229#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18230
6dda9f4a
KY
18231static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18232{
18233 unsigned int present;
18234 unsigned char bits;
18235
864f92be 18236 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18237 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18238 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18239 HDA_AMP_MUTE, bits);
f1d4e28b 18240 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18241 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18242}
18243
18244static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18245{
18246 unsigned int present;
18247 unsigned char bits;
18248
864f92be 18249 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18250 bits = present ? HDA_AMP_MUTE : 0;
18251 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18252 HDA_AMP_MUTE, bits);
f1d4e28b 18253 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18254 HDA_AMP_MUTE, bits);
f1d4e28b 18255 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18256 HDA_AMP_MUTE, bits);
f1d4e28b 18257 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18258 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18259}
18260
18261static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18262{
18263 unsigned int present;
18264 unsigned char bits;
18265
864f92be 18266 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18267 bits = present ? HDA_AMP_MUTE : 0;
18268 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18269 HDA_AMP_MUTE, bits);
f1d4e28b 18270 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18271 HDA_AMP_MUTE, bits);
f1d4e28b 18272 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18273 HDA_AMP_MUTE, bits);
f1d4e28b 18274 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18275 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18276}
18277
18278static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18279{
18280 unsigned int present;
18281 unsigned char bits;
18282
864f92be 18283 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18284 bits = present ? 0 : PIN_OUT;
18285 snd_hda_codec_write(codec, 0x14, 0,
18286 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18287}
18288
18289static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18290{
18291 unsigned int present1, present2;
18292
864f92be
WF
18293 present1 = snd_hda_jack_detect(codec, 0x21);
18294 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18295
18296 if (present1 || present2) {
18297 snd_hda_codec_write_cache(codec, 0x14, 0,
18298 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18299 } else {
18300 snd_hda_codec_write_cache(codec, 0x14, 0,
18301 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18302 }
18303}
18304
18305static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18306{
18307 unsigned int present1, present2;
18308
864f92be
WF
18309 present1 = snd_hda_jack_detect(codec, 0x1b);
18310 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18311
18312 if (present1 || present2) {
18313 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18314 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18315 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18316 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18317 } else {
18318 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18319 HDA_AMP_MUTE, 0);
f1d4e28b 18320 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18321 HDA_AMP_MUTE, 0);
f1d4e28b 18322 }
6dda9f4a
KY
18323}
18324
ebb83eeb
KY
18325static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18326{
18327 unsigned int present1, present2;
18328
18329 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18330 AC_VERB_GET_PIN_SENSE, 0)
18331 & AC_PINSENSE_PRESENCE;
18332 present2 = snd_hda_codec_read(codec, 0x21, 0,
18333 AC_VERB_GET_PIN_SENSE, 0)
18334 & AC_PINSENSE_PRESENCE;
18335
18336 if (present1 || present2) {
18337 snd_hda_codec_write_cache(codec, 0x14, 0,
18338 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18339 snd_hda_codec_write_cache(codec, 0x17, 0,
18340 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18341 } else {
18342 snd_hda_codec_write_cache(codec, 0x14, 0,
18343 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18344 snd_hda_codec_write_cache(codec, 0x17, 0,
18345 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18346 }
18347}
18348
18349static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18350{
18351 unsigned int present1, present2;
18352
18353 present1 = snd_hda_codec_read(codec, 0x21, 0,
18354 AC_VERB_GET_PIN_SENSE, 0)
18355 & AC_PINSENSE_PRESENCE;
18356 present2 = snd_hda_codec_read(codec, 0x15, 0,
18357 AC_VERB_GET_PIN_SENSE, 0)
18358 & AC_PINSENSE_PRESENCE;
18359
18360 if (present1 || present2) {
18361 snd_hda_codec_write_cache(codec, 0x14, 0,
18362 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18363 snd_hda_codec_write_cache(codec, 0x17, 0,
18364 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18365 } else {
18366 snd_hda_codec_write_cache(codec, 0x14, 0,
18367 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18368 snd_hda_codec_write_cache(codec, 0x17, 0,
18369 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18370 }
18371}
18372
6dda9f4a
KY
18373static void alc663_m51va_unsol_event(struct hda_codec *codec,
18374 unsigned int res)
18375{
18376 switch (res >> 26) {
18377 case ALC880_HP_EVENT:
18378 alc663_m51va_speaker_automute(codec);
18379 break;
18380 case ALC880_MIC_EVENT:
4f5d1706 18381 alc_mic_automute(codec);
6dda9f4a
KY
18382 break;
18383 }
18384}
18385
4f5d1706
TI
18386static void alc663_m51va_setup(struct hda_codec *codec)
18387{
18388 struct alc_spec *spec = codec->spec;
18389 spec->ext_mic.pin = 0x18;
18390 spec->ext_mic.mux_idx = 0;
18391 spec->int_mic.pin = 0x12;
ebb83eeb 18392 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18393 spec->auto_mic = 1;
18394}
18395
6dda9f4a
KY
18396static void alc663_m51va_inithook(struct hda_codec *codec)
18397{
18398 alc663_m51va_speaker_automute(codec);
4f5d1706 18399 alc_mic_automute(codec);
6dda9f4a
KY
18400}
18401
f1d4e28b 18402/* ***************** Mode1 ******************************/
4f5d1706 18403#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18404
18405static void alc663_mode1_setup(struct hda_codec *codec)
18406{
18407 struct alc_spec *spec = codec->spec;
18408 spec->ext_mic.pin = 0x18;
18409 spec->ext_mic.mux_idx = 0;
18410 spec->int_mic.pin = 0x19;
18411 spec->int_mic.mux_idx = 1;
18412 spec->auto_mic = 1;
18413}
18414
4f5d1706 18415#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18416
f1d4e28b
KY
18417/* ***************** Mode2 ******************************/
18418static void alc662_mode2_unsol_event(struct hda_codec *codec,
18419 unsigned int res)
18420{
18421 switch (res >> 26) {
18422 case ALC880_HP_EVENT:
18423 alc662_f5z_speaker_automute(codec);
18424 break;
18425 case ALC880_MIC_EVENT:
4f5d1706 18426 alc_mic_automute(codec);
f1d4e28b
KY
18427 break;
18428 }
18429}
18430
ebb83eeb 18431#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18432
f1d4e28b
KY
18433static void alc662_mode2_inithook(struct hda_codec *codec)
18434{
18435 alc662_f5z_speaker_automute(codec);
4f5d1706 18436 alc_mic_automute(codec);
f1d4e28b
KY
18437}
18438/* ***************** Mode3 ******************************/
18439static void alc663_mode3_unsol_event(struct hda_codec *codec,
18440 unsigned int res)
18441{
18442 switch (res >> 26) {
18443 case ALC880_HP_EVENT:
18444 alc663_two_hp_m1_speaker_automute(codec);
18445 break;
18446 case ALC880_MIC_EVENT:
4f5d1706 18447 alc_mic_automute(codec);
f1d4e28b
KY
18448 break;
18449 }
18450}
18451
ebb83eeb 18452#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18453
f1d4e28b
KY
18454static void alc663_mode3_inithook(struct hda_codec *codec)
18455{
18456 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18457 alc_mic_automute(codec);
f1d4e28b
KY
18458}
18459/* ***************** Mode4 ******************************/
18460static void alc663_mode4_unsol_event(struct hda_codec *codec,
18461 unsigned int res)
18462{
18463 switch (res >> 26) {
18464 case ALC880_HP_EVENT:
18465 alc663_21jd_two_speaker_automute(codec);
18466 break;
18467 case ALC880_MIC_EVENT:
4f5d1706 18468 alc_mic_automute(codec);
f1d4e28b
KY
18469 break;
18470 }
18471}
18472
ebb83eeb 18473#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18474
f1d4e28b
KY
18475static void alc663_mode4_inithook(struct hda_codec *codec)
18476{
18477 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18478 alc_mic_automute(codec);
f1d4e28b
KY
18479}
18480/* ***************** Mode5 ******************************/
18481static void alc663_mode5_unsol_event(struct hda_codec *codec,
18482 unsigned int res)
18483{
18484 switch (res >> 26) {
18485 case ALC880_HP_EVENT:
18486 alc663_15jd_two_speaker_automute(codec);
18487 break;
18488 case ALC880_MIC_EVENT:
4f5d1706 18489 alc_mic_automute(codec);
f1d4e28b
KY
18490 break;
18491 }
18492}
18493
ebb83eeb 18494#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18495
f1d4e28b
KY
18496static void alc663_mode5_inithook(struct hda_codec *codec)
18497{
18498 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18499 alc_mic_automute(codec);
f1d4e28b
KY
18500}
18501/* ***************** Mode6 ******************************/
18502static void alc663_mode6_unsol_event(struct hda_codec *codec,
18503 unsigned int res)
18504{
18505 switch (res >> 26) {
18506 case ALC880_HP_EVENT:
18507 alc663_two_hp_m2_speaker_automute(codec);
18508 break;
18509 case ALC880_MIC_EVENT:
4f5d1706 18510 alc_mic_automute(codec);
f1d4e28b
KY
18511 break;
18512 }
18513}
18514
ebb83eeb 18515#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18516
f1d4e28b
KY
18517static void alc663_mode6_inithook(struct hda_codec *codec)
18518{
18519 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18520 alc_mic_automute(codec);
f1d4e28b
KY
18521}
18522
ebb83eeb
KY
18523/* ***************** Mode7 ******************************/
18524static void alc663_mode7_unsol_event(struct hda_codec *codec,
18525 unsigned int res)
18526{
18527 switch (res >> 26) {
18528 case ALC880_HP_EVENT:
18529 alc663_two_hp_m7_speaker_automute(codec);
18530 break;
18531 case ALC880_MIC_EVENT:
18532 alc_mic_automute(codec);
18533 break;
18534 }
18535}
18536
18537#define alc663_mode7_setup alc663_mode1_setup
18538
18539static void alc663_mode7_inithook(struct hda_codec *codec)
18540{
18541 alc663_two_hp_m7_speaker_automute(codec);
18542 alc_mic_automute(codec);
18543}
18544
18545/* ***************** Mode8 ******************************/
18546static void alc663_mode8_unsol_event(struct hda_codec *codec,
18547 unsigned int res)
18548{
18549 switch (res >> 26) {
18550 case ALC880_HP_EVENT:
18551 alc663_two_hp_m8_speaker_automute(codec);
18552 break;
18553 case ALC880_MIC_EVENT:
18554 alc_mic_automute(codec);
18555 break;
18556 }
18557}
18558
18559#define alc663_mode8_setup alc663_m51va_setup
18560
18561static void alc663_mode8_inithook(struct hda_codec *codec)
18562{
18563 alc663_two_hp_m8_speaker_automute(codec);
18564 alc_mic_automute(codec);
18565}
18566
6dda9f4a
KY
18567static void alc663_g71v_hp_automute(struct hda_codec *codec)
18568{
18569 unsigned int present;
18570 unsigned char bits;
18571
864f92be 18572 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18573 bits = present ? HDA_AMP_MUTE : 0;
18574 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18575 HDA_AMP_MUTE, bits);
18576 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18577 HDA_AMP_MUTE, bits);
18578}
18579
18580static void alc663_g71v_front_automute(struct hda_codec *codec)
18581{
18582 unsigned int present;
18583 unsigned char bits;
18584
864f92be 18585 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18586 bits = present ? HDA_AMP_MUTE : 0;
18587 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18588 HDA_AMP_MUTE, bits);
18589}
18590
18591static void alc663_g71v_unsol_event(struct hda_codec *codec,
18592 unsigned int res)
18593{
18594 switch (res >> 26) {
18595 case ALC880_HP_EVENT:
18596 alc663_g71v_hp_automute(codec);
18597 break;
18598 case ALC880_FRONT_EVENT:
18599 alc663_g71v_front_automute(codec);
18600 break;
18601 case ALC880_MIC_EVENT:
4f5d1706 18602 alc_mic_automute(codec);
6dda9f4a
KY
18603 break;
18604 }
18605}
18606
4f5d1706
TI
18607#define alc663_g71v_setup alc663_m51va_setup
18608
6dda9f4a
KY
18609static void alc663_g71v_inithook(struct hda_codec *codec)
18610{
18611 alc663_g71v_front_automute(codec);
18612 alc663_g71v_hp_automute(codec);
4f5d1706 18613 alc_mic_automute(codec);
6dda9f4a
KY
18614}
18615
18616static void alc663_g50v_unsol_event(struct hda_codec *codec,
18617 unsigned int res)
18618{
18619 switch (res >> 26) {
18620 case ALC880_HP_EVENT:
18621 alc663_m51va_speaker_automute(codec);
18622 break;
18623 case ALC880_MIC_EVENT:
4f5d1706 18624 alc_mic_automute(codec);
6dda9f4a
KY
18625 break;
18626 }
18627}
18628
4f5d1706
TI
18629#define alc663_g50v_setup alc663_m51va_setup
18630
6dda9f4a
KY
18631static void alc663_g50v_inithook(struct hda_codec *codec)
18632{
18633 alc663_m51va_speaker_automute(codec);
4f5d1706 18634 alc_mic_automute(codec);
6dda9f4a
KY
18635}
18636
f1d4e28b
KY
18637static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18638 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18639 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18640
5f99f86a 18641 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18642 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18643 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18644
5f99f86a 18645 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18646 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18647 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18648 { } /* end */
18649};
18650
9541ba1d
CP
18651static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18652 /* Master Playback automatically created from Speaker and Headphone */
18653 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18654 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18655 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18656 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18657
8607f7c4
DH
18658 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18659 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18660 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18661
28c4edb7
DH
18662 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18663 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18664 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18665 { } /* end */
18666};
18667
cb53c626
TI
18668#ifdef CONFIG_SND_HDA_POWER_SAVE
18669#define alc662_loopbacks alc880_loopbacks
18670#endif
18671
bc9f98a9 18672
def319f9 18673/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18674#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18675#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18676#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18677#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18678
18679/*
18680 * configuration and preset
18681 */
ea734963 18682static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18683 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18684 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18685 [ALC662_3ST_6ch] = "3stack-6ch",
18686 [ALC662_5ST_DIG] = "6stack-dig",
18687 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18688 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18689 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18690 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18691 [ALC663_ASUS_M51VA] = "m51va",
18692 [ALC663_ASUS_G71V] = "g71v",
18693 [ALC663_ASUS_H13] = "h13",
18694 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18695 [ALC663_ASUS_MODE1] = "asus-mode1",
18696 [ALC662_ASUS_MODE2] = "asus-mode2",
18697 [ALC663_ASUS_MODE3] = "asus-mode3",
18698 [ALC663_ASUS_MODE4] = "asus-mode4",
18699 [ALC663_ASUS_MODE5] = "asus-mode5",
18700 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18701 [ALC663_ASUS_MODE7] = "asus-mode7",
18702 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18703 [ALC272_DELL] = "dell",
18704 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18705 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18706 [ALC662_AUTO] = "auto",
18707};
18708
18709static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18710 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18711 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18712 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18713 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18714 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18715 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18716 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18717 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18718 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18719 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18720 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18721 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18722 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18723 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18724 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18725 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18726 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18727 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18728 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18729 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18730 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18731 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18732 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18733 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18734 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18735 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18736 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18737 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18738 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18739 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18740 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18741 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18742 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18743 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18744 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18745 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18746 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18747 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18748 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18749 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18750 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18751 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18752 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18753 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18754 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18755 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18756 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18757 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18758 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18759 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18760 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18761 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18762 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18763 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18764 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18765 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18766 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18767 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18768 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18769 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18770 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18771 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18772 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18773 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18774 ALC662_3ST_6ch_DIG),
4dee8baa 18775 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18776 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18777 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18778 ALC662_3ST_6ch_DIG),
6227cdce 18779 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18780 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18781 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18782 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18783 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18784 ALC662_3ST_6ch_DIG),
dea0a509
TI
18785 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18786 ALC663_ASUS_H13),
965b76d2 18787 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18788 {}
18789};
18790
18791static struct alc_config_preset alc662_presets[] = {
18792 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18793 .mixers = { alc662_3ST_2ch_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_3ST_2ch_modes),
18800 .channel_mode = alc662_3ST_2ch_modes,
18801 .input_mux = &alc662_capture_source,
18802 },
18803 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18804 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18805 .init_verbs = { alc662_init_verbs },
18806 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18807 .dac_nids = alc662_dac_nids,
18808 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18809 .dig_in_nid = ALC662_DIGIN_NID,
18810 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18811 .channel_mode = alc662_3ST_6ch_modes,
18812 .need_dac_fix = 1,
18813 .input_mux = &alc662_capture_source,
f12ab1e0 18814 },
bc9f98a9 18815 [ALC662_3ST_6ch] = {
f9e336f6 18816 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18817 .init_verbs = { alc662_init_verbs },
18818 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18819 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18821 .channel_mode = alc662_3ST_6ch_modes,
18822 .need_dac_fix = 1,
18823 .input_mux = &alc662_capture_source,
f12ab1e0 18824 },
bc9f98a9 18825 [ALC662_5ST_DIG] = {
f9e336f6 18826 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18827 .init_verbs = { alc662_init_verbs },
18828 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18829 .dac_nids = alc662_dac_nids,
18830 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18831 .dig_in_nid = ALC662_DIGIN_NID,
18832 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18833 .channel_mode = alc662_5stack_modes,
18834 .input_mux = &alc662_capture_source,
18835 },
18836 [ALC662_LENOVO_101E] = {
f9e336f6 18837 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18838 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18839 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18840 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18841 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18842 .channel_mode = alc662_3ST_2ch_modes,
18843 .input_mux = &alc662_lenovo_101e_capture_source,
18844 .unsol_event = alc662_lenovo_101e_unsol_event,
18845 .init_hook = alc662_lenovo_101e_all_automute,
18846 },
291702f0 18847 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18848 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18849 .init_verbs = { alc662_init_verbs,
18850 alc662_eeepc_sue_init_verbs },
18851 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18852 .dac_nids = alc662_dac_nids,
291702f0
KY
18853 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18854 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18855 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18856 .setup = alc662_eeepc_setup,
291702f0
KY
18857 .init_hook = alc662_eeepc_inithook,
18858 },
8c427226 18859 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18860 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18861 alc662_chmode_mixer },
18862 .init_verbs = { alc662_init_verbs,
18863 alc662_eeepc_ep20_sue_init_verbs },
18864 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18865 .dac_nids = alc662_dac_nids,
8c427226
KY
18866 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18867 .channel_mode = alc662_3ST_6ch_modes,
18868 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18869 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18870 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18871 .init_hook = alc662_eeepc_ep20_inithook,
18872 },
f1d4e28b 18873 [ALC662_ECS] = {
f9e336f6 18874 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18875 .init_verbs = { alc662_init_verbs,
18876 alc662_ecs_init_verbs },
18877 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18878 .dac_nids = alc662_dac_nids,
18879 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18880 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18881 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18882 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18883 .init_hook = alc662_eeepc_inithook,
18884 },
6dda9f4a 18885 [ALC663_ASUS_M51VA] = {
f9e336f6 18886 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18887 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18888 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18889 .dac_nids = alc662_dac_nids,
18890 .dig_out_nid = ALC662_DIGOUT_NID,
18891 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18892 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18893 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18894 .setup = alc663_m51va_setup,
6dda9f4a
KY
18895 .init_hook = alc663_m51va_inithook,
18896 },
18897 [ALC663_ASUS_G71V] = {
f9e336f6 18898 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18899 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18900 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18901 .dac_nids = alc662_dac_nids,
18902 .dig_out_nid = ALC662_DIGOUT_NID,
18903 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18904 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18905 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18906 .setup = alc663_g71v_setup,
6dda9f4a
KY
18907 .init_hook = alc663_g71v_inithook,
18908 },
18909 [ALC663_ASUS_H13] = {
f9e336f6 18910 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18911 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18912 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18913 .dac_nids = alc662_dac_nids,
18914 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18915 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18916 .unsol_event = alc663_m51va_unsol_event,
18917 .init_hook = alc663_m51va_inithook,
18918 },
18919 [ALC663_ASUS_G50V] = {
f9e336f6 18920 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18921 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18922 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18923 .dac_nids = alc662_dac_nids,
18924 .dig_out_nid = ALC662_DIGOUT_NID,
18925 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18926 .channel_mode = alc662_3ST_6ch_modes,
18927 .input_mux = &alc663_capture_source,
18928 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18929 .setup = alc663_g50v_setup,
6dda9f4a
KY
18930 .init_hook = alc663_g50v_inithook,
18931 },
f1d4e28b 18932 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18933 .mixers = { alc663_m51va_mixer },
18934 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18935 .init_verbs = { alc662_init_verbs,
18936 alc663_21jd_amic_init_verbs },
18937 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18938 .hp_nid = 0x03,
18939 .dac_nids = alc662_dac_nids,
18940 .dig_out_nid = ALC662_DIGOUT_NID,
18941 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18942 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18943 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18944 .setup = alc663_mode1_setup,
f1d4e28b
KY
18945 .init_hook = alc663_mode1_inithook,
18946 },
18947 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18948 .mixers = { alc662_1bjd_mixer },
18949 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18950 .init_verbs = { alc662_init_verbs,
18951 alc662_1bjd_amic_init_verbs },
18952 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18953 .dac_nids = alc662_dac_nids,
18954 .dig_out_nid = ALC662_DIGOUT_NID,
18955 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18956 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18957 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18958 .setup = alc662_mode2_setup,
f1d4e28b
KY
18959 .init_hook = alc662_mode2_inithook,
18960 },
18961 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18962 .mixers = { alc663_two_hp_m1_mixer },
18963 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18964 .init_verbs = { alc662_init_verbs,
18965 alc663_two_hp_amic_m1_init_verbs },
18966 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18967 .hp_nid = 0x03,
18968 .dac_nids = alc662_dac_nids,
18969 .dig_out_nid = ALC662_DIGOUT_NID,
18970 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18971 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18972 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18973 .setup = alc663_mode3_setup,
f1d4e28b
KY
18974 .init_hook = alc663_mode3_inithook,
18975 },
18976 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18977 .mixers = { alc663_asus_21jd_clfe_mixer },
18978 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18979 .init_verbs = { alc662_init_verbs,
18980 alc663_21jd_amic_init_verbs},
18981 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18982 .hp_nid = 0x03,
18983 .dac_nids = alc662_dac_nids,
18984 .dig_out_nid = ALC662_DIGOUT_NID,
18985 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18986 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18987 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18988 .setup = alc663_mode4_setup,
f1d4e28b
KY
18989 .init_hook = alc663_mode4_inithook,
18990 },
18991 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18992 .mixers = { alc663_asus_15jd_clfe_mixer },
18993 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18994 .init_verbs = { alc662_init_verbs,
18995 alc663_15jd_amic_init_verbs },
18996 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18997 .hp_nid = 0x03,
18998 .dac_nids = alc662_dac_nids,
18999 .dig_out_nid = ALC662_DIGOUT_NID,
19000 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19001 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 19002 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 19003 .setup = alc663_mode5_setup,
f1d4e28b
KY
19004 .init_hook = alc663_mode5_inithook,
19005 },
19006 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
19007 .mixers = { alc663_two_hp_m2_mixer },
19008 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
19009 .init_verbs = { alc662_init_verbs,
19010 alc663_two_hp_amic_m2_init_verbs },
19011 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19012 .hp_nid = 0x03,
19013 .dac_nids = alc662_dac_nids,
19014 .dig_out_nid = ALC662_DIGOUT_NID,
19015 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19016 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 19017 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 19018 .setup = alc663_mode6_setup,
f1d4e28b
KY
19019 .init_hook = alc663_mode6_inithook,
19020 },
ebb83eeb
KY
19021 [ALC663_ASUS_MODE7] = {
19022 .mixers = { alc663_mode7_mixer },
19023 .cap_mixer = alc662_auto_capture_mixer,
19024 .init_verbs = { alc662_init_verbs,
19025 alc663_mode7_init_verbs },
19026 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19027 .hp_nid = 0x03,
19028 .dac_nids = alc662_dac_nids,
19029 .dig_out_nid = ALC662_DIGOUT_NID,
19030 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19031 .channel_mode = alc662_3ST_2ch_modes,
19032 .unsol_event = alc663_mode7_unsol_event,
19033 .setup = alc663_mode7_setup,
19034 .init_hook = alc663_mode7_inithook,
19035 },
19036 [ALC663_ASUS_MODE8] = {
19037 .mixers = { alc663_mode8_mixer },
19038 .cap_mixer = alc662_auto_capture_mixer,
19039 .init_verbs = { alc662_init_verbs,
19040 alc663_mode8_init_verbs },
19041 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19042 .hp_nid = 0x03,
19043 .dac_nids = alc662_dac_nids,
19044 .dig_out_nid = ALC662_DIGOUT_NID,
19045 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19046 .channel_mode = alc662_3ST_2ch_modes,
19047 .unsol_event = alc663_mode8_unsol_event,
19048 .setup = alc663_mode8_setup,
19049 .init_hook = alc663_mode8_inithook,
19050 },
622e84cd
KY
19051 [ALC272_DELL] = {
19052 .mixers = { alc663_m51va_mixer },
19053 .cap_mixer = alc272_auto_capture_mixer,
19054 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
19055 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19056 .dac_nids = alc662_dac_nids,
19057 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19058 .adc_nids = alc272_adc_nids,
19059 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19060 .capsrc_nids = alc272_capsrc_nids,
19061 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19062 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19063 .setup = alc663_m51va_setup,
622e84cd
KY
19064 .init_hook = alc663_m51va_inithook,
19065 },
19066 [ALC272_DELL_ZM1] = {
19067 .mixers = { alc663_m51va_mixer },
19068 .cap_mixer = alc662_auto_capture_mixer,
19069 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19070 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19071 .dac_nids = alc662_dac_nids,
19072 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19073 .adc_nids = alc662_adc_nids,
b59bdf3b 19074 .num_adc_nids = 1,
622e84cd
KY
19075 .capsrc_nids = alc662_capsrc_nids,
19076 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19077 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19078 .setup = alc663_m51va_setup,
622e84cd
KY
19079 .init_hook = alc663_m51va_inithook,
19080 },
9541ba1d
CP
19081 [ALC272_SAMSUNG_NC10] = {
19082 .mixers = { alc272_nc10_mixer },
19083 .init_verbs = { alc662_init_verbs,
19084 alc663_21jd_amic_init_verbs },
19085 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19086 .dac_nids = alc272_dac_nids,
19087 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19088 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 19089 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 19090 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19091 .setup = alc663_mode4_setup,
9541ba1d
CP
19092 .init_hook = alc663_mode4_inithook,
19093 },
bc9f98a9
KY
19094};
19095
19096
19097/*
19098 * BIOS auto configuration
19099 */
19100
7085ec12
TI
19101/* convert from MIX nid to DAC */
19102static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19103{
19104 if (nid == 0x0f)
19105 return 0x02;
19106 else if (nid >= 0x0c && nid <= 0x0e)
19107 return nid - 0x0c + 0x02;
cc1c452e
DH
19108 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19109 return 0x25;
7085ec12
TI
19110 else
19111 return 0;
19112}
19113
19114/* get MIX nid connected to the given pin targeted to DAC */
19115static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19116 hda_nid_t dac)
19117{
cc1c452e 19118 hda_nid_t mix[5];
7085ec12
TI
19119 int i, num;
19120
19121 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19122 for (i = 0; i < num; i++) {
19123 if (alc662_mix_to_dac(mix[i]) == dac)
19124 return mix[i];
19125 }
19126 return 0;
19127}
19128
19129/* look for an empty DAC slot */
19130static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19131{
19132 struct alc_spec *spec = codec->spec;
19133 hda_nid_t srcs[5];
19134 int i, j, num;
19135
19136 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19137 if (num < 0)
19138 return 0;
19139 for (i = 0; i < num; i++) {
19140 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19141 if (!nid)
19142 continue;
19143 for (j = 0; j < spec->multiout.num_dacs; j++)
19144 if (spec->multiout.dac_nids[j] == nid)
19145 break;
19146 if (j >= spec->multiout.num_dacs)
19147 return nid;
19148 }
19149 return 0;
19150}
19151
19152/* fill in the dac_nids table from the parsed pin configuration */
19153static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19154 const struct auto_pin_cfg *cfg)
19155{
19156 struct alc_spec *spec = codec->spec;
19157 int i;
19158 hda_nid_t dac;
19159
19160 spec->multiout.dac_nids = spec->private_dac_nids;
19161 for (i = 0; i < cfg->line_outs; i++) {
19162 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19163 if (!dac)
19164 continue;
19165 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19166 }
19167 return 0;
19168}
19169
bcb2f0f5
TI
19170static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19171 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19172{
bcb2f0f5 19173 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
19174 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19175}
19176
bcb2f0f5
TI
19177static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19178 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19179{
bcb2f0f5 19180 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19181 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19182}
19183
bcb2f0f5
TI
19184#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19185 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19186#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19187 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19188#define alc662_add_stereo_vol(spec, pfx, nid) \
19189 alc662_add_vol_ctl(spec, pfx, nid, 3)
19190#define alc662_add_stereo_sw(spec, pfx, nid) \
19191 alc662_add_sw_ctl(spec, pfx, nid, 3)
19192
bc9f98a9 19193/* add playback controls from the parsed DAC table */
7085ec12 19194static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19195 const struct auto_pin_cfg *cfg)
19196{
7085ec12 19197 struct alc_spec *spec = codec->spec;
ea734963 19198 static const char * const chname[4] = {
bc9f98a9
KY
19199 "Front", "Surround", NULL /*CLFE*/, "Side"
19200 };
bcb2f0f5 19201 const char *pfx = alc_get_line_out_pfx(cfg, true);
7085ec12 19202 hda_nid_t nid, mix;
bc9f98a9
KY
19203 int i, err;
19204
19205 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19206 nid = spec->multiout.dac_nids[i];
19207 if (!nid)
19208 continue;
19209 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19210 if (!mix)
bc9f98a9 19211 continue;
bcb2f0f5 19212 if (!pfx && i == 2) {
bc9f98a9 19213 /* Center/LFE */
7085ec12 19214 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19215 if (err < 0)
19216 return err;
7085ec12 19217 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19218 if (err < 0)
19219 return err;
7085ec12 19220 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19221 if (err < 0)
19222 return err;
7085ec12 19223 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19224 if (err < 0)
19225 return err;
19226 } else {
bcb2f0f5
TI
19227 const char *name = pfx;
19228 if (!name)
19229 name = chname[i];
19230 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
bc9f98a9
KY
19231 if (err < 0)
19232 return err;
bcb2f0f5 19233 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
bc9f98a9
KY
19234 if (err < 0)
19235 return err;
19236 }
19237 }
19238 return 0;
19239}
19240
19241/* add playback controls for speaker and HP outputs */
7085ec12
TI
19242/* return DAC nid if any new DAC is assigned */
19243static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19244 const char *pfx)
19245{
7085ec12
TI
19246 struct alc_spec *spec = codec->spec;
19247 hda_nid_t nid, mix;
bc9f98a9 19248 int err;
bc9f98a9
KY
19249
19250 if (!pin)
19251 return 0;
7085ec12
TI
19252 nid = alc662_look_for_dac(codec, pin);
19253 if (!nid) {
7085ec12
TI
19254 /* the corresponding DAC is already occupied */
19255 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19256 return 0; /* no way */
19257 /* create a switch only */
0afe5f89 19258 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19259 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19260 }
19261
7085ec12
TI
19262 mix = alc662_dac_to_mix(codec, pin, nid);
19263 if (!mix)
19264 return 0;
19265 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19266 if (err < 0)
19267 return err;
19268 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19269 if (err < 0)
19270 return err;
19271 return nid;
bc9f98a9
KY
19272}
19273
19274/* create playback/capture controls for input pins */
05f5f477 19275#define alc662_auto_create_input_ctls \
4b7348a1 19276 alc882_auto_create_input_ctls
bc9f98a9
KY
19277
19278static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19279 hda_nid_t nid, int pin_type,
7085ec12 19280 hda_nid_t dac)
bc9f98a9 19281{
7085ec12 19282 int i, num;
ce503f38 19283 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19284
f6c7e546 19285 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19286 /* need the manual connection? */
7085ec12
TI
19287 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19288 if (num <= 1)
19289 return;
19290 for (i = 0; i < num; i++) {
19291 if (alc662_mix_to_dac(srcs[i]) != dac)
19292 continue;
19293 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19294 return;
bc9f98a9
KY
19295 }
19296}
19297
19298static void alc662_auto_init_multi_out(struct hda_codec *codec)
19299{
19300 struct alc_spec *spec = codec->spec;
7085ec12 19301 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19302 int i;
19303
19304 for (i = 0; i <= HDA_SIDE; i++) {
19305 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19306 if (nid)
baba8ee9 19307 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19308 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19309 }
19310}
19311
19312static void alc662_auto_init_hp_out(struct hda_codec *codec)
19313{
19314 struct alc_spec *spec = codec->spec;
19315 hda_nid_t pin;
19316
19317 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19318 if (pin)
19319 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19320 spec->multiout.hp_nid);
f6c7e546
TI
19321 pin = spec->autocfg.speaker_pins[0];
19322 if (pin)
7085ec12
TI
19323 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19324 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19325}
19326
bc9f98a9
KY
19327#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19328
19329static void alc662_auto_init_analog_input(struct hda_codec *codec)
19330{
19331 struct alc_spec *spec = codec->spec;
66ceeb6b 19332 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19333 int i;
19334
66ceeb6b
TI
19335 for (i = 0; i < cfg->num_inputs; i++) {
19336 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19337 if (alc_is_input_pin(codec, nid)) {
30ea098f 19338 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19339 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19340 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19341 snd_hda_codec_write(codec, nid, 0,
19342 AC_VERB_SET_AMP_GAIN_MUTE,
19343 AMP_OUT_MUTE);
19344 }
19345 }
19346}
19347
f511b01c
TI
19348#define alc662_auto_init_input_src alc882_auto_init_input_src
19349
bc9f98a9
KY
19350static int alc662_parse_auto_config(struct hda_codec *codec)
19351{
19352 struct alc_spec *spec = codec->spec;
19353 int err;
19354 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19355
19356 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19357 alc662_ignore);
19358 if (err < 0)
19359 return err;
19360 if (!spec->autocfg.line_outs)
19361 return 0; /* can't find valid BIOS pin config */
19362
7085ec12 19363 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19364 if (err < 0)
19365 return err;
7085ec12 19366 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19367 if (err < 0)
19368 return err;
7085ec12 19369 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19370 spec->autocfg.speaker_pins[0],
19371 "Speaker");
19372 if (err < 0)
19373 return err;
7085ec12
TI
19374 if (err)
19375 spec->multiout.extra_out_nid[0] = err;
19376 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19377 "Headphone");
19378 if (err < 0)
19379 return err;
7085ec12
TI
19380 if (err)
19381 spec->multiout.hp_nid = err;
05f5f477 19382 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19383 if (err < 0)
bc9f98a9
KY
19384 return err;
19385
19386 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19387
757899ac 19388 alc_auto_parse_digital(codec);
bc9f98a9 19389
603c4019 19390 if (spec->kctls.list)
d88897ea 19391 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19392
19393 spec->num_mux_defs = 1;
61b9b9b1 19394 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19395
cec27c89
KY
19396 add_verb(spec, alc662_init_verbs);
19397 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19398 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19399 add_verb(spec, alc663_init_verbs);
19400
19401 if (codec->vendor_id == 0x10ec0272)
19402 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19403
19404 err = alc_auto_add_mic_boost(codec);
19405 if (err < 0)
19406 return err;
19407
6227cdce
KY
19408 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19409 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19410 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19411 else
19412 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19413
8c87286f 19414 return 1;
bc9f98a9
KY
19415}
19416
19417/* additional initialization for auto-configuration model */
19418static void alc662_auto_init(struct hda_codec *codec)
19419{
f6c7e546 19420 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19421 alc662_auto_init_multi_out(codec);
19422 alc662_auto_init_hp_out(codec);
19423 alc662_auto_init_analog_input(codec);
f511b01c 19424 alc662_auto_init_input_src(codec);
757899ac 19425 alc_auto_init_digital(codec);
f6c7e546 19426 if (spec->unsol_event)
7fb0d78f 19427 alc_inithook(codec);
bc9f98a9
KY
19428}
19429
6be7948f 19430static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19431 const struct alc_fixup *fix, int action)
6fc398cb 19432{
b5bfbc67 19433 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19434 return;
6be7948f
TB
19435 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19436 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19437 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19438 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19439 (0 << AC_AMPCAP_MUTE_SHIFT)))
19440 printk(KERN_WARNING
19441 "hda_codec: failed to override amp caps for NID 0x2\n");
19442}
19443
6cb3b707 19444enum {
2df03514 19445 ALC662_FIXUP_ASPIRE,
6cb3b707 19446 ALC662_FIXUP_IDEAPAD,
6be7948f 19447 ALC272_FIXUP_MARIO,
d2ebd479 19448 ALC662_FIXUP_CZC_P10T,
6cb3b707
DH
19449};
19450
19451static const struct alc_fixup alc662_fixups[] = {
2df03514 19452 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19453 .type = ALC_FIXUP_PINS,
19454 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19455 { 0x15, 0x99130112 }, /* subwoofer */
19456 { }
19457 }
19458 },
6cb3b707 19459 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19460 .type = ALC_FIXUP_PINS,
19461 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19462 { 0x17, 0x99130112 }, /* subwoofer */
19463 { }
19464 }
19465 },
6be7948f 19466 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19467 .type = ALC_FIXUP_FUNC,
19468 .v.func = alc272_fixup_mario,
d2ebd479
AA
19469 },
19470 [ALC662_FIXUP_CZC_P10T] = {
19471 .type = ALC_FIXUP_VERBS,
19472 .v.verbs = (const struct hda_verb[]) {
19473 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19474 {}
19475 }
19476 },
6cb3b707
DH
19477};
19478
19479static struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19480 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
2df03514 19481 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19482 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19483 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19484 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19485 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19486 {}
19487};
19488
6be7948f
TB
19489static const struct alc_model_fixup alc662_fixup_models[] = {
19490 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19491 {}
19492};
6cb3b707
DH
19493
19494
bc9f98a9
KY
19495static int patch_alc662(struct hda_codec *codec)
19496{
19497 struct alc_spec *spec;
19498 int err, board_config;
693194f3 19499 int coef;
bc9f98a9
KY
19500
19501 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19502 if (!spec)
19503 return -ENOMEM;
19504
19505 codec->spec = spec;
19506
da00c244
KY
19507 alc_auto_parse_customize_define(codec);
19508
2c3bf9ab
TI
19509 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19510
693194f3
KY
19511 coef = alc_read_coef_idx(codec, 0);
19512 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19513 alc_codec_rename(codec, "ALC661");
693194f3
KY
19514 else if (coef & (1 << 14) &&
19515 codec->bus->pci->subsystem_vendor == 0x1025 &&
19516 spec->cdefine.platform_type == 1)
c027ddcd 19517 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19518 else if (coef == 0x4011)
19519 alc_codec_rename(codec, "ALC656");
274693f3 19520
bc9f98a9
KY
19521 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19522 alc662_models,
19523 alc662_cfg_tbl);
19524 if (board_config < 0) {
9a11f1aa
TI
19525 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19526 codec->chip_name);
bc9f98a9
KY
19527 board_config = ALC662_AUTO;
19528 }
19529
19530 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19531 alc_pick_fixup(codec, alc662_fixup_models,
19532 alc662_fixup_tbl, alc662_fixups);
19533 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19534 /* automatic parse from the BIOS config */
19535 err = alc662_parse_auto_config(codec);
19536 if (err < 0) {
19537 alc_free(codec);
19538 return err;
8c87286f 19539 } else if (!err) {
bc9f98a9
KY
19540 printk(KERN_INFO
19541 "hda_codec: Cannot set up configuration "
19542 "from BIOS. Using base mode...\n");
19543 board_config = ALC662_3ST_2ch_DIG;
19544 }
19545 }
19546
dc1eae25 19547 if (has_cdefine_beep(codec)) {
8af2591d
TI
19548 err = snd_hda_attach_beep_device(codec, 0x1);
19549 if (err < 0) {
19550 alc_free(codec);
19551 return err;
19552 }
680cd536
KK
19553 }
19554
bc9f98a9 19555 if (board_config != ALC662_AUTO)
e9c364c0 19556 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19557
bc9f98a9
KY
19558 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19559 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19560
bc9f98a9
KY
19561 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19562 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19563
dd704698
TI
19564 if (!spec->adc_nids) {
19565 spec->adc_nids = alc662_adc_nids;
19566 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19567 }
19568 if (!spec->capsrc_nids)
19569 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19570
f9e336f6 19571 if (!spec->cap_mixer)
b59bdf3b 19572 set_capture_mixer(codec);
cec27c89 19573
dc1eae25 19574 if (has_cdefine_beep(codec)) {
da00c244
KY
19575 switch (codec->vendor_id) {
19576 case 0x10ec0662:
19577 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19578 break;
19579 case 0x10ec0272:
19580 case 0x10ec0663:
19581 case 0x10ec0665:
19582 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19583 break;
19584 case 0x10ec0273:
19585 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19586 break;
19587 }
cec27c89 19588 }
2134ea4f
TI
19589 spec->vmaster_nid = 0x02;
19590
b5bfbc67
TI
19591 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19592
bc9f98a9 19593 codec->patch_ops = alc_patch_ops;
b5bfbc67 19594 if (board_config == ALC662_AUTO)
bc9f98a9 19595 spec->init_hook = alc662_auto_init;
6cb3b707 19596
bf1b0225
KY
19597 alc_init_jacks(codec);
19598
cb53c626
TI
19599#ifdef CONFIG_SND_HDA_POWER_SAVE
19600 if (!spec->loopback.amplist)
19601 spec->loopback.amplist = alc662_loopbacks;
19602#endif
bc9f98a9
KY
19603
19604 return 0;
19605}
19606
274693f3
KY
19607static int patch_alc888(struct hda_codec *codec)
19608{
19609 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19610 kfree(codec->chip_name);
01e0f137
KY
19611 if (codec->vendor_id == 0x10ec0887)
19612 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19613 else
19614 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19615 if (!codec->chip_name) {
19616 alc_free(codec);
274693f3 19617 return -ENOMEM;
ac2c92e0
TI
19618 }
19619 return patch_alc662(codec);
274693f3 19620 }
ac2c92e0 19621 return patch_alc882(codec);
274693f3
KY
19622}
19623
d1eb57f4
KY
19624/*
19625 * ALC680 support
19626 */
c69aefab 19627#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19628#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19629#define alc680_modes alc260_modes
19630
19631static hda_nid_t alc680_dac_nids[3] = {
19632 /* Lout1, Lout2, hp */
19633 0x02, 0x03, 0x04
19634};
19635
19636static hda_nid_t alc680_adc_nids[3] = {
19637 /* ADC0-2 */
19638 /* DMIC, MIC, Line-in*/
19639 0x07, 0x08, 0x09
19640};
19641
c69aefab
KY
19642/*
19643 * Analog capture ADC cgange
19644 */
66ceeb6b
TI
19645static void alc680_rec_autoswitch(struct hda_codec *codec)
19646{
19647 struct alc_spec *spec = codec->spec;
19648 struct auto_pin_cfg *cfg = &spec->autocfg;
19649 int pin_found = 0;
19650 int type_found = AUTO_PIN_LAST;
19651 hda_nid_t nid;
19652 int i;
19653
19654 for (i = 0; i < cfg->num_inputs; i++) {
19655 nid = cfg->inputs[i].pin;
19656 if (!(snd_hda_query_pin_caps(codec, nid) &
19657 AC_PINCAP_PRES_DETECT))
19658 continue;
19659 if (snd_hda_jack_detect(codec, nid)) {
19660 if (cfg->inputs[i].type < type_found) {
19661 type_found = cfg->inputs[i].type;
19662 pin_found = nid;
19663 }
19664 }
19665 }
19666
19667 nid = 0x07;
19668 if (pin_found)
19669 snd_hda_get_connections(codec, pin_found, &nid, 1);
19670
19671 if (nid != spec->cur_adc)
19672 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19673 spec->cur_adc = nid;
19674 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19675 spec->cur_adc_format);
19676}
19677
c69aefab
KY
19678static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19679 struct hda_codec *codec,
19680 unsigned int stream_tag,
19681 unsigned int format,
19682 struct snd_pcm_substream *substream)
19683{
19684 struct alc_spec *spec = codec->spec;
c69aefab 19685
66ceeb6b 19686 spec->cur_adc = 0x07;
c69aefab
KY
19687 spec->cur_adc_stream_tag = stream_tag;
19688 spec->cur_adc_format = format;
19689
66ceeb6b 19690 alc680_rec_autoswitch(codec);
c69aefab
KY
19691 return 0;
19692}
19693
19694static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19695 struct hda_codec *codec,
19696 struct snd_pcm_substream *substream)
19697{
19698 snd_hda_codec_cleanup_stream(codec, 0x07);
19699 snd_hda_codec_cleanup_stream(codec, 0x08);
19700 snd_hda_codec_cleanup_stream(codec, 0x09);
19701 return 0;
19702}
19703
19704static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19705 .substreams = 1, /* can be overridden */
19706 .channels_min = 2,
19707 .channels_max = 2,
19708 /* NID is set in alc_build_pcms */
19709 .ops = {
19710 .prepare = alc680_capture_pcm_prepare,
19711 .cleanup = alc680_capture_pcm_cleanup
19712 },
19713};
19714
d1eb57f4
KY
19715static struct snd_kcontrol_new alc680_base_mixer[] = {
19716 /* output mixer control */
19717 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19718 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19719 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19720 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19721 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19722 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19723 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19724 { }
19725};
19726
c69aefab
KY
19727static struct hda_bind_ctls alc680_bind_cap_vol = {
19728 .ops = &snd_hda_bind_vol,
19729 .values = {
19730 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19731 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19732 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19733 0
19734 },
19735};
19736
19737static struct hda_bind_ctls alc680_bind_cap_switch = {
19738 .ops = &snd_hda_bind_sw,
19739 .values = {
19740 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19741 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19742 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19743 0
19744 },
19745};
19746
19747static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19748 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19749 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19750 { } /* end */
19751};
19752
19753/*
19754 * generic initialization of ADC, input mixers and output mixers
19755 */
19756static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19757 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19758 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19759 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19760
c69aefab
KY
19761 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19762 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19763 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19764 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19765 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19766 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19767
19768 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19769 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19770 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19772 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19773
19774 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19775 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19776 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19777
d1eb57f4
KY
19778 { }
19779};
19780
c69aefab
KY
19781/* toggle speaker-output according to the hp-jack state */
19782static void alc680_base_setup(struct hda_codec *codec)
19783{
19784 struct alc_spec *spec = codec->spec;
19785
19786 spec->autocfg.hp_pins[0] = 0x16;
19787 spec->autocfg.speaker_pins[0] = 0x14;
19788 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19789 spec->autocfg.num_inputs = 2;
19790 spec->autocfg.inputs[0].pin = 0x18;
19791 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19792 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19793 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19794}
19795
19796static void alc680_unsol_event(struct hda_codec *codec,
19797 unsigned int res)
19798{
19799 if ((res >> 26) == ALC880_HP_EVENT)
19800 alc_automute_amp(codec);
19801 if ((res >> 26) == ALC880_MIC_EVENT)
19802 alc680_rec_autoswitch(codec);
19803}
19804
19805static void alc680_inithook(struct hda_codec *codec)
19806{
19807 alc_automute_amp(codec);
19808 alc680_rec_autoswitch(codec);
19809}
19810
d1eb57f4
KY
19811/* create input playback/capture controls for the given pin */
19812static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19813 const char *ctlname, int idx)
19814{
19815 hda_nid_t dac;
19816 int err;
19817
19818 switch (nid) {
19819 case 0x14:
19820 dac = 0x02;
19821 break;
19822 case 0x15:
19823 dac = 0x03;
19824 break;
19825 case 0x16:
19826 dac = 0x04;
19827 break;
19828 default:
19829 return 0;
19830 }
19831 if (spec->multiout.dac_nids[0] != dac &&
19832 spec->multiout.dac_nids[1] != dac) {
19833 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19834 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19835 HDA_OUTPUT));
19836 if (err < 0)
19837 return err;
19838
19839 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19840 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19841
19842 if (err < 0)
19843 return err;
19844 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19845 }
19846
19847 return 0;
19848}
19849
19850/* add playback controls from the parsed DAC table */
19851static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19852 const struct auto_pin_cfg *cfg)
19853{
19854 hda_nid_t nid;
19855 int err;
19856
19857 spec->multiout.dac_nids = spec->private_dac_nids;
19858
19859 nid = cfg->line_out_pins[0];
19860 if (nid) {
19861 const char *name;
19862 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19863 name = "Speaker";
19864 else
19865 name = "Front";
19866 err = alc680_new_analog_output(spec, nid, name, 0);
19867 if (err < 0)
19868 return err;
19869 }
19870
19871 nid = cfg->speaker_pins[0];
19872 if (nid) {
19873 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19874 if (err < 0)
19875 return err;
19876 }
19877 nid = cfg->hp_pins[0];
19878 if (nid) {
19879 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19880 if (err < 0)
19881 return err;
19882 }
19883
19884 return 0;
19885}
19886
19887static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19888 hda_nid_t nid, int pin_type)
19889{
19890 alc_set_pin_output(codec, nid, pin_type);
19891}
19892
19893static void alc680_auto_init_multi_out(struct hda_codec *codec)
19894{
19895 struct alc_spec *spec = codec->spec;
19896 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19897 if (nid) {
19898 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19899 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19900 }
19901}
19902
19903static void alc680_auto_init_hp_out(struct hda_codec *codec)
19904{
19905 struct alc_spec *spec = codec->spec;
19906 hda_nid_t pin;
19907
19908 pin = spec->autocfg.hp_pins[0];
19909 if (pin)
19910 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19911 pin = spec->autocfg.speaker_pins[0];
19912 if (pin)
19913 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19914}
19915
19916/* pcm configuration: identical with ALC880 */
19917#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19918#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19919#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19920#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19921#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19922
19923/*
19924 * BIOS auto configuration
19925 */
19926static int alc680_parse_auto_config(struct hda_codec *codec)
19927{
19928 struct alc_spec *spec = codec->spec;
19929 int err;
19930 static hda_nid_t alc680_ignore[] = { 0 };
19931
19932 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19933 alc680_ignore);
19934 if (err < 0)
19935 return err;
c69aefab 19936
d1eb57f4
KY
19937 if (!spec->autocfg.line_outs) {
19938 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19939 spec->multiout.max_channels = 2;
19940 spec->no_analog = 1;
19941 goto dig_only;
19942 }
19943 return 0; /* can't find valid BIOS pin config */
19944 }
19945 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19946 if (err < 0)
19947 return err;
19948
19949 spec->multiout.max_channels = 2;
19950
19951 dig_only:
19952 /* digital only support output */
757899ac 19953 alc_auto_parse_digital(codec);
d1eb57f4
KY
19954 if (spec->kctls.list)
19955 add_mixer(spec, spec->kctls.list);
19956
19957 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19958
19959 err = alc_auto_add_mic_boost(codec);
19960 if (err < 0)
19961 return err;
19962
19963 return 1;
19964}
19965
19966#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19967
19968/* init callback for auto-configuration model -- overriding the default init */
19969static void alc680_auto_init(struct hda_codec *codec)
19970{
19971 struct alc_spec *spec = codec->spec;
19972 alc680_auto_init_multi_out(codec);
19973 alc680_auto_init_hp_out(codec);
19974 alc680_auto_init_analog_input(codec);
757899ac 19975 alc_auto_init_digital(codec);
d1eb57f4
KY
19976 if (spec->unsol_event)
19977 alc_inithook(codec);
19978}
19979
19980/*
19981 * configuration and preset
19982 */
ea734963 19983static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19984 [ALC680_BASE] = "base",
19985 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19986};
19987
19988static struct snd_pci_quirk alc680_cfg_tbl[] = {
19989 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19990 {}
19991};
19992
19993static struct alc_config_preset alc680_presets[] = {
19994 [ALC680_BASE] = {
19995 .mixers = { alc680_base_mixer },
c69aefab 19996 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19997 .init_verbs = { alc680_init_verbs },
19998 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19999 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
20000 .dig_out_nid = ALC680_DIGOUT_NID,
20001 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20002 .channel_mode = alc680_modes,
c69aefab
KY
20003 .unsol_event = alc680_unsol_event,
20004 .setup = alc680_base_setup,
20005 .init_hook = alc680_inithook,
20006
d1eb57f4
KY
20007 },
20008};
20009
20010static int patch_alc680(struct hda_codec *codec)
20011{
20012 struct alc_spec *spec;
20013 int board_config;
20014 int err;
20015
20016 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20017 if (spec == NULL)
20018 return -ENOMEM;
20019
20020 codec->spec = spec;
20021
20022 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20023 alc680_models,
20024 alc680_cfg_tbl);
20025
20026 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20027 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20028 codec->chip_name);
20029 board_config = ALC680_AUTO;
20030 }
20031
20032 if (board_config == ALC680_AUTO) {
20033 /* automatic parse from the BIOS config */
20034 err = alc680_parse_auto_config(codec);
20035 if (err < 0) {
20036 alc_free(codec);
20037 return err;
20038 } else if (!err) {
20039 printk(KERN_INFO
20040 "hda_codec: Cannot set up configuration "
20041 "from BIOS. Using base mode...\n");
20042 board_config = ALC680_BASE;
20043 }
20044 }
20045
20046 if (board_config != ALC680_AUTO)
20047 setup_preset(codec, &alc680_presets[board_config]);
20048
20049 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 20050 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 20051 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 20052 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
20053
20054 if (!spec->adc_nids) {
20055 spec->adc_nids = alc680_adc_nids;
20056 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20057 }
20058
20059 if (!spec->cap_mixer)
20060 set_capture_mixer(codec);
20061
20062 spec->vmaster_nid = 0x02;
20063
20064 codec->patch_ops = alc_patch_ops;
20065 if (board_config == ALC680_AUTO)
20066 spec->init_hook = alc680_auto_init;
20067
20068 return 0;
20069}
20070
1da177e4
LT
20071/*
20072 * patch entries
20073 */
1289e9e8 20074static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 20075 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20076 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20077 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20078 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20079 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20080 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20081 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20082 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20083 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20084 .patch = patch_alc861 },
f32610ed
JS
20085 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20086 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20087 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20088 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20089 .patch = patch_alc882 },
bc9f98a9
KY
20090 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20091 .patch = patch_alc662 },
6dda9f4a 20092 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20093 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20094 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20095 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20096 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20097 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20098 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20099 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20100 .patch = patch_alc882 },
cb308f97 20101 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20102 .patch = patch_alc882 },
df694daa 20103 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20104 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20105 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20106 .patch = patch_alc882 },
274693f3 20107 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20108 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20109 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20110 {} /* terminator */
20111};
1289e9e8
TI
20112
20113MODULE_ALIAS("snd-hda-codec-id:10ec*");
20114
20115MODULE_LICENSE("GPL");
20116MODULE_DESCRIPTION("Realtek HD-audio codec");
20117
20118static struct hda_codec_preset_list realtek_list = {
20119 .preset = snd_hda_preset_realtek,
20120 .owner = THIS_MODULE,
20121};
20122
20123static int __init patch_realtek_init(void)
20124{
20125 return snd_hda_add_codec_preset(&realtek_list);
20126}
20127
20128static void __exit patch_realtek_exit(void)
20129{
20130 snd_hda_delete_codec_preset(&realtek_list);
20131}
20132
20133module_init(patch_realtek_init)
20134module_exit(patch_realtek_exit)