]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Fix mix->DAC deduction for ALC892
[thirdparty/kernel/stable.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
1da177e4
LT
302struct alc_spec {
303 /* codec parameterization */
df694daa 304 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 305 unsigned int num_mixers;
f9e336f6 306 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 307 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 308
2d9c6482 309 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
310 * don't forget NULL
311 * termination!
e9edcee0
TI
312 */
313 unsigned int num_init_verbs;
1da177e4 314
aa563af7 315 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
316 struct hda_pcm_stream *stream_analog_playback;
317 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
318 struct hda_pcm_stream *stream_analog_alt_playback;
319 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 320
aa563af7 321 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
322 struct hda_pcm_stream *stream_digital_playback;
323 struct hda_pcm_stream *stream_digital_capture;
324
325 /* playback */
16ded525
TI
326 struct hda_multi_out multiout; /* playback set-up
327 * max_channels, dacs must be set
328 * dig_out_nid and hp_nid are optional
329 */
6330079f 330 hda_nid_t alt_dac_nid;
6a05ac4a 331 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 332 int dig_out_type;
1da177e4
LT
333
334 /* capture */
335 unsigned int num_adc_nids;
336 hda_nid_t *adc_nids;
e1406348 337 hda_nid_t *capsrc_nids;
16ded525 338 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 339
840b64c0
TI
340 /* capture setup for dynamic dual-adc switch */
341 unsigned int cur_adc_idx;
342 hda_nid_t cur_adc;
343 unsigned int cur_adc_stream_tag;
344 unsigned int cur_adc_format;
345
1da177e4 346 /* capture source */
a1e8d2da 347 unsigned int num_mux_defs;
1da177e4
LT
348 const struct hda_input_mux *input_mux;
349 unsigned int cur_mux[3];
6c819492
TI
350 struct alc_mic_route ext_mic;
351 struct alc_mic_route int_mic;
1da177e4
LT
352
353 /* channel model */
d2a6d7dc 354 const struct hda_channel_mode *channel_mode;
1da177e4 355 int num_channel_mode;
4e195a7b 356 int need_dac_fix;
3b315d70
HM
357 int const_channel_count;
358 int ext_channel_count;
1da177e4
LT
359
360 /* PCM information */
4c5186ed 361 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 362
e9edcee0
TI
363 /* dynamic controls, init_verbs and input_mux */
364 struct auto_pin_cfg autocfg;
da00c244 365 struct alc_customize_define cdefine;
603c4019 366 struct snd_array kctls;
61b9b9b1 367 struct hda_input_mux private_imux[3];
41923e44 368 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
369 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
370 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 371
ae6b813a
TI
372 /* hooks */
373 void (*init_hook)(struct hda_codec *codec);
374 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 375#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 376 void (*power_hook)(struct hda_codec *codec);
f5de24b0 377#endif
ae6b813a 378
834be88d
TI
379 /* for pin sensing */
380 unsigned int sense_updated: 1;
381 unsigned int jack_present: 1;
bec15c3a 382 unsigned int master_sw: 1;
6c819492 383 unsigned int auto_mic:1;
cb53c626 384
e64f14f4
TI
385 /* other flags */
386 unsigned int no_analog :1; /* digital I/O only */
840b64c0 387 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
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:
75eb1c31 1268 case 0x10ec0665:
c9b58006 1269 case 0x10ec0862:
20a3a05d 1270 case 0x10ec0889:
3fb4a508
TI
1271 set_eapd(codec, 0x14, 1);
1272 set_eapd(codec, 0x15, 1);
c9b58006 1273 break;
bdd148a3 1274 }
c9b58006
KY
1275 switch (codec->vendor_id) {
1276 case 0x10ec0260:
1277 snd_hda_codec_write(codec, 0x1a, 0,
1278 AC_VERB_SET_COEF_INDEX, 7);
1279 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1280 AC_VERB_GET_PROC_COEF, 0);
1281 snd_hda_codec_write(codec, 0x1a, 0,
1282 AC_VERB_SET_COEF_INDEX, 7);
1283 snd_hda_codec_write(codec, 0x1a, 0,
1284 AC_VERB_SET_PROC_COEF,
1285 tmp | 0x2010);
1286 break;
1287 case 0x10ec0262:
1288 case 0x10ec0880:
1289 case 0x10ec0882:
1290 case 0x10ec0883:
1291 case 0x10ec0885:
4a5a4c56 1292 case 0x10ec0887:
20b67ddd 1293 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1294 alc889_coef_init(codec);
c9b58006 1295 break;
f9423e7a 1296 case 0x10ec0888:
4a79ba34 1297 alc888_coef_init(codec);
f9423e7a 1298 break;
0aea778e 1299#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1300 case 0x10ec0267:
1301 case 0x10ec0268:
1302 snd_hda_codec_write(codec, 0x20, 0,
1303 AC_VERB_SET_COEF_INDEX, 7);
1304 tmp = snd_hda_codec_read(codec, 0x20, 0,
1305 AC_VERB_GET_PROC_COEF, 0);
1306 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1307 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1308 snd_hda_codec_write(codec, 0x20, 0,
1309 AC_VERB_SET_PROC_COEF,
1310 tmp | 0x3000);
1311 break;
0aea778e 1312#endif /* XXX */
bc9f98a9 1313 }
4a79ba34
TI
1314 break;
1315 }
1316}
1317
1318static void alc_init_auto_hp(struct hda_codec *codec)
1319{
1320 struct alc_spec *spec = codec->spec;
bb35febd
TI
1321 struct auto_pin_cfg *cfg = &spec->autocfg;
1322 int i;
4a79ba34 1323
bb35febd
TI
1324 if (!cfg->hp_pins[0]) {
1325 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1326 return;
1327 }
4a79ba34 1328
bb35febd
TI
1329 if (!cfg->speaker_pins[0]) {
1330 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4a79ba34 1331 return;
bb35febd
TI
1332 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1333 sizeof(cfg->speaker_pins));
1334 cfg->speaker_outs = cfg->line_outs;
1335 }
1336
1337 if (!cfg->hp_pins[0]) {
1338 memcpy(cfg->hp_pins, cfg->line_out_pins,
1339 sizeof(cfg->hp_pins));
1340 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1341 }
1342
bb35febd
TI
1343 for (i = 0; i < cfg->hp_outs; i++) {
1344 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1345 cfg->hp_pins[i]);
1346 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
4a79ba34
TI
1347 AC_VERB_SET_UNSOLICITED_ENABLE,
1348 AC_USRSP_EN | ALC880_HP_EVENT);
bb35febd 1349 }
4a79ba34
TI
1350 spec->unsol_event = alc_sku_unsol_event;
1351}
1352
6c819492
TI
1353static void alc_init_auto_mic(struct hda_codec *codec)
1354{
1355 struct alc_spec *spec = codec->spec;
1356 struct auto_pin_cfg *cfg = &spec->autocfg;
1357 hda_nid_t fixed, ext;
1358 int i;
1359
1360 /* there must be only two mic inputs exclusively */
66ceeb6b 1361 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1362 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1363 return;
1364
1365 fixed = ext = 0;
66ceeb6b
TI
1366 for (i = 0; i < cfg->num_inputs; i++) {
1367 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1368 unsigned int defcfg;
6c819492 1369 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1370 switch (snd_hda_get_input_pin_attr(defcfg)) {
1371 case INPUT_PIN_ATTR_INT:
6c819492
TI
1372 if (fixed)
1373 return; /* already occupied */
1374 fixed = nid;
1375 break;
99ae28be
TI
1376 case INPUT_PIN_ATTR_UNUSED:
1377 return; /* invalid entry */
1378 default:
6c819492
TI
1379 if (ext)
1380 return; /* already occupied */
1381 ext = nid;
1382 break;
6c819492
TI
1383 }
1384 }
eaa9b3a7
TI
1385 if (!ext || !fixed)
1386 return;
6c819492
TI
1387 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1388 return; /* no unsol support */
1389 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1390 ext, fixed);
1391 spec->ext_mic.pin = ext;
1392 spec->int_mic.pin = fixed;
1393 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1394 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1395 spec->auto_mic = 1;
1396 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1397 AC_VERB_SET_UNSOLICITED_ENABLE,
1398 AC_USRSP_EN | ALC880_MIC_EVENT);
1399 spec->unsol_event = alc_sku_unsol_event;
1400}
1401
90622917
DH
1402/* Could be any non-zero and even value. When used as fixup, tells
1403 * the driver to ignore any present sku defines.
1404 */
1405#define ALC_FIXUP_SKU_IGNORE (2)
1406
da00c244
KY
1407static int alc_auto_parse_customize_define(struct hda_codec *codec)
1408{
1409 unsigned int ass, tmp, i;
7fb56223 1410 unsigned nid = 0;
da00c244
KY
1411 struct alc_spec *spec = codec->spec;
1412
b6cbe517
TI
1413 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1414
90622917
DH
1415 if (spec->cdefine.fixup) {
1416 ass = spec->cdefine.sku_cfg;
1417 if (ass == ALC_FIXUP_SKU_IGNORE)
1418 return -1;
1419 goto do_sku;
1420 }
1421
da00c244 1422 ass = codec->subsystem_id & 0xffff;
b6cbe517 1423 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1424 goto do_sku;
1425
1426 nid = 0x1d;
1427 if (codec->vendor_id == 0x10ec0260)
1428 nid = 0x17;
1429 ass = snd_hda_codec_get_pincfg(codec, nid);
1430
1431 if (!(ass & 1)) {
1432 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1433 codec->chip_name, ass);
1434 return -1;
1435 }
1436
1437 /* check sum */
1438 tmp = 0;
1439 for (i = 1; i < 16; i++) {
1440 if ((ass >> i) & 1)
1441 tmp++;
1442 }
1443 if (((ass >> 16) & 0xf) != tmp)
1444 return -1;
1445
1446 spec->cdefine.port_connectivity = ass >> 30;
1447 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1448 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1449 spec->cdefine.customization = ass >> 8;
1450do_sku:
1451 spec->cdefine.sku_cfg = ass;
1452 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1453 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1454 spec->cdefine.swap = (ass & 0x2) >> 1;
1455 spec->cdefine.override = ass & 0x1;
1456
1457 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1458 nid, spec->cdefine.sku_cfg);
1459 snd_printd("SKU: port_connectivity=0x%x\n",
1460 spec->cdefine.port_connectivity);
1461 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1462 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1463 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1464 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1465 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1466 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1467 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1468
1469 return 0;
1470}
1471
4a79ba34
TI
1472/* check subsystem ID and set up device-specific initialization;
1473 * return 1 if initialized, 0 if invalid SSID
1474 */
1475/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1476 * 31 ~ 16 : Manufacture ID
1477 * 15 ~ 8 : SKU ID
1478 * 7 ~ 0 : Assembly ID
1479 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1480 */
1481static int alc_subsystem_id(struct hda_codec *codec,
1482 hda_nid_t porta, hda_nid_t porte,
6227cdce 1483 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1484{
1485 unsigned int ass, tmp, i;
1486 unsigned nid;
1487 struct alc_spec *spec = codec->spec;
1488
90622917
DH
1489 if (spec->cdefine.fixup) {
1490 ass = spec->cdefine.sku_cfg;
1491 if (ass == ALC_FIXUP_SKU_IGNORE)
1492 return 0;
1493 goto do_sku;
1494 }
1495
4a79ba34
TI
1496 ass = codec->subsystem_id & 0xffff;
1497 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1498 goto do_sku;
1499
1500 /* invalid SSID, check the special NID pin defcfg instead */
1501 /*
def319f9 1502 * 31~30 : port connectivity
4a79ba34
TI
1503 * 29~21 : reserve
1504 * 20 : PCBEEP input
1505 * 19~16 : Check sum (15:1)
1506 * 15~1 : Custom
1507 * 0 : override
1508 */
1509 nid = 0x1d;
1510 if (codec->vendor_id == 0x10ec0260)
1511 nid = 0x17;
1512 ass = snd_hda_codec_get_pincfg(codec, nid);
1513 snd_printd("realtek: No valid SSID, "
1514 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1515 ass, nid);
6227cdce 1516 if (!(ass & 1))
4a79ba34
TI
1517 return 0;
1518 if ((ass >> 30) != 1) /* no physical connection */
1519 return 0;
1520
1521 /* check sum */
1522 tmp = 0;
1523 for (i = 1; i < 16; i++) {
1524 if ((ass >> i) & 1)
1525 tmp++;
1526 }
1527 if (((ass >> 16) & 0xf) != tmp)
1528 return 0;
1529do_sku:
1530 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1531 ass & 0xffff, codec->vendor_id);
1532 /*
1533 * 0 : override
1534 * 1 : Swap Jack
1535 * 2 : 0 --> Desktop, 1 --> Laptop
1536 * 3~5 : External Amplifier control
1537 * 7~6 : Reserved
1538 */
1539 tmp = (ass & 0x38) >> 3; /* external Amp control */
1540 switch (tmp) {
1541 case 1:
1542 spec->init_amp = ALC_INIT_GPIO1;
1543 break;
1544 case 3:
1545 spec->init_amp = ALC_INIT_GPIO2;
1546 break;
1547 case 7:
1548 spec->init_amp = ALC_INIT_GPIO3;
1549 break;
1550 case 5:
5a8cfb4e 1551 default:
4a79ba34 1552 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1553 break;
1554 }
ea1fb29a 1555
8c427226 1556 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1557 * when the external headphone out jack is plugged"
1558 */
8c427226 1559 if (!(ass & 0x8000))
4a79ba34 1560 return 1;
c9b58006
KY
1561 /*
1562 * 10~8 : Jack location
1563 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1564 * 14~13: Resvered
1565 * 15 : 1 --> enable the function "Mute internal speaker
1566 * when the external headphone out jack is plugged"
1567 */
c9b58006 1568 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1569 hda_nid_t nid;
c9b58006
KY
1570 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1571 if (tmp == 0)
01d4825d 1572 nid = porta;
c9b58006 1573 else if (tmp == 1)
01d4825d 1574 nid = porte;
c9b58006 1575 else if (tmp == 2)
01d4825d 1576 nid = portd;
6227cdce
KY
1577 else if (tmp == 3)
1578 nid = porti;
c9b58006 1579 else
4a79ba34 1580 return 1;
01d4825d
TI
1581 for (i = 0; i < spec->autocfg.line_outs; i++)
1582 if (spec->autocfg.line_out_pins[i] == nid)
1583 return 1;
1584 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1585 }
1586
4a79ba34 1587 alc_init_auto_hp(codec);
6c819492 1588 alc_init_auto_mic(codec);
4a79ba34
TI
1589 return 1;
1590}
ea1fb29a 1591
4a79ba34 1592static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1593 hda_nid_t porta, hda_nid_t porte,
1594 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1595{
6227cdce 1596 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1597 struct alc_spec *spec = codec->spec;
1598 snd_printd("realtek: "
1599 "Enable default setup for auto mode as fallback\n");
1600 spec->init_amp = ALC_INIT_DEFAULT;
1601 alc_init_auto_hp(codec);
6c819492 1602 alc_init_auto_mic(codec);
4a79ba34 1603 }
bc9f98a9
KY
1604}
1605
f95474ec 1606/*
f8f25ba3 1607 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1608 */
1609
1610struct alc_pincfg {
1611 hda_nid_t nid;
1612 u32 val;
1613};
1614
e1eb5f10
TB
1615struct alc_model_fixup {
1616 const int id;
1617 const char *name;
1618};
1619
f8f25ba3 1620struct alc_fixup {
b5bfbc67 1621 int type;
361fe6e9
TI
1622 bool chained;
1623 int chain_id;
b5bfbc67
TI
1624 union {
1625 unsigned int sku;
1626 const struct alc_pincfg *pins;
1627 const struct hda_verb *verbs;
1628 void (*func)(struct hda_codec *codec,
1629 const struct alc_fixup *fix,
1630 int action);
1631 } v;
f8f25ba3
TI
1632};
1633
b5bfbc67
TI
1634enum {
1635 ALC_FIXUP_INVALID,
1636 ALC_FIXUP_SKU,
1637 ALC_FIXUP_PINS,
1638 ALC_FIXUP_VERBS,
1639 ALC_FIXUP_FUNC,
1640};
1641
1642enum {
1643 ALC_FIXUP_ACT_PRE_PROBE,
1644 ALC_FIXUP_ACT_PROBE,
58701120 1645 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1646};
1647
1648static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1649{
b5bfbc67
TI
1650 struct alc_spec *spec = codec->spec;
1651 int id = spec->fixup_id;
aa1d0c52 1652#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1653 const char *modelname = spec->fixup_name;
aa1d0c52 1654#endif
b5bfbc67 1655 int depth = 0;
f95474ec 1656
b5bfbc67
TI
1657 if (!spec->fixup_list)
1658 return;
1659
1660 while (id >= 0) {
1661 const struct alc_fixup *fix = spec->fixup_list + id;
1662 const struct alc_pincfg *cfg;
1663
1664 switch (fix->type) {
1665 case ALC_FIXUP_SKU:
1666 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1667 break;;
1668 snd_printdd(KERN_INFO "hda_codec: %s: "
1669 "Apply sku override for %s\n",
1670 codec->chip_name, modelname);
1671 spec->cdefine.sku_cfg = fix->v.sku;
1672 spec->cdefine.fixup = 1;
1673 break;
1674 case ALC_FIXUP_PINS:
1675 cfg = fix->v.pins;
1676 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1677 break;
1678 snd_printdd(KERN_INFO "hda_codec: %s: "
1679 "Apply pincfg for %s\n",
1680 codec->chip_name, modelname);
1681 for (; cfg->nid; cfg++)
1682 snd_hda_codec_set_pincfg(codec, cfg->nid,
1683 cfg->val);
1684 break;
1685 case ALC_FIXUP_VERBS:
1686 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1687 break;
1688 snd_printdd(KERN_INFO "hda_codec: %s: "
1689 "Apply fix-verbs for %s\n",
1690 codec->chip_name, modelname);
1691 add_verb(codec->spec, fix->v.verbs);
1692 break;
1693 case ALC_FIXUP_FUNC:
1694 if (!fix->v.func)
1695 break;
1696 snd_printdd(KERN_INFO "hda_codec: %s: "
1697 "Apply fix-func for %s\n",
1698 codec->chip_name, modelname);
1699 fix->v.func(codec, fix, action);
1700 break;
1701 default:
1702 snd_printk(KERN_ERR "hda_codec: %s: "
1703 "Invalid fixup type %d\n",
1704 codec->chip_name, fix->type);
1705 break;
1706 }
1707 if (!fix[id].chained)
1708 break;
1709 if (++depth > 10)
1710 break;
1711 id = fix[id].chain_id;
9d57883f 1712 }
f95474ec
TI
1713}
1714
e1eb5f10 1715static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1716 const struct alc_model_fixup *models,
1717 const struct snd_pci_quirk *quirk,
1718 const struct alc_fixup *fixlist)
e1eb5f10 1719{
b5bfbc67
TI
1720 struct alc_spec *spec = codec->spec;
1721 int id = -1;
1722 const char *name = NULL;
e1eb5f10 1723
e1eb5f10
TB
1724 if (codec->modelname && models) {
1725 while (models->name) {
1726 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
1727 id = models->id;
1728 name = models->name;
e1eb5f10
TB
1729 break;
1730 }
1731 models++;
1732 }
b5bfbc67
TI
1733 }
1734 if (id < 0) {
1735 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1736 if (quirk) {
1737 id = quirk->value;
1738#ifdef CONFIG_SND_DEBUG_VERBOSE
1739 name = quirk->name;
1740#endif
1741 }
1742 }
1743
1744 spec->fixup_id = id;
1745 if (id >= 0) {
1746 spec->fixup_list = fixlist;
1747 spec->fixup_name = name;
e1eb5f10 1748 }
f95474ec
TI
1749}
1750
274693f3
KY
1751static int alc_read_coef_idx(struct hda_codec *codec,
1752 unsigned int coef_idx)
1753{
1754 unsigned int val;
1755 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1756 coef_idx);
1757 val = snd_hda_codec_read(codec, 0x20, 0,
1758 AC_VERB_GET_PROC_COEF, 0);
1759 return val;
1760}
1761
977ddd6b
KY
1762static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1763 unsigned int coef_val)
1764{
1765 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1766 coef_idx);
1767 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1768 coef_val);
1769}
1770
757899ac
TI
1771/* set right pin controls for digital I/O */
1772static void alc_auto_init_digital(struct hda_codec *codec)
1773{
1774 struct alc_spec *spec = codec->spec;
1775 int i;
1776 hda_nid_t pin;
1777
1778 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1779 pin = spec->autocfg.dig_out_pins[i];
1780 if (pin) {
1781 snd_hda_codec_write(codec, pin, 0,
1782 AC_VERB_SET_PIN_WIDGET_CONTROL,
1783 PIN_OUT);
1784 }
1785 }
1786 pin = spec->autocfg.dig_in_pin;
1787 if (pin)
1788 snd_hda_codec_write(codec, pin, 0,
1789 AC_VERB_SET_PIN_WIDGET_CONTROL,
1790 PIN_IN);
1791}
1792
1793/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1794static void alc_auto_parse_digital(struct hda_codec *codec)
1795{
1796 struct alc_spec *spec = codec->spec;
1797 int i, err;
1798 hda_nid_t dig_nid;
1799
1800 /* support multiple SPDIFs; the secondary is set up as a slave */
1801 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1802 err = snd_hda_get_connections(codec,
1803 spec->autocfg.dig_out_pins[i],
1804 &dig_nid, 1);
1805 if (err < 0)
1806 continue;
1807 if (!i) {
1808 spec->multiout.dig_out_nid = dig_nid;
1809 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1810 } else {
1811 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1812 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1813 break;
1814 spec->slave_dig_outs[i - 1] = dig_nid;
1815 }
1816 }
1817
1818 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
1819 dig_nid = codec->start_nid;
1820 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1821 unsigned int wcaps = get_wcaps(codec, dig_nid);
1822 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1823 continue;
1824 if (!(wcaps & AC_WCAP_DIGITAL))
1825 continue;
1826 if (!(wcaps & AC_WCAP_CONN_LIST))
1827 continue;
1828 err = get_connection_index(codec, dig_nid,
1829 spec->autocfg.dig_in_pin);
1830 if (err >= 0) {
1831 spec->dig_in_nid = dig_nid;
1832 break;
1833 }
1834 }
757899ac
TI
1835 }
1836}
1837
ef8ef5fb
VP
1838/*
1839 * ALC888
1840 */
1841
1842/*
1843 * 2ch mode
1844 */
1845static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1846/* Mic-in jack as mic in */
1847 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1848 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1849/* Line-in jack as Line in */
1850 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1851 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1852/* Line-Out as Front */
1853 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1854 { } /* end */
1855};
1856
1857/*
1858 * 4ch mode
1859 */
1860static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1861/* Mic-in jack as mic in */
1862 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1863 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1864/* Line-in jack as Surround */
1865 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1866 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1867/* Line-Out as Front */
1868 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1869 { } /* end */
1870};
1871
1872/*
1873 * 6ch mode
1874 */
1875static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1876/* Mic-in jack as CLFE */
1877 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1878 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1879/* Line-in jack as Surround */
1880 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1881 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1882/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1883 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1884 { } /* end */
1885};
1886
1887/*
1888 * 8ch mode
1889 */
1890static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1891/* Mic-in jack as CLFE */
1892 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1893 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1894/* Line-in jack as Surround */
1895 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1896 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1897/* Line-Out as Side */
1898 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1899 { } /* end */
1900};
1901
1902static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1903 { 2, alc888_4ST_ch2_intel_init },
1904 { 4, alc888_4ST_ch4_intel_init },
1905 { 6, alc888_4ST_ch6_intel_init },
1906 { 8, alc888_4ST_ch8_intel_init },
1907};
1908
1909/*
1910 * ALC888 Fujitsu Siemens Amillo xa3530
1911 */
1912
1913static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1914/* Front Mic: set to PIN_IN (empty by default) */
1915 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1916/* Connect Internal HP to Front */
1917 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1918 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1919 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1920/* Connect Bass HP to Front */
1921 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1922 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1923 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1924/* Connect Line-Out side jack (SPDIF) to Side */
1925 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1926 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1927 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1928/* Connect Mic jack to CLFE */
1929 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1930 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1931 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1932/* Connect Line-in jack to Surround */
1933 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1934 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1935 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1936/* Connect HP out jack to Front */
1937 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1938 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1939 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1940/* Enable unsolicited event for HP jack and Line-out jack */
1941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1942 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1943 {}
1944};
1945
a9fd4f3f 1946static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1947{
bb35febd 1948 alc_automute_speaker(codec, 0);
ef8ef5fb
VP
1949}
1950
a9fd4f3f
TI
1951static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1952 unsigned int res)
ef8ef5fb 1953{
a9fd4f3f
TI
1954 if (codec->vendor_id == 0x10ec0880)
1955 res >>= 28;
1956 else
1957 res >>= 26;
1958 if (res == ALC880_HP_EVENT)
1959 alc_automute_amp(codec);
ef8ef5fb
VP
1960}
1961
4f5d1706 1962static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1963{
1964 struct alc_spec *spec = codec->spec;
1965
1966 spec->autocfg.hp_pins[0] = 0x15;
1967 spec->autocfg.speaker_pins[0] = 0x14;
1968 spec->autocfg.speaker_pins[1] = 0x16;
1969 spec->autocfg.speaker_pins[2] = 0x17;
1970 spec->autocfg.speaker_pins[3] = 0x19;
1971 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1972}
1973
1974static void alc889_intel_init_hook(struct hda_codec *codec)
1975{
1976 alc889_coef_init(codec);
4f5d1706 1977 alc_automute_amp(codec);
6732bd0d
WF
1978}
1979
4f5d1706 1980static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1981{
1982 struct alc_spec *spec = codec->spec;
1983
1984 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1985 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1986 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1987 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1988}
ef8ef5fb 1989
5b2d1eca
VP
1990/*
1991 * ALC888 Acer Aspire 4930G model
1992 */
1993
1994static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1995/* Front Mic: set to PIN_IN (empty by default) */
1996 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1997/* Unselect Front Mic by default in input mixer 3 */
1998 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1999/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2000 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2001/* Connect Internal HP to front */
2002 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2003 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2004 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2005/* Connect HP out to front */
2006 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2009 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2010 { }
2011};
2012
d2fd4b09
TV
2013/*
2014 * ALC888 Acer Aspire 6530G model
2015 */
2016
2017static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2018/* Route to built-in subwoofer as well as speakers */
2019 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2020 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2021 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2022 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2023/* Bias voltage on for external mic port */
2024 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2025/* Front Mic: set to PIN_IN (empty by default) */
2026 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2027/* Unselect Front Mic by default in input mixer 3 */
2028 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2029/* Enable unsolicited event for HP jack */
2030 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2031/* Enable speaker output */
2032 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2033 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2034 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2035/* Enable headphone output */
2036 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2037 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2038 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2039 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2040 { }
2041};
2042
d9477207
DK
2043/*
2044 *ALC888 Acer Aspire 7730G model
2045 */
2046
2047static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2048/* Bias voltage on for external mic port */
2049 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2050/* Front Mic: set to PIN_IN (empty by default) */
2051 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2052/* Unselect Front Mic by default in input mixer 3 */
2053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2054/* Enable unsolicited event for HP jack */
2055 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2056/* Enable speaker output */
2057 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2059 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2060/* Enable headphone output */
2061 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2063 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2064 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2065/*Enable internal subwoofer */
2066 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2067 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2068 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2069 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2070 { }
2071};
2072
3b315d70 2073/*
018df418 2074 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2075 */
2076
018df418 2077static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2078/* Front Mic: set to PIN_IN (empty by default) */
2079 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2080/* Unselect Front Mic by default in input mixer 3 */
2081 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2082/* Enable unsolicited event for HP jack */
2083 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2084/* Connect Internal Front to Front */
2085 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2086 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2087 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2088/* Connect Internal Rear to Rear */
2089 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2090 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2091 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2092/* Connect Internal CLFE to CLFE */
2093 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2094 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2095 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2096/* Connect HP out to Front */
018df418 2097 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2099 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2100/* Enable all DACs */
2101/* DAC DISABLE/MUTE 1? */
2102/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2103 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2104 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2105/* DAC DISABLE/MUTE 2? */
2106/* some bit here disables the other DACs. Init=0x4900 */
2107 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2108 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2109/* DMIC fix
2110 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2111 * which makes the stereo useless. However, either the mic or the ALC889
2112 * makes the signal become a difference/sum signal instead of standard
2113 * stereo, which is annoying. So instead we flip this bit which makes the
2114 * codec replicate the sum signal to both channels, turning it into a
2115 * normal mono mic.
2116 */
2117/* DMIC_CONTROL? Init value = 0x0001 */
2118 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2119 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2120 { }
2121};
2122
ef8ef5fb 2123static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2124 /* Front mic only available on one ADC */
2125 {
2126 .num_items = 4,
2127 .items = {
2128 { "Mic", 0x0 },
2129 { "Line", 0x2 },
2130 { "CD", 0x4 },
2131 { "Front Mic", 0xb },
2132 },
2133 },
2134 {
2135 .num_items = 3,
2136 .items = {
2137 { "Mic", 0x0 },
2138 { "Line", 0x2 },
2139 { "CD", 0x4 },
2140 },
2141 }
2142};
2143
d2fd4b09
TV
2144static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2145 /* Interal mic only available on one ADC */
2146 {
684a8842 2147 .num_items = 5,
d2fd4b09 2148 .items = {
8607f7c4 2149 { "Mic", 0x0 },
684a8842 2150 { "Line In", 0x2 },
d2fd4b09 2151 { "CD", 0x4 },
684a8842 2152 { "Input Mix", 0xa },
28c4edb7 2153 { "Internal Mic", 0xb },
d2fd4b09
TV
2154 },
2155 },
2156 {
684a8842 2157 .num_items = 4,
d2fd4b09 2158 .items = {
8607f7c4 2159 { "Mic", 0x0 },
684a8842 2160 { "Line In", 0x2 },
d2fd4b09 2161 { "CD", 0x4 },
684a8842 2162 { "Input Mix", 0xa },
d2fd4b09
TV
2163 },
2164 }
2165};
2166
018df418
HM
2167static struct hda_input_mux alc889_capture_sources[3] = {
2168 /* Digital mic only available on first "ADC" */
2169 {
2170 .num_items = 5,
2171 .items = {
2172 { "Mic", 0x0 },
2173 { "Line", 0x2 },
2174 { "CD", 0x4 },
2175 { "Front Mic", 0xb },
2176 { "Input Mix", 0xa },
2177 },
2178 },
2179 {
2180 .num_items = 4,
2181 .items = {
2182 { "Mic", 0x0 },
2183 { "Line", 0x2 },
2184 { "CD", 0x4 },
2185 { "Input Mix", 0xa },
2186 },
2187 },
2188 {
2189 .num_items = 4,
2190 .items = {
2191 { "Mic", 0x0 },
2192 { "Line", 0x2 },
2193 { "CD", 0x4 },
2194 { "Input Mix", 0xa },
2195 },
2196 }
2197};
2198
ef8ef5fb 2199static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2200 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2201 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2202 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2203 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2204 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2205 HDA_OUTPUT),
2206 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2207 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2208 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2209 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2210 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2211 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2212 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2213 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2214 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2215 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2216 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2217 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2218 { } /* end */
2219};
2220
460c92fa
ŁW
2221static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2222 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2223 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2224 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2225 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2226 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2227 HDA_OUTPUT),
786c51f9
ŁW
2228 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2229 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2230 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2231 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2232 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2233 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2234 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2235 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2236 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2237 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2238 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2239 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2240 { } /* end */
2241};
2242
556eea9a
HM
2243static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2244 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2245 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2246 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2247 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2248 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2249 HDA_OUTPUT),
2250 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2251 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2252 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2253 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2254 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2255 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2256 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2257 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2258 { } /* end */
2259};
2260
2261
4f5d1706 2262static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2263{
a9fd4f3f 2264 struct alc_spec *spec = codec->spec;
5b2d1eca 2265
a9fd4f3f
TI
2266 spec->autocfg.hp_pins[0] = 0x15;
2267 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2268 spec->autocfg.speaker_pins[1] = 0x16;
2269 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2270}
2271
4f5d1706 2272static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2273{
2274 struct alc_spec *spec = codec->spec;
2275
2276 spec->autocfg.hp_pins[0] = 0x15;
2277 spec->autocfg.speaker_pins[0] = 0x14;
2278 spec->autocfg.speaker_pins[1] = 0x16;
2279 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2280}
2281
d9477207
DK
2282static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2283{
2284 struct alc_spec *spec = codec->spec;
2285
2286 spec->autocfg.hp_pins[0] = 0x15;
2287 spec->autocfg.speaker_pins[0] = 0x14;
2288 spec->autocfg.speaker_pins[1] = 0x16;
2289 spec->autocfg.speaker_pins[2] = 0x17;
2290}
2291
4f5d1706 2292static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2293{
2294 struct alc_spec *spec = codec->spec;
2295
2296 spec->autocfg.hp_pins[0] = 0x15;
2297 spec->autocfg.speaker_pins[0] = 0x14;
2298 spec->autocfg.speaker_pins[1] = 0x16;
2299 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2300}
2301
1da177e4 2302/*
e9edcee0
TI
2303 * ALC880 3-stack model
2304 *
2305 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2306 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2307 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2308 */
2309
e9edcee0
TI
2310static hda_nid_t alc880_dac_nids[4] = {
2311 /* front, rear, clfe, rear_surr */
2312 0x02, 0x05, 0x04, 0x03
2313};
2314
2315static hda_nid_t alc880_adc_nids[3] = {
2316 /* ADC0-2 */
2317 0x07, 0x08, 0x09,
2318};
2319
2320/* The datasheet says the node 0x07 is connected from inputs,
2321 * but it shows zero connection in the real implementation on some devices.
df694daa 2322 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2323 */
e9edcee0
TI
2324static hda_nid_t alc880_adc_nids_alt[2] = {
2325 /* ADC1-2 */
2326 0x08, 0x09,
2327};
2328
2329#define ALC880_DIGOUT_NID 0x06
2330#define ALC880_DIGIN_NID 0x0a
2331
2332static struct hda_input_mux alc880_capture_source = {
2333 .num_items = 4,
2334 .items = {
2335 { "Mic", 0x0 },
2336 { "Front Mic", 0x3 },
2337 { "Line", 0x2 },
2338 { "CD", 0x4 },
2339 },
2340};
2341
2342/* channel source setting (2/6 channel selection for 3-stack) */
2343/* 2ch mode */
2344static struct hda_verb alc880_threestack_ch2_init[] = {
2345 /* set line-in to input, mute it */
2346 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2347 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2348 /* set mic-in to input vref 80%, mute it */
2349 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2350 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2351 { } /* end */
2352};
2353
2354/* 6ch mode */
2355static struct hda_verb alc880_threestack_ch6_init[] = {
2356 /* set line-in to output, unmute it */
2357 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2358 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2359 /* set mic-in to output, unmute it */
2360 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2361 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2362 { } /* end */
2363};
2364
d2a6d7dc 2365static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2366 { 2, alc880_threestack_ch2_init },
2367 { 6, alc880_threestack_ch6_init },
2368};
2369
c8b6bf9b 2370static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2371 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2372 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2373 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2374 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2375 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2376 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2377 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2378 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2379 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2380 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2381 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2382 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2383 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2386 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2387 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2388 {
2389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2390 .name = "Channel Mode",
df694daa
KY
2391 .info = alc_ch_mode_info,
2392 .get = alc_ch_mode_get,
2393 .put = alc_ch_mode_put,
e9edcee0
TI
2394 },
2395 { } /* end */
2396};
2397
2398/* capture mixer elements */
f9e336f6
TI
2399static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2400 struct snd_ctl_elem_info *uinfo)
2401{
2402 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2403 struct alc_spec *spec = codec->spec;
2404 int err;
1da177e4 2405
5a9e02e9 2406 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2407 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2408 HDA_INPUT);
2409 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2410 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2411 return err;
2412}
2413
2414static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2415 unsigned int size, unsigned int __user *tlv)
2416{
2417 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2418 struct alc_spec *spec = codec->spec;
2419 int err;
1da177e4 2420
5a9e02e9 2421 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2422 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2423 HDA_INPUT);
2424 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2425 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2426 return err;
2427}
2428
2429typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2430 struct snd_ctl_elem_value *ucontrol);
2431
2432static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2433 struct snd_ctl_elem_value *ucontrol,
2434 getput_call_t func)
2435{
2436 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2437 struct alc_spec *spec = codec->spec;
2438 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2439 int err;
2440
5a9e02e9 2441 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2442 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2443 3, 0, HDA_INPUT);
2444 err = func(kcontrol, ucontrol);
5a9e02e9 2445 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2446 return err;
2447}
2448
2449static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2450 struct snd_ctl_elem_value *ucontrol)
2451{
2452 return alc_cap_getput_caller(kcontrol, ucontrol,
2453 snd_hda_mixer_amp_volume_get);
2454}
2455
2456static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2457 struct snd_ctl_elem_value *ucontrol)
2458{
2459 return alc_cap_getput_caller(kcontrol, ucontrol,
2460 snd_hda_mixer_amp_volume_put);
2461}
2462
2463/* capture mixer elements */
2464#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2465
2466static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2467 struct snd_ctl_elem_value *ucontrol)
2468{
2469 return alc_cap_getput_caller(kcontrol, ucontrol,
2470 snd_hda_mixer_amp_switch_get);
2471}
2472
2473static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2474 struct snd_ctl_elem_value *ucontrol)
2475{
2476 return alc_cap_getput_caller(kcontrol, ucontrol,
2477 snd_hda_mixer_amp_switch_put);
2478}
2479
a23b688f 2480#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2481 { \
2482 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2483 .name = "Capture Switch", \
2484 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2485 .count = num, \
2486 .info = alc_cap_sw_info, \
2487 .get = alc_cap_sw_get, \
2488 .put = alc_cap_sw_put, \
2489 }, \
2490 { \
2491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2492 .name = "Capture Volume", \
2493 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2494 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2495 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2496 .count = num, \
2497 .info = alc_cap_vol_info, \
2498 .get = alc_cap_vol_get, \
2499 .put = alc_cap_vol_put, \
2500 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2501 }
2502
2503#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2504 { \
2505 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2506 /* .name = "Capture Source", */ \
2507 .name = "Input Source", \
2508 .count = num, \
2509 .info = alc_mux_enum_info, \
2510 .get = alc_mux_enum_get, \
2511 .put = alc_mux_enum_put, \
a23b688f
TI
2512 }
2513
2514#define DEFINE_CAPMIX(num) \
2515static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2516 _DEFINE_CAPMIX(num), \
2517 _DEFINE_CAPSRC(num), \
2518 { } /* end */ \
2519}
2520
2521#define DEFINE_CAPMIX_NOSRC(num) \
2522static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2523 _DEFINE_CAPMIX(num), \
2524 { } /* end */ \
f9e336f6
TI
2525}
2526
2527/* up to three ADCs */
2528DEFINE_CAPMIX(1);
2529DEFINE_CAPMIX(2);
2530DEFINE_CAPMIX(3);
a23b688f
TI
2531DEFINE_CAPMIX_NOSRC(1);
2532DEFINE_CAPMIX_NOSRC(2);
2533DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2534
2535/*
2536 * ALC880 5-stack model
2537 *
9c7f852e
TI
2538 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2539 * Side = 0x02 (0xd)
e9edcee0
TI
2540 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2541 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2542 */
2543
2544/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2545static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2546 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2547 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2548 { } /* end */
2549};
2550
e9edcee0
TI
2551/* channel source setting (6/8 channel selection for 5-stack) */
2552/* 6ch mode */
2553static struct hda_verb alc880_fivestack_ch6_init[] = {
2554 /* set line-in to input, mute it */
2555 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2556 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2557 { } /* end */
2558};
2559
e9edcee0
TI
2560/* 8ch mode */
2561static struct hda_verb alc880_fivestack_ch8_init[] = {
2562 /* set line-in to output, unmute it */
2563 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2564 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2565 { } /* end */
2566};
2567
d2a6d7dc 2568static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2569 { 6, alc880_fivestack_ch6_init },
2570 { 8, alc880_fivestack_ch8_init },
2571};
2572
2573
2574/*
2575 * ALC880 6-stack model
2576 *
9c7f852e
TI
2577 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2578 * Side = 0x05 (0x0f)
e9edcee0
TI
2579 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2580 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2581 */
2582
2583static hda_nid_t alc880_6st_dac_nids[4] = {
2584 /* front, rear, clfe, rear_surr */
2585 0x02, 0x03, 0x04, 0x05
f12ab1e0 2586};
e9edcee0
TI
2587
2588static struct hda_input_mux alc880_6stack_capture_source = {
2589 .num_items = 4,
2590 .items = {
2591 { "Mic", 0x0 },
2592 { "Front Mic", 0x1 },
2593 { "Line", 0x2 },
2594 { "CD", 0x4 },
2595 },
2596};
2597
2598/* fixed 8-channels */
d2a6d7dc 2599static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2600 { 8, NULL },
2601};
2602
c8b6bf9b 2603static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2604 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2605 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2606 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2607 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2608 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2609 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2610 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2611 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2612 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2613 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2614 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2615 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2616 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2617 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2618 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2619 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2620 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2621 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2622 {
2623 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2624 .name = "Channel Mode",
df694daa
KY
2625 .info = alc_ch_mode_info,
2626 .get = alc_ch_mode_get,
2627 .put = alc_ch_mode_put,
16ded525
TI
2628 },
2629 { } /* end */
2630};
2631
e9edcee0
TI
2632
2633/*
2634 * ALC880 W810 model
2635 *
2636 * W810 has rear IO for:
2637 * Front (DAC 02)
2638 * Surround (DAC 03)
2639 * Center/LFE (DAC 04)
2640 * Digital out (06)
2641 *
2642 * The system also has a pair of internal speakers, and a headphone jack.
2643 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2644 *
e9edcee0
TI
2645 * There is a variable resistor to control the speaker or headphone
2646 * volume. This is a hardware-only device without a software API.
2647 *
2648 * Plugging headphones in will disable the internal speakers. This is
2649 * implemented in hardware, not via the driver using jack sense. In
2650 * a similar fashion, plugging into the rear socket marked "front" will
2651 * disable both the speakers and headphones.
2652 *
2653 * For input, there's a microphone jack, and an "audio in" jack.
2654 * These may not do anything useful with this driver yet, because I
2655 * haven't setup any initialization verbs for these yet...
2656 */
2657
2658static hda_nid_t alc880_w810_dac_nids[3] = {
2659 /* front, rear/surround, clfe */
2660 0x02, 0x03, 0x04
16ded525
TI
2661};
2662
e9edcee0 2663/* fixed 6 channels */
d2a6d7dc 2664static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2665 { 6, NULL }
2666};
2667
2668/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2669static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2670 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2671 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2672 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2673 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2674 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2675 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2676 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2677 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2678 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2679 { } /* end */
2680};
2681
2682
2683/*
2684 * Z710V model
2685 *
2686 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2687 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2688 * Line = 0x1a
e9edcee0
TI
2689 */
2690
2691static hda_nid_t alc880_z71v_dac_nids[1] = {
2692 0x02
2693};
2694#define ALC880_Z71V_HP_DAC 0x03
2695
2696/* fixed 2 channels */
d2a6d7dc 2697static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2698 { 2, NULL }
2699};
2700
c8b6bf9b 2701static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2703 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2704 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2705 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2710 { } /* end */
2711};
2712
e9edcee0 2713
e9edcee0
TI
2714/*
2715 * ALC880 F1734 model
2716 *
2717 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2718 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2719 */
2720
2721static hda_nid_t alc880_f1734_dac_nids[1] = {
2722 0x03
2723};
2724#define ALC880_F1734_HP_DAC 0x02
2725
c8b6bf9b 2726static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2727 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2728 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2729 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2730 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2731 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2732 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2733 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2734 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2735 { } /* end */
2736};
2737
937b4160
TI
2738static struct hda_input_mux alc880_f1734_capture_source = {
2739 .num_items = 2,
2740 .items = {
2741 { "Mic", 0x1 },
2742 { "CD", 0x4 },
2743 },
2744};
2745
e9edcee0 2746
e9edcee0
TI
2747/*
2748 * ALC880 ASUS model
2749 *
2750 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2751 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2752 * Mic = 0x18, Line = 0x1a
2753 */
2754
2755#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2756#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2757
c8b6bf9b 2758static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2759 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2760 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2761 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2762 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2763 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2764 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2765 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2766 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2767 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2768 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2769 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2770 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2771 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2772 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2773 {
2774 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2775 .name = "Channel Mode",
df694daa
KY
2776 .info = alc_ch_mode_info,
2777 .get = alc_ch_mode_get,
2778 .put = alc_ch_mode_put,
16ded525
TI
2779 },
2780 { } /* end */
2781};
e9edcee0 2782
e9edcee0
TI
2783/*
2784 * ALC880 ASUS W1V model
2785 *
2786 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2787 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2788 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2789 */
2790
2791/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2792static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2793 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2794 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2795 { } /* end */
2796};
2797
df694daa
KY
2798/* TCL S700 */
2799static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2800 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2801 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2802 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2803 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2804 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2805 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2806 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2807 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2808 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2809 { } /* end */
2810};
2811
ccc656ce
KY
2812/* Uniwill */
2813static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2814 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2815 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2816 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2817 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2818 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2819 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2820 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2821 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2822 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2823 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2824 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2825 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2826 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2828 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2829 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2830 {
2831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2832 .name = "Channel Mode",
2833 .info = alc_ch_mode_info,
2834 .get = alc_ch_mode_get,
2835 .put = alc_ch_mode_put,
2836 },
2837 { } /* end */
2838};
2839
2cf9f0fc
TD
2840static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2841 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2842 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2843 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2844 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2845 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2846 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
2847 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2848 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
2849 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2850 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
2851 { } /* end */
2852};
2853
ccc656ce 2854static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2855 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2856 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2857 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2858 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2860 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2861 { } /* end */
2862};
2863
2134ea4f
TI
2864/*
2865 * virtual master controls
2866 */
2867
2868/*
2869 * slave controls for virtual master
2870 */
ea734963 2871static const char * const alc_slave_vols[] = {
2134ea4f
TI
2872 "Front Playback Volume",
2873 "Surround Playback Volume",
2874 "Center Playback Volume",
2875 "LFE Playback Volume",
2876 "Side Playback Volume",
2877 "Headphone Playback Volume",
2878 "Speaker Playback Volume",
2879 "Mono Playback Volume",
2134ea4f 2880 "Line-Out Playback Volume",
26f5df26 2881 "PCM Playback Volume",
2134ea4f
TI
2882 NULL,
2883};
2884
ea734963 2885static const char * const alc_slave_sws[] = {
2134ea4f
TI
2886 "Front Playback Switch",
2887 "Surround Playback Switch",
2888 "Center Playback Switch",
2889 "LFE Playback Switch",
2890 "Side Playback Switch",
2891 "Headphone Playback Switch",
2892 "Speaker Playback Switch",
2893 "Mono Playback Switch",
edb54a55 2894 "IEC958 Playback Switch",
23033b2b
TI
2895 "Line-Out Playback Switch",
2896 "PCM Playback Switch",
2134ea4f
TI
2897 NULL,
2898};
2899
1da177e4 2900/*
e9edcee0 2901 * build control elements
1da177e4 2902 */
603c4019 2903
5b0cb1d8
JK
2904#define NID_MAPPING (-1)
2905
2906#define SUBDEV_SPEAKER_ (0 << 6)
2907#define SUBDEV_HP_ (1 << 6)
2908#define SUBDEV_LINE_ (2 << 6)
2909#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2910#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2911#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2912
603c4019
TI
2913static void alc_free_kctls(struct hda_codec *codec);
2914
67d634c0 2915#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2916/* additional beep mixers; the actual parameters are overwritten at build */
2917static struct snd_kcontrol_new alc_beep_mixer[] = {
2918 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2919 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2920 { } /* end */
2921};
67d634c0 2922#endif
45bdd1c1 2923
1da177e4
LT
2924static int alc_build_controls(struct hda_codec *codec)
2925{
2926 struct alc_spec *spec = codec->spec;
2f44f847 2927 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2928 struct snd_kcontrol_new *knew;
2929 int i, j, err;
2930 unsigned int u;
2931 hda_nid_t nid;
1da177e4
LT
2932
2933 for (i = 0; i < spec->num_mixers; i++) {
2934 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2935 if (err < 0)
2936 return err;
2937 }
f9e336f6
TI
2938 if (spec->cap_mixer) {
2939 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2940 if (err < 0)
2941 return err;
2942 }
1da177e4 2943 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2944 err = snd_hda_create_spdif_out_ctls(codec,
2945 spec->multiout.dig_out_nid);
1da177e4
LT
2946 if (err < 0)
2947 return err;
e64f14f4
TI
2948 if (!spec->no_analog) {
2949 err = snd_hda_create_spdif_share_sw(codec,
2950 &spec->multiout);
2951 if (err < 0)
2952 return err;
2953 spec->multiout.share_spdif = 1;
2954 }
1da177e4
LT
2955 }
2956 if (spec->dig_in_nid) {
2957 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2958 if (err < 0)
2959 return err;
2960 }
2134ea4f 2961
67d634c0 2962#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2963 /* create beep controls if needed */
2964 if (spec->beep_amp) {
2965 struct snd_kcontrol_new *knew;
2966 for (knew = alc_beep_mixer; knew->name; knew++) {
2967 struct snd_kcontrol *kctl;
2968 kctl = snd_ctl_new1(knew, codec);
2969 if (!kctl)
2970 return -ENOMEM;
2971 kctl->private_value = spec->beep_amp;
5e26dfd0 2972 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2973 if (err < 0)
2974 return err;
2975 }
2976 }
67d634c0 2977#endif
45bdd1c1 2978
2134ea4f 2979 /* if we have no master control, let's create it */
e64f14f4
TI
2980 if (!spec->no_analog &&
2981 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2982 unsigned int vmaster_tlv[4];
2134ea4f 2983 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2984 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2985 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2986 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2987 if (err < 0)
2988 return err;
2989 }
e64f14f4
TI
2990 if (!spec->no_analog &&
2991 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2992 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2993 NULL, alc_slave_sws);
2994 if (err < 0)
2995 return err;
2996 }
2997
5b0cb1d8 2998 /* assign Capture Source enums to NID */
fbe618f2
TI
2999 if (spec->capsrc_nids || spec->adc_nids) {
3000 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3001 if (!kctl)
3002 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3003 for (i = 0; kctl && i < kctl->count; i++) {
3004 hda_nid_t *nids = spec->capsrc_nids;
3005 if (!nids)
3006 nids = spec->adc_nids;
3007 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3008 if (err < 0)
3009 return err;
3010 }
5b0cb1d8
JK
3011 }
3012 if (spec->cap_mixer) {
3013 const char *kname = kctl ? kctl->id.name : NULL;
3014 for (knew = spec->cap_mixer; knew->name; knew++) {
3015 if (kname && strcmp(knew->name, kname) == 0)
3016 continue;
3017 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3018 for (i = 0; kctl && i < kctl->count; i++) {
3019 err = snd_hda_add_nid(codec, kctl, i,
3020 spec->adc_nids[i]);
3021 if (err < 0)
3022 return err;
3023 }
3024 }
3025 }
3026
3027 /* other nid->control mapping */
3028 for (i = 0; i < spec->num_mixers; i++) {
3029 for (knew = spec->mixers[i]; knew->name; knew++) {
3030 if (knew->iface != NID_MAPPING)
3031 continue;
3032 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3033 if (kctl == NULL)
3034 continue;
3035 u = knew->subdevice;
3036 for (j = 0; j < 4; j++, u >>= 8) {
3037 nid = u & 0x3f;
3038 if (nid == 0)
3039 continue;
3040 switch (u & 0xc0) {
3041 case SUBDEV_SPEAKER_:
3042 nid = spec->autocfg.speaker_pins[nid];
3043 break;
3044 case SUBDEV_LINE_:
3045 nid = spec->autocfg.line_out_pins[nid];
3046 break;
3047 case SUBDEV_HP_:
3048 nid = spec->autocfg.hp_pins[nid];
3049 break;
3050 default:
3051 continue;
3052 }
3053 err = snd_hda_add_nid(codec, kctl, 0, nid);
3054 if (err < 0)
3055 return err;
3056 }
3057 u = knew->private_value;
3058 for (j = 0; j < 4; j++, u >>= 8) {
3059 nid = u & 0xff;
3060 if (nid == 0)
3061 continue;
3062 err = snd_hda_add_nid(codec, kctl, 0, nid);
3063 if (err < 0)
3064 return err;
3065 }
3066 }
3067 }
bae84e70
TI
3068
3069 alc_free_kctls(codec); /* no longer needed */
3070
1da177e4
LT
3071 return 0;
3072}
3073
e9edcee0 3074
1da177e4
LT
3075/*
3076 * initialize the codec volumes, etc
3077 */
3078
e9edcee0
TI
3079/*
3080 * generic initialization of ADC, input mixers and output mixers
3081 */
3082static struct hda_verb alc880_volume_init_verbs[] = {
3083 /*
3084 * Unmute ADC0-2 and set the default input to mic-in
3085 */
71fe7b82 3086 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3088 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3089 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3090 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3091 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3092
e9edcee0
TI
3093 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3094 * mixer widget
9c7f852e
TI
3095 * Note: PASD motherboards uses the Line In 2 as the input for front
3096 * panel mic (mic 2)
1da177e4 3097 */
e9edcee0 3098 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3106
e9edcee0
TI
3107 /*
3108 * Set up output mixers (0x0c - 0x0f)
1da177e4 3109 */
e9edcee0
TI
3110 /* set vol=0 to output mixers */
3111 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3112 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3113 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3114 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3115 /* set up input amps for analog loopback */
3116 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3123 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3124 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3125
3126 { }
3127};
3128
e9edcee0
TI
3129/*
3130 * 3-stack pin configuration:
3131 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3132 */
3133static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3134 /*
3135 * preset connection lists of input pins
3136 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3137 */
3138 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3139 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3140 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3141
3142 /*
3143 * Set pin mode and muting
3144 */
3145 /* set front pin widgets 0x14 for output */
05acb863 3146 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3147 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3148 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3149 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3150 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3151 /* Mic2 (as headphone out) for HP output */
3152 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3153 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3154 /* Line In pin widget for input */
05acb863 3155 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3156 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3157 /* Line2 (as front mic) pin widget for input and vref at 80% */
3158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3159 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3160 /* CD pin widget for input */
05acb863 3161 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3162
e9edcee0
TI
3163 { }
3164};
1da177e4 3165
e9edcee0
TI
3166/*
3167 * 5-stack pin configuration:
3168 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3169 * line-in/side = 0x1a, f-mic = 0x1b
3170 */
3171static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3172 /*
3173 * preset connection lists of input pins
3174 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3175 */
e9edcee0
TI
3176 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3177 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3178
e9edcee0
TI
3179 /*
3180 * Set pin mode and muting
1da177e4 3181 */
e9edcee0
TI
3182 /* set pin widgets 0x14-0x17 for output */
3183 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3184 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3185 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3186 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3187 /* unmute pins for output (no gain on this amp) */
3188 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3190 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3191 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3192
3193 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3194 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3195 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3196 /* Mic2 (as headphone out) for HP output */
3197 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3198 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3199 /* Line In pin widget for input */
3200 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3201 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3202 /* Line2 (as front mic) pin widget for input and vref at 80% */
3203 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3204 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3205 /* CD pin widget for input */
3206 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3207
3208 { }
3209};
3210
e9edcee0
TI
3211/*
3212 * W810 pin configuration:
3213 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3214 */
3215static struct hda_verb alc880_pin_w810_init_verbs[] = {
3216 /* hphone/speaker input selector: front DAC */
3217 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3218
05acb863 3219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3220 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3221 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3222 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3223 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3224 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3225
e9edcee0 3226 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3227 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3228
1da177e4
LT
3229 { }
3230};
3231
e9edcee0
TI
3232/*
3233 * Z71V pin configuration:
3234 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3235 */
3236static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3237 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3238 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3239 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3241
16ded525 3242 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3243 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3244 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3245 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3246
3247 { }
3248};
3249
e9edcee0
TI
3250/*
3251 * 6-stack pin configuration:
9c7f852e
TI
3252 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3253 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3254 */
3255static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3256 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3257
16ded525 3258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3259 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3260 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3261 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3262 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3263 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3264 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3265 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3266
16ded525 3267 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3268 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3269 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3270 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3271 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3272 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3274 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3275 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3276
e9edcee0
TI
3277 { }
3278};
3279
ccc656ce
KY
3280/*
3281 * Uniwill pin configuration:
3282 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3283 * line = 0x1a
3284 */
3285static struct hda_verb alc880_uniwill_init_verbs[] = {
3286 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3287
3288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3289 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3292 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3293 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3294 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3295 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3296 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3298 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3299 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3300 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3301 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3302
3303 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3304 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3305 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3306 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3307 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3308 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3309 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3310 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3311 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3312
3313 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3314 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3315
3316 { }
3317};
3318
3319/*
3320* Uniwill P53
ea1fb29a 3321* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3322 */
3323static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3324 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3325
3326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3328 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3329 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3330 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3331 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3334 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3335 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3336 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3337 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3338
3339 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3340 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3341 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3342 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3343 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3344 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3345
3346 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3347 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3348
3349 { }
3350};
3351
2cf9f0fc
TD
3352static struct hda_verb alc880_beep_init_verbs[] = {
3353 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3354 { }
3355};
3356
458a4fab 3357/* auto-toggle front mic */
eeb43387 3358static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3359{
3360 unsigned int present;
3361 unsigned char bits;
ccc656ce 3362
864f92be 3363 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3364 bits = present ? HDA_AMP_MUTE : 0;
3365 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3366}
3367
4f5d1706 3368static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3369{
a9fd4f3f
TI
3370 struct alc_spec *spec = codec->spec;
3371
3372 spec->autocfg.hp_pins[0] = 0x14;
3373 spec->autocfg.speaker_pins[0] = 0x15;
3374 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3375}
3376
3377static void alc880_uniwill_init_hook(struct hda_codec *codec)
3378{
a9fd4f3f 3379 alc_automute_amp(codec);
eeb43387 3380 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3381}
3382
3383static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3384 unsigned int res)
3385{
3386 /* Looks like the unsol event is incompatible with the standard
3387 * definition. 4bit tag is placed at 28 bit!
3388 */
458a4fab 3389 switch (res >> 28) {
458a4fab 3390 case ALC880_MIC_EVENT:
eeb43387 3391 alc88x_simple_mic_automute(codec);
458a4fab 3392 break;
a9fd4f3f
TI
3393 default:
3394 alc_automute_amp_unsol_event(codec, res);
3395 break;
458a4fab 3396 }
ccc656ce
KY
3397}
3398
4f5d1706 3399static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3400{
a9fd4f3f 3401 struct alc_spec *spec = codec->spec;
ccc656ce 3402
a9fd4f3f
TI
3403 spec->autocfg.hp_pins[0] = 0x14;
3404 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3405}
3406
3407static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3408{
3409 unsigned int present;
ea1fb29a 3410
ccc656ce 3411 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3412 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3413 present &= HDA_AMP_VOLMASK;
3414 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3415 HDA_AMP_VOLMASK, present);
3416 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3417 HDA_AMP_VOLMASK, present);
ccc656ce 3418}
47fd830a 3419
ccc656ce
KY
3420static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3421 unsigned int res)
3422{
3423 /* Looks like the unsol event is incompatible with the standard
3424 * definition. 4bit tag is placed at 28 bit!
3425 */
f12ab1e0 3426 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3427 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3428 else
3429 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3430}
3431
e9edcee0
TI
3432/*
3433 * F1734 pin configuration:
3434 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3435 */
3436static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3437 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3438 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3439 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3440 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3441 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3442
e9edcee0 3443 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3444 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3445 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3447
e9edcee0
TI
3448 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3449 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3450 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3451 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3453 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3454 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3455 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3456 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3457
937b4160
TI
3458 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3459 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3460
dfc0ff62
TI
3461 { }
3462};
3463
e9edcee0
TI
3464/*
3465 * ASUS pin configuration:
3466 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3467 */
3468static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3469 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3470 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3471 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3472 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3473
3474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3475 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3477 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3478 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3479 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3480 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3482
3483 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3485 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3487 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3488 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3489 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3490 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3491 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3492
e9edcee0
TI
3493 { }
3494};
16ded525 3495
e9edcee0 3496/* Enable GPIO mask and set output */
bc9f98a9
KY
3497#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3498#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3499#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3500
3501/* Clevo m520g init */
3502static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3503 /* headphone output */
3504 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3505 /* line-out */
3506 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3507 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3508 /* Line-in */
3509 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3510 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3511 /* CD */
3512 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3513 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3514 /* Mic1 (rear panel) */
3515 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3516 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3517 /* Mic2 (front panel) */
3518 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3519 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3520 /* headphone */
3521 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3522 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3523 /* change to EAPD mode */
3524 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3525 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3526
3527 { }
16ded525
TI
3528};
3529
df694daa 3530static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3531 /* change to EAPD mode */
3532 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3533 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3534
df694daa
KY
3535 /* Headphone output */
3536 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3537 /* Front output*/
3538 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3539 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3540
3541 /* Line In pin widget for input */
3542 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3543 /* CD pin widget for input */
3544 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3545 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3546 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3547
3548 /* change to EAPD mode */
3549 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3550 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3551
3552 { }
3553};
16ded525 3554
e9edcee0 3555/*
ae6b813a
TI
3556 * LG m1 express dual
3557 *
3558 * Pin assignment:
3559 * Rear Line-In/Out (blue): 0x14
3560 * Build-in Mic-In: 0x15
3561 * Speaker-out: 0x17
3562 * HP-Out (green): 0x1b
3563 * Mic-In/Out (red): 0x19
3564 * SPDIF-Out: 0x1e
3565 */
3566
3567/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3568static hda_nid_t alc880_lg_dac_nids[3] = {
3569 0x05, 0x02, 0x03
3570};
3571
3572/* seems analog CD is not working */
3573static struct hda_input_mux alc880_lg_capture_source = {
3574 .num_items = 3,
3575 .items = {
3576 { "Mic", 0x1 },
3577 { "Line", 0x5 },
3578 { "Internal Mic", 0x6 },
3579 },
3580};
3581
3582/* 2,4,6 channel modes */
3583static struct hda_verb alc880_lg_ch2_init[] = {
3584 /* set line-in and mic-in to input */
3585 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3586 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3587 { }
3588};
3589
3590static struct hda_verb alc880_lg_ch4_init[] = {
3591 /* set line-in to out and mic-in to input */
3592 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3593 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3594 { }
3595};
3596
3597static struct hda_verb alc880_lg_ch6_init[] = {
3598 /* set line-in and mic-in to output */
3599 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3600 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3601 { }
3602};
3603
3604static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3605 { 2, alc880_lg_ch2_init },
3606 { 4, alc880_lg_ch4_init },
3607 { 6, alc880_lg_ch6_init },
3608};
3609
3610static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3611 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3612 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3613 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3614 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3615 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3616 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3617 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3618 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3619 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3620 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3623 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3624 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3625 {
3626 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3627 .name = "Channel Mode",
3628 .info = alc_ch_mode_info,
3629 .get = alc_ch_mode_get,
3630 .put = alc_ch_mode_put,
3631 },
3632 { } /* end */
3633};
3634
3635static struct hda_verb alc880_lg_init_verbs[] = {
3636 /* set capture source to mic-in */
3637 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3638 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3639 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3640 /* mute all amp mixer inputs */
3641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3644 /* line-in to input */
3645 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3646 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3647 /* built-in mic */
3648 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3650 /* speaker-out */
3651 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3652 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3653 /* mic-in to input */
3654 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3655 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3656 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3657 /* HP-out */
3658 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3660 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3661 /* jack sense */
a9fd4f3f 3662 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3663 { }
3664};
3665
3666/* toggle speaker-output according to the hp-jack state */
4f5d1706 3667static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3668{
a9fd4f3f 3669 struct alc_spec *spec = codec->spec;
ae6b813a 3670
a9fd4f3f
TI
3671 spec->autocfg.hp_pins[0] = 0x1b;
3672 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3673}
3674
d681518a
TI
3675/*
3676 * LG LW20
3677 *
3678 * Pin assignment:
3679 * Speaker-out: 0x14
3680 * Mic-In: 0x18
e4f41da9
CM
3681 * Built-in Mic-In: 0x19
3682 * Line-In: 0x1b
3683 * HP-Out: 0x1a
d681518a
TI
3684 * SPDIF-Out: 0x1e
3685 */
3686
d681518a 3687static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3688 .num_items = 3,
d681518a
TI
3689 .items = {
3690 { "Mic", 0x0 },
3691 { "Internal Mic", 0x1 },
e4f41da9 3692 { "Line In", 0x2 },
d681518a
TI
3693 },
3694};
3695
0a8c5da3
CM
3696#define alc880_lg_lw_modes alc880_threestack_modes
3697
d681518a 3698static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3699 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3700 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3701 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3702 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3703 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3704 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3705 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3706 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3707 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3708 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3711 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3712 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3713 {
3714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3715 .name = "Channel Mode",
3716 .info = alc_ch_mode_info,
3717 .get = alc_ch_mode_get,
3718 .put = alc_ch_mode_put,
3719 },
d681518a
TI
3720 { } /* end */
3721};
3722
3723static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3724 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3725 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3726 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3727
d681518a
TI
3728 /* set capture source to mic-in */
3729 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3730 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3731 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3732 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3733 /* speaker-out */
3734 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3735 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3736 /* HP-out */
d681518a
TI
3737 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3738 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3739 /* mic-in to input */
3740 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3741 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3742 /* built-in mic */
3743 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3744 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3745 /* jack sense */
a9fd4f3f 3746 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3747 { }
3748};
3749
3750/* toggle speaker-output according to the hp-jack state */
4f5d1706 3751static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3752{
a9fd4f3f 3753 struct alc_spec *spec = codec->spec;
d681518a 3754
a9fd4f3f
TI
3755 spec->autocfg.hp_pins[0] = 0x1b;
3756 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3757}
3758
df99cd33
TI
3759static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3760 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3761 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3762 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3763 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3764 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3765 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3766 { } /* end */
3767};
3768
3769static struct hda_input_mux alc880_medion_rim_capture_source = {
3770 .num_items = 2,
3771 .items = {
3772 { "Mic", 0x0 },
3773 { "Internal Mic", 0x1 },
3774 },
3775};
3776
3777static struct hda_verb alc880_medion_rim_init_verbs[] = {
3778 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3779
3780 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3781 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3782
3783 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3784 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3785 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3786 /* Mic2 (as headphone out) for HP output */
3787 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3788 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3789 /* Internal Speaker */
3790 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3791 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3792
3793 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3794 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3795
3796 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3797 { }
3798};
3799
3800/* toggle speaker-output according to the hp-jack state */
3801static void alc880_medion_rim_automute(struct hda_codec *codec)
3802{
a9fd4f3f
TI
3803 struct alc_spec *spec = codec->spec;
3804 alc_automute_amp(codec);
3805 /* toggle EAPD */
3806 if (spec->jack_present)
df99cd33
TI
3807 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3808 else
3809 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3810}
3811
3812static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3813 unsigned int res)
3814{
3815 /* Looks like the unsol event is incompatible with the standard
3816 * definition. 4bit tag is placed at 28 bit!
3817 */
3818 if ((res >> 28) == ALC880_HP_EVENT)
3819 alc880_medion_rim_automute(codec);
3820}
3821
4f5d1706 3822static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3823{
3824 struct alc_spec *spec = codec->spec;
3825
3826 spec->autocfg.hp_pins[0] = 0x14;
3827 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3828}
3829
cb53c626
TI
3830#ifdef CONFIG_SND_HDA_POWER_SAVE
3831static struct hda_amp_list alc880_loopbacks[] = {
3832 { 0x0b, HDA_INPUT, 0 },
3833 { 0x0b, HDA_INPUT, 1 },
3834 { 0x0b, HDA_INPUT, 2 },
3835 { 0x0b, HDA_INPUT, 3 },
3836 { 0x0b, HDA_INPUT, 4 },
3837 { } /* end */
3838};
3839
3840static struct hda_amp_list alc880_lg_loopbacks[] = {
3841 { 0x0b, HDA_INPUT, 1 },
3842 { 0x0b, HDA_INPUT, 6 },
3843 { 0x0b, HDA_INPUT, 7 },
3844 { } /* end */
3845};
3846#endif
3847
ae6b813a
TI
3848/*
3849 * Common callbacks
e9edcee0
TI
3850 */
3851
584c0c4c
TI
3852static void alc_init_special_input_src(struct hda_codec *codec);
3853
1da177e4
LT
3854static int alc_init(struct hda_codec *codec)
3855{
3856 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3857 unsigned int i;
3858
2c3bf9ab 3859 alc_fix_pll(codec);
4a79ba34 3860 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3861
e9edcee0
TI
3862 for (i = 0; i < spec->num_init_verbs; i++)
3863 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 3864 alc_init_special_input_src(codec);
ae6b813a
TI
3865
3866 if (spec->init_hook)
3867 spec->init_hook(codec);
3868
58701120
TI
3869 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
3870
9e5341b9 3871 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
3872 return 0;
3873}
3874
ae6b813a
TI
3875static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3876{
3877 struct alc_spec *spec = codec->spec;
3878
3879 if (spec->unsol_event)
3880 spec->unsol_event(codec, res);
3881}
3882
cb53c626
TI
3883#ifdef CONFIG_SND_HDA_POWER_SAVE
3884static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3885{
3886 struct alc_spec *spec = codec->spec;
3887 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3888}
3889#endif
3890
1da177e4
LT
3891/*
3892 * Analog playback callbacks
3893 */
3894static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3895 struct hda_codec *codec,
c8b6bf9b 3896 struct snd_pcm_substream *substream)
1da177e4
LT
3897{
3898 struct alc_spec *spec = codec->spec;
9a08160b
TI
3899 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3900 hinfo);
1da177e4
LT
3901}
3902
3903static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3904 struct hda_codec *codec,
3905 unsigned int stream_tag,
3906 unsigned int format,
c8b6bf9b 3907 struct snd_pcm_substream *substream)
1da177e4
LT
3908{
3909 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3910 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3911 stream_tag, format, substream);
1da177e4
LT
3912}
3913
3914static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3915 struct hda_codec *codec,
c8b6bf9b 3916 struct snd_pcm_substream *substream)
1da177e4
LT
3917{
3918 struct alc_spec *spec = codec->spec;
3919 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3920}
3921
3922/*
3923 * Digital out
3924 */
3925static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3926 struct hda_codec *codec,
c8b6bf9b 3927 struct snd_pcm_substream *substream)
1da177e4
LT
3928{
3929 struct alc_spec *spec = codec->spec;
3930 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3931}
3932
6b97eb45
TI
3933static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3934 struct hda_codec *codec,
3935 unsigned int stream_tag,
3936 unsigned int format,
3937 struct snd_pcm_substream *substream)
3938{
3939 struct alc_spec *spec = codec->spec;
3940 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3941 stream_tag, format, substream);
3942}
3943
9b5f12e5
TI
3944static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3945 struct hda_codec *codec,
3946 struct snd_pcm_substream *substream)
3947{
3948 struct alc_spec *spec = codec->spec;
3949 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3950}
3951
1da177e4
LT
3952static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3953 struct hda_codec *codec,
c8b6bf9b 3954 struct snd_pcm_substream *substream)
1da177e4
LT
3955{
3956 struct alc_spec *spec = codec->spec;
3957 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3958}
3959
3960/*
3961 * Analog capture
3962 */
6330079f 3963static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3964 struct hda_codec *codec,
3965 unsigned int stream_tag,
3966 unsigned int format,
c8b6bf9b 3967 struct snd_pcm_substream *substream)
1da177e4
LT
3968{
3969 struct alc_spec *spec = codec->spec;
3970
6330079f 3971 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3972 stream_tag, 0, format);
3973 return 0;
3974}
3975
6330079f 3976static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3977 struct hda_codec *codec,
c8b6bf9b 3978 struct snd_pcm_substream *substream)
1da177e4
LT
3979{
3980 struct alc_spec *spec = codec->spec;
3981
888afa15
TI
3982 snd_hda_codec_cleanup_stream(codec,
3983 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3984 return 0;
3985}
3986
840b64c0
TI
3987/* analog capture with dynamic dual-adc changes */
3988static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3989 struct hda_codec *codec,
3990 unsigned int stream_tag,
3991 unsigned int format,
3992 struct snd_pcm_substream *substream)
3993{
3994 struct alc_spec *spec = codec->spec;
3995 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3996 spec->cur_adc_stream_tag = stream_tag;
3997 spec->cur_adc_format = format;
3998 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3999 return 0;
4000}
4001
4002static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4003 struct hda_codec *codec,
4004 struct snd_pcm_substream *substream)
4005{
4006 struct alc_spec *spec = codec->spec;
4007 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4008 spec->cur_adc = 0;
4009 return 0;
4010}
4011
4012static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4013 .substreams = 1,
4014 .channels_min = 2,
4015 .channels_max = 2,
4016 .nid = 0, /* fill later */
4017 .ops = {
4018 .prepare = dualmic_capture_pcm_prepare,
4019 .cleanup = dualmic_capture_pcm_cleanup
4020 },
4021};
1da177e4
LT
4022
4023/*
4024 */
4025static struct hda_pcm_stream alc880_pcm_analog_playback = {
4026 .substreams = 1,
4027 .channels_min = 2,
4028 .channels_max = 8,
e9edcee0 4029 /* NID is set in alc_build_pcms */
1da177e4
LT
4030 .ops = {
4031 .open = alc880_playback_pcm_open,
4032 .prepare = alc880_playback_pcm_prepare,
4033 .cleanup = alc880_playback_pcm_cleanup
4034 },
4035};
4036
4037static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4038 .substreams = 1,
4039 .channels_min = 2,
4040 .channels_max = 2,
4041 /* NID is set in alc_build_pcms */
4042};
4043
4044static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4045 .substreams = 1,
4046 .channels_min = 2,
4047 .channels_max = 2,
4048 /* NID is set in alc_build_pcms */
4049};
4050
4051static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4052 .substreams = 2, /* can be overridden */
1da177e4
LT
4053 .channels_min = 2,
4054 .channels_max = 2,
e9edcee0 4055 /* NID is set in alc_build_pcms */
1da177e4 4056 .ops = {
6330079f
TI
4057 .prepare = alc880_alt_capture_pcm_prepare,
4058 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4059 },
4060};
4061
4062static struct hda_pcm_stream alc880_pcm_digital_playback = {
4063 .substreams = 1,
4064 .channels_min = 2,
4065 .channels_max = 2,
4066 /* NID is set in alc_build_pcms */
4067 .ops = {
4068 .open = alc880_dig_playback_pcm_open,
6b97eb45 4069 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4070 .prepare = alc880_dig_playback_pcm_prepare,
4071 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4072 },
4073};
4074
4075static struct hda_pcm_stream alc880_pcm_digital_capture = {
4076 .substreams = 1,
4077 .channels_min = 2,
4078 .channels_max = 2,
4079 /* NID is set in alc_build_pcms */
4080};
4081
4c5186ed 4082/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 4083static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4084 .substreams = 0,
4085 .channels_min = 0,
4086 .channels_max = 0,
4087};
4088
1da177e4
LT
4089static int alc_build_pcms(struct hda_codec *codec)
4090{
4091 struct alc_spec *spec = codec->spec;
4092 struct hda_pcm *info = spec->pcm_rec;
4093 int i;
4094
4095 codec->num_pcms = 1;
4096 codec->pcm_info = info;
4097
e64f14f4
TI
4098 if (spec->no_analog)
4099 goto skip_analog;
4100
812a2cca
TI
4101 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4102 "%s Analog", codec->chip_name);
1da177e4 4103 info->name = spec->stream_name_analog;
274693f3 4104
4a471b7d 4105 if (spec->stream_analog_playback) {
da3cec35
TI
4106 if (snd_BUG_ON(!spec->multiout.dac_nids))
4107 return -EINVAL;
4a471b7d
TI
4108 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4109 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4110 }
4111 if (spec->stream_analog_capture) {
da3cec35
TI
4112 if (snd_BUG_ON(!spec->adc_nids))
4113 return -EINVAL;
4a471b7d
TI
4114 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4115 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4116 }
4117
4118 if (spec->channel_mode) {
4119 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4120 for (i = 0; i < spec->num_channel_mode; i++) {
4121 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4122 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4123 }
1da177e4
LT
4124 }
4125 }
4126
e64f14f4 4127 skip_analog:
e08a007d 4128 /* SPDIF for stream index #1 */
1da177e4 4129 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4130 snprintf(spec->stream_name_digital,
4131 sizeof(spec->stream_name_digital),
4132 "%s Digital", codec->chip_name);
e08a007d 4133 codec->num_pcms = 2;
b25c9da1 4134 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4135 info = spec->pcm_rec + 1;
1da177e4 4136 info->name = spec->stream_name_digital;
8c441982
TI
4137 if (spec->dig_out_type)
4138 info->pcm_type = spec->dig_out_type;
4139 else
4140 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4141 if (spec->multiout.dig_out_nid &&
4142 spec->stream_digital_playback) {
1da177e4
LT
4143 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4144 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4145 }
4a471b7d
TI
4146 if (spec->dig_in_nid &&
4147 spec->stream_digital_capture) {
1da177e4
LT
4148 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4149 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4150 }
963f803f
TI
4151 /* FIXME: do we need this for all Realtek codec models? */
4152 codec->spdif_status_reset = 1;
1da177e4
LT
4153 }
4154
e64f14f4
TI
4155 if (spec->no_analog)
4156 return 0;
4157
e08a007d
TI
4158 /* If the use of more than one ADC is requested for the current
4159 * model, configure a second analog capture-only PCM.
4160 */
4161 /* Additional Analaog capture for index #2 */
6330079f
TI
4162 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4163 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4164 codec->num_pcms = 3;
c06134d7 4165 info = spec->pcm_rec + 2;
e08a007d 4166 info->name = spec->stream_name_analog;
6330079f
TI
4167 if (spec->alt_dac_nid) {
4168 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4169 *spec->stream_analog_alt_playback;
4170 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4171 spec->alt_dac_nid;
4172 } else {
4173 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4174 alc_pcm_null_stream;
4175 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4176 }
4177 if (spec->num_adc_nids > 1) {
4178 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4179 *spec->stream_analog_alt_capture;
4180 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4181 spec->adc_nids[1];
4182 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4183 spec->num_adc_nids - 1;
4184 } else {
4185 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4186 alc_pcm_null_stream;
4187 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4188 }
4189 }
4190
1da177e4
LT
4191 return 0;
4192}
4193
a4e09aa3
TI
4194static inline void alc_shutup(struct hda_codec *codec)
4195{
4196 snd_hda_shutup_pins(codec);
4197}
4198
603c4019
TI
4199static void alc_free_kctls(struct hda_codec *codec)
4200{
4201 struct alc_spec *spec = codec->spec;
4202
4203 if (spec->kctls.list) {
4204 struct snd_kcontrol_new *kctl = spec->kctls.list;
4205 int i;
4206 for (i = 0; i < spec->kctls.used; i++)
4207 kfree(kctl[i].name);
4208 }
4209 snd_array_free(&spec->kctls);
4210}
4211
1da177e4
LT
4212static void alc_free(struct hda_codec *codec)
4213{
e9edcee0 4214 struct alc_spec *spec = codec->spec;
e9edcee0 4215
f12ab1e0 4216 if (!spec)
e9edcee0
TI
4217 return;
4218
a4e09aa3 4219 alc_shutup(codec);
cd372fb3 4220 snd_hda_input_jack_free(codec);
603c4019 4221 alc_free_kctls(codec);
e9edcee0 4222 kfree(spec);
680cd536 4223 snd_hda_detach_beep_device(codec);
1da177e4
LT
4224}
4225
f5de24b0 4226#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4227static void alc_power_eapd(struct hda_codec *codec)
4228{
4229 /* We currently only handle front, HP */
4230 switch (codec->vendor_id) {
4231 case 0x10ec0260:
9e4c8496
TI
4232 set_eapd(codec, 0x0f, 0);
4233 set_eapd(codec, 0x10, 0);
c97259df
DC
4234 break;
4235 case 0x10ec0262:
4236 case 0x10ec0267:
4237 case 0x10ec0268:
4238 case 0x10ec0269:
9e4c8496 4239 case 0x10ec0270:
c97259df
DC
4240 case 0x10ec0272:
4241 case 0x10ec0660:
4242 case 0x10ec0662:
4243 case 0x10ec0663:
75eb1c31 4244 case 0x10ec0665:
c97259df
DC
4245 case 0x10ec0862:
4246 case 0x10ec0889:
9e4c8496
TI
4247 set_eapd(codec, 0x14, 0);
4248 set_eapd(codec, 0x15, 0);
c97259df
DC
4249 break;
4250 }
4251}
4252
f5de24b0
HM
4253static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4254{
4255 struct alc_spec *spec = codec->spec;
a4e09aa3 4256 alc_shutup(codec);
f5de24b0 4257 if (spec && spec->power_hook)
c97259df 4258 spec->power_hook(codec);
f5de24b0
HM
4259 return 0;
4260}
4261#endif
4262
e044c39a 4263#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4264static int alc_resume(struct hda_codec *codec)
4265{
e044c39a
TI
4266 codec->patch_ops.init(codec);
4267 snd_hda_codec_resume_amp(codec);
4268 snd_hda_codec_resume_cache(codec);
9e5341b9 4269 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4270 return 0;
4271}
e044c39a
TI
4272#endif
4273
1da177e4
LT
4274/*
4275 */
4276static struct hda_codec_ops alc_patch_ops = {
4277 .build_controls = alc_build_controls,
4278 .build_pcms = alc_build_pcms,
4279 .init = alc_init,
4280 .free = alc_free,
ae6b813a 4281 .unsol_event = alc_unsol_event,
e044c39a
TI
4282#ifdef SND_HDA_NEEDS_RESUME
4283 .resume = alc_resume,
4284#endif
cb53c626 4285#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4286 .suspend = alc_suspend,
cb53c626
TI
4287 .check_power_status = alc_check_power_status,
4288#endif
c97259df 4289 .reboot_notify = alc_shutup,
1da177e4
LT
4290};
4291
c027ddcd
KY
4292/* replace the codec chip_name with the given string */
4293static int alc_codec_rename(struct hda_codec *codec, const char *name)
4294{
4295 kfree(codec->chip_name);
4296 codec->chip_name = kstrdup(name, GFP_KERNEL);
4297 if (!codec->chip_name) {
4298 alc_free(codec);
4299 return -ENOMEM;
4300 }
4301 return 0;
4302}
4303
2fa522be
TI
4304/*
4305 * Test configuration for debugging
4306 *
4307 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4308 * enum controls.
4309 */
4310#ifdef CONFIG_SND_DEBUG
4311static hda_nid_t alc880_test_dac_nids[4] = {
4312 0x02, 0x03, 0x04, 0x05
4313};
4314
4315static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4316 .num_items = 7,
2fa522be
TI
4317 .items = {
4318 { "In-1", 0x0 },
4319 { "In-2", 0x1 },
4320 { "In-3", 0x2 },
4321 { "In-4", 0x3 },
4322 { "CD", 0x4 },
ae6b813a
TI
4323 { "Front", 0x5 },
4324 { "Surround", 0x6 },
2fa522be
TI
4325 },
4326};
4327
d2a6d7dc 4328static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4329 { 2, NULL },
fd2c326d 4330 { 4, NULL },
2fa522be 4331 { 6, NULL },
fd2c326d 4332 { 8, NULL },
2fa522be
TI
4333};
4334
9c7f852e
TI
4335static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4336 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4337{
4338 static char *texts[] = {
4339 "N/A", "Line Out", "HP Out",
4340 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4341 };
4342 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4343 uinfo->count = 1;
4344 uinfo->value.enumerated.items = 8;
4345 if (uinfo->value.enumerated.item >= 8)
4346 uinfo->value.enumerated.item = 7;
4347 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4348 return 0;
4349}
4350
9c7f852e
TI
4351static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4352 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4353{
4354 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4355 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4356 unsigned int pin_ctl, item = 0;
4357
4358 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4359 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4360 if (pin_ctl & AC_PINCTL_OUT_EN) {
4361 if (pin_ctl & AC_PINCTL_HP_EN)
4362 item = 2;
4363 else
4364 item = 1;
4365 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4366 switch (pin_ctl & AC_PINCTL_VREFEN) {
4367 case AC_PINCTL_VREF_HIZ: item = 3; break;
4368 case AC_PINCTL_VREF_50: item = 4; break;
4369 case AC_PINCTL_VREF_GRD: item = 5; break;
4370 case AC_PINCTL_VREF_80: item = 6; break;
4371 case AC_PINCTL_VREF_100: item = 7; break;
4372 }
4373 }
4374 ucontrol->value.enumerated.item[0] = item;
4375 return 0;
4376}
4377
9c7f852e
TI
4378static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4379 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4380{
4381 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4382 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4383 static unsigned int ctls[] = {
4384 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4385 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4386 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4387 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4388 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4389 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4390 };
4391 unsigned int old_ctl, new_ctl;
4392
4393 old_ctl = snd_hda_codec_read(codec, nid, 0,
4394 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4395 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4396 if (old_ctl != new_ctl) {
82beb8fd
TI
4397 int val;
4398 snd_hda_codec_write_cache(codec, nid, 0,
4399 AC_VERB_SET_PIN_WIDGET_CONTROL,
4400 new_ctl);
47fd830a
TI
4401 val = ucontrol->value.enumerated.item[0] >= 3 ?
4402 HDA_AMP_MUTE : 0;
4403 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4404 HDA_AMP_MUTE, val);
2fa522be
TI
4405 return 1;
4406 }
4407 return 0;
4408}
4409
9c7f852e
TI
4410static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4411 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4412{
4413 static char *texts[] = {
4414 "Front", "Surround", "CLFE", "Side"
4415 };
4416 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4417 uinfo->count = 1;
4418 uinfo->value.enumerated.items = 4;
4419 if (uinfo->value.enumerated.item >= 4)
4420 uinfo->value.enumerated.item = 3;
4421 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4422 return 0;
4423}
4424
9c7f852e
TI
4425static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4426 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4427{
4428 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4429 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4430 unsigned int sel;
4431
4432 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4433 ucontrol->value.enumerated.item[0] = sel & 3;
4434 return 0;
4435}
4436
9c7f852e
TI
4437static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4438 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4439{
4440 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4441 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4442 unsigned int sel;
4443
4444 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4445 if (ucontrol->value.enumerated.item[0] != sel) {
4446 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4447 snd_hda_codec_write_cache(codec, nid, 0,
4448 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4449 return 1;
4450 }
4451 return 0;
4452}
4453
4454#define PIN_CTL_TEST(xname,nid) { \
4455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4456 .name = xname, \
5b0cb1d8 4457 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4458 .info = alc_test_pin_ctl_info, \
4459 .get = alc_test_pin_ctl_get, \
4460 .put = alc_test_pin_ctl_put, \
4461 .private_value = nid \
4462 }
4463
4464#define PIN_SRC_TEST(xname,nid) { \
4465 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4466 .name = xname, \
5b0cb1d8 4467 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4468 .info = alc_test_pin_src_info, \
4469 .get = alc_test_pin_src_get, \
4470 .put = alc_test_pin_src_put, \
4471 .private_value = nid \
4472 }
4473
c8b6bf9b 4474static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4475 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4476 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4477 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4478 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4479 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4480 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4481 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4482 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4483 PIN_CTL_TEST("Front Pin Mode", 0x14),
4484 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4485 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4486 PIN_CTL_TEST("Side Pin Mode", 0x17),
4487 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4488 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4489 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4490 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4491 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4492 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4493 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4494 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4495 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4496 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4497 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4498 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4499 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4500 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4501 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4502 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4503 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4504 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4505 {
4506 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4507 .name = "Channel Mode",
df694daa
KY
4508 .info = alc_ch_mode_info,
4509 .get = alc_ch_mode_get,
4510 .put = alc_ch_mode_put,
2fa522be
TI
4511 },
4512 { } /* end */
4513};
4514
4515static struct hda_verb alc880_test_init_verbs[] = {
4516 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4519 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4520 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4521 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4522 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4523 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4524 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4525 /* Vol output for 0x0c-0x0f */
05acb863
TI
4526 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4527 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4528 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4529 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4530 /* Set output pins 0x14-0x17 */
05acb863
TI
4531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4532 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4533 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4534 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4535 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4536 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4537 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4538 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4539 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4540 /* Set input pins 0x18-0x1c */
16ded525
TI
4541 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4542 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4544 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4545 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4546 /* Mute input pins 0x18-0x1b */
05acb863
TI
4547 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4548 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4549 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4550 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4551 /* ADC set up */
05acb863 4552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4553 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4555 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4556 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4557 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4558 /* Analog input/passthru */
4559 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4560 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4561 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4562 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4563 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4564 { }
4565};
4566#endif
4567
1da177e4
LT
4568/*
4569 */
4570
ea734963 4571static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4572 [ALC880_3ST] = "3stack",
4573 [ALC880_TCL_S700] = "tcl",
4574 [ALC880_3ST_DIG] = "3stack-digout",
4575 [ALC880_CLEVO] = "clevo",
4576 [ALC880_5ST] = "5stack",
4577 [ALC880_5ST_DIG] = "5stack-digout",
4578 [ALC880_W810] = "w810",
4579 [ALC880_Z71V] = "z71v",
4580 [ALC880_6ST] = "6stack",
4581 [ALC880_6ST_DIG] = "6stack-digout",
4582 [ALC880_ASUS] = "asus",
4583 [ALC880_ASUS_W1V] = "asus-w1v",
4584 [ALC880_ASUS_DIG] = "asus-dig",
4585 [ALC880_ASUS_DIG2] = "asus-dig2",
4586 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4587 [ALC880_UNIWILL_P53] = "uniwill-p53",
4588 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4589 [ALC880_F1734] = "F1734",
4590 [ALC880_LG] = "lg",
4591 [ALC880_LG_LW] = "lg-lw",
df99cd33 4592 [ALC880_MEDION_RIM] = "medion",
2fa522be 4593#ifdef CONFIG_SND_DEBUG
f5fcc13c 4594 [ALC880_TEST] = "test",
2fa522be 4595#endif
f5fcc13c
TI
4596 [ALC880_AUTO] = "auto",
4597};
4598
4599static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4600 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4601 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4602 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4603 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4604 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4605 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4606 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4607 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4608 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4609 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4610 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4611 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4612 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4613 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4614 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4615 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4616 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4617 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4618 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4619 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4620 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4621 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4622 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4623 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4624 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4625 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4626 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4627 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4628 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4629 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4630 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4631 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4632 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4633 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4634 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4635 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4636 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4637 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4638 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4639 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4640 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
4641 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4642 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4643 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4644 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4645 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4646 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4647 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4648 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4649 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4650 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4651 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4652 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4653 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4654 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4655 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4656 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4657 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4658 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4659 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4660 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4661 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4662 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4663 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4664 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4665 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4666 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4667 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4668 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4669 /* default Intel */
4670 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4671 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4672 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4673 {}
4674};
4675
16ded525 4676/*
df694daa 4677 * ALC880 codec presets
16ded525 4678 */
16ded525
TI
4679static struct alc_config_preset alc880_presets[] = {
4680 [ALC880_3ST] = {
e9edcee0 4681 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4682 .init_verbs = { alc880_volume_init_verbs,
4683 alc880_pin_3stack_init_verbs },
16ded525 4684 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4685 .dac_nids = alc880_dac_nids,
16ded525
TI
4686 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4687 .channel_mode = alc880_threestack_modes,
4e195a7b 4688 .need_dac_fix = 1,
16ded525
TI
4689 .input_mux = &alc880_capture_source,
4690 },
4691 [ALC880_3ST_DIG] = {
e9edcee0 4692 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4693 .init_verbs = { alc880_volume_init_verbs,
4694 alc880_pin_3stack_init_verbs },
16ded525 4695 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4696 .dac_nids = alc880_dac_nids,
4697 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4698 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4699 .channel_mode = alc880_threestack_modes,
4e195a7b 4700 .need_dac_fix = 1,
16ded525
TI
4701 .input_mux = &alc880_capture_source,
4702 },
df694daa
KY
4703 [ALC880_TCL_S700] = {
4704 .mixers = { alc880_tcl_s700_mixer },
4705 .init_verbs = { alc880_volume_init_verbs,
4706 alc880_pin_tcl_S700_init_verbs,
4707 alc880_gpio2_init_verbs },
4708 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4709 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4710 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4711 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4712 .hp_nid = 0x03,
4713 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4714 .channel_mode = alc880_2_jack_modes,
4715 .input_mux = &alc880_capture_source,
4716 },
16ded525 4717 [ALC880_5ST] = {
f12ab1e0
TI
4718 .mixers = { alc880_three_stack_mixer,
4719 alc880_five_stack_mixer},
4720 .init_verbs = { alc880_volume_init_verbs,
4721 alc880_pin_5stack_init_verbs },
16ded525
TI
4722 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4723 .dac_nids = alc880_dac_nids,
16ded525
TI
4724 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4725 .channel_mode = alc880_fivestack_modes,
4726 .input_mux = &alc880_capture_source,
4727 },
4728 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4729 .mixers = { alc880_three_stack_mixer,
4730 alc880_five_stack_mixer },
4731 .init_verbs = { alc880_volume_init_verbs,
4732 alc880_pin_5stack_init_verbs },
16ded525
TI
4733 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4734 .dac_nids = alc880_dac_nids,
4735 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4736 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4737 .channel_mode = alc880_fivestack_modes,
4738 .input_mux = &alc880_capture_source,
4739 },
b6482d48
TI
4740 [ALC880_6ST] = {
4741 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4742 .init_verbs = { alc880_volume_init_verbs,
4743 alc880_pin_6stack_init_verbs },
b6482d48
TI
4744 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4745 .dac_nids = alc880_6st_dac_nids,
4746 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4747 .channel_mode = alc880_sixstack_modes,
4748 .input_mux = &alc880_6stack_capture_source,
4749 },
16ded525 4750 [ALC880_6ST_DIG] = {
e9edcee0 4751 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4752 .init_verbs = { alc880_volume_init_verbs,
4753 alc880_pin_6stack_init_verbs },
16ded525
TI
4754 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4755 .dac_nids = alc880_6st_dac_nids,
4756 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4757 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4758 .channel_mode = alc880_sixstack_modes,
4759 .input_mux = &alc880_6stack_capture_source,
4760 },
4761 [ALC880_W810] = {
e9edcee0 4762 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4763 .init_verbs = { alc880_volume_init_verbs,
4764 alc880_pin_w810_init_verbs,
b0af0de5 4765 alc880_gpio2_init_verbs },
16ded525
TI
4766 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4767 .dac_nids = alc880_w810_dac_nids,
4768 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4769 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4770 .channel_mode = alc880_w810_modes,
4771 .input_mux = &alc880_capture_source,
4772 },
4773 [ALC880_Z71V] = {
e9edcee0 4774 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4775 .init_verbs = { alc880_volume_init_verbs,
4776 alc880_pin_z71v_init_verbs },
16ded525
TI
4777 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4778 .dac_nids = alc880_z71v_dac_nids,
4779 .dig_out_nid = ALC880_DIGOUT_NID,
4780 .hp_nid = 0x03,
e9edcee0
TI
4781 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4782 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4783 .input_mux = &alc880_capture_source,
4784 },
4785 [ALC880_F1734] = {
e9edcee0 4786 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4787 .init_verbs = { alc880_volume_init_verbs,
4788 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4789 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4790 .dac_nids = alc880_f1734_dac_nids,
4791 .hp_nid = 0x02,
4792 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4793 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4794 .input_mux = &alc880_f1734_capture_source,
4795 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4796 .setup = alc880_uniwill_p53_setup,
4797 .init_hook = alc_automute_amp,
16ded525
TI
4798 },
4799 [ALC880_ASUS] = {
e9edcee0 4800 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4801 .init_verbs = { alc880_volume_init_verbs,
4802 alc880_pin_asus_init_verbs,
e9edcee0
TI
4803 alc880_gpio1_init_verbs },
4804 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4805 .dac_nids = alc880_asus_dac_nids,
4806 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4807 .channel_mode = alc880_asus_modes,
4e195a7b 4808 .need_dac_fix = 1,
16ded525
TI
4809 .input_mux = &alc880_capture_source,
4810 },
4811 [ALC880_ASUS_DIG] = {
e9edcee0 4812 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4813 .init_verbs = { alc880_volume_init_verbs,
4814 alc880_pin_asus_init_verbs,
e9edcee0
TI
4815 alc880_gpio1_init_verbs },
4816 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4817 .dac_nids = alc880_asus_dac_nids,
16ded525 4818 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4819 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4820 .channel_mode = alc880_asus_modes,
4e195a7b 4821 .need_dac_fix = 1,
16ded525
TI
4822 .input_mux = &alc880_capture_source,
4823 },
df694daa
KY
4824 [ALC880_ASUS_DIG2] = {
4825 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4826 .init_verbs = { alc880_volume_init_verbs,
4827 alc880_pin_asus_init_verbs,
df694daa
KY
4828 alc880_gpio2_init_verbs }, /* use GPIO2 */
4829 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4830 .dac_nids = alc880_asus_dac_nids,
4831 .dig_out_nid = ALC880_DIGOUT_NID,
4832 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4833 .channel_mode = alc880_asus_modes,
4e195a7b 4834 .need_dac_fix = 1,
df694daa
KY
4835 .input_mux = &alc880_capture_source,
4836 },
16ded525 4837 [ALC880_ASUS_W1V] = {
e9edcee0 4838 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4839 .init_verbs = { alc880_volume_init_verbs,
4840 alc880_pin_asus_init_verbs,
e9edcee0
TI
4841 alc880_gpio1_init_verbs },
4842 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4843 .dac_nids = alc880_asus_dac_nids,
16ded525 4844 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4845 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4846 .channel_mode = alc880_asus_modes,
4e195a7b 4847 .need_dac_fix = 1,
16ded525
TI
4848 .input_mux = &alc880_capture_source,
4849 },
4850 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4851 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4852 .init_verbs = { alc880_volume_init_verbs,
4853 alc880_pin_asus_init_verbs },
e9edcee0
TI
4854 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4855 .dac_nids = alc880_asus_dac_nids,
16ded525 4856 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4857 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4858 .channel_mode = alc880_asus_modes,
4e195a7b 4859 .need_dac_fix = 1,
16ded525
TI
4860 .input_mux = &alc880_capture_source,
4861 },
ccc656ce
KY
4862 [ALC880_UNIWILL] = {
4863 .mixers = { alc880_uniwill_mixer },
4864 .init_verbs = { alc880_volume_init_verbs,
4865 alc880_uniwill_init_verbs },
4866 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4867 .dac_nids = alc880_asus_dac_nids,
4868 .dig_out_nid = ALC880_DIGOUT_NID,
4869 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4870 .channel_mode = alc880_threestack_modes,
4871 .need_dac_fix = 1,
4872 .input_mux = &alc880_capture_source,
4873 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4874 .setup = alc880_uniwill_setup,
a9fd4f3f 4875 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4876 },
4877 [ALC880_UNIWILL_P53] = {
4878 .mixers = { alc880_uniwill_p53_mixer },
4879 .init_verbs = { alc880_volume_init_verbs,
4880 alc880_uniwill_p53_init_verbs },
4881 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4882 .dac_nids = alc880_asus_dac_nids,
4883 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4884 .channel_mode = alc880_threestack_modes,
4885 .input_mux = &alc880_capture_source,
4886 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4887 .setup = alc880_uniwill_p53_setup,
4888 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4889 },
4890 [ALC880_FUJITSU] = {
45bdd1c1 4891 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4892 .init_verbs = { alc880_volume_init_verbs,
4893 alc880_uniwill_p53_init_verbs,
4894 alc880_beep_init_verbs },
4895 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4896 .dac_nids = alc880_dac_nids,
d53d7d9e 4897 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4898 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4899 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4900 .input_mux = &alc880_capture_source,
4901 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4902 .setup = alc880_uniwill_p53_setup,
4903 .init_hook = alc_automute_amp,
ccc656ce 4904 },
df694daa
KY
4905 [ALC880_CLEVO] = {
4906 .mixers = { alc880_three_stack_mixer },
4907 .init_verbs = { alc880_volume_init_verbs,
4908 alc880_pin_clevo_init_verbs },
4909 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4910 .dac_nids = alc880_dac_nids,
4911 .hp_nid = 0x03,
4912 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4913 .channel_mode = alc880_threestack_modes,
4e195a7b 4914 .need_dac_fix = 1,
df694daa
KY
4915 .input_mux = &alc880_capture_source,
4916 },
ae6b813a
TI
4917 [ALC880_LG] = {
4918 .mixers = { alc880_lg_mixer },
4919 .init_verbs = { alc880_volume_init_verbs,
4920 alc880_lg_init_verbs },
4921 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4922 .dac_nids = alc880_lg_dac_nids,
4923 .dig_out_nid = ALC880_DIGOUT_NID,
4924 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4925 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4926 .need_dac_fix = 1,
ae6b813a 4927 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4928 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4929 .setup = alc880_lg_setup,
4930 .init_hook = alc_automute_amp,
cb53c626
TI
4931#ifdef CONFIG_SND_HDA_POWER_SAVE
4932 .loopbacks = alc880_lg_loopbacks,
4933#endif
ae6b813a 4934 },
d681518a
TI
4935 [ALC880_LG_LW] = {
4936 .mixers = { alc880_lg_lw_mixer },
4937 .init_verbs = { alc880_volume_init_verbs,
4938 alc880_lg_lw_init_verbs },
0a8c5da3 4939 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4940 .dac_nids = alc880_dac_nids,
4941 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4942 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4943 .channel_mode = alc880_lg_lw_modes,
d681518a 4944 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4945 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4946 .setup = alc880_lg_lw_setup,
4947 .init_hook = alc_automute_amp,
d681518a 4948 },
df99cd33
TI
4949 [ALC880_MEDION_RIM] = {
4950 .mixers = { alc880_medion_rim_mixer },
4951 .init_verbs = { alc880_volume_init_verbs,
4952 alc880_medion_rim_init_verbs,
4953 alc_gpio2_init_verbs },
4954 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4955 .dac_nids = alc880_dac_nids,
4956 .dig_out_nid = ALC880_DIGOUT_NID,
4957 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4958 .channel_mode = alc880_2_jack_modes,
4959 .input_mux = &alc880_medion_rim_capture_source,
4960 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4961 .setup = alc880_medion_rim_setup,
4962 .init_hook = alc880_medion_rim_automute,
df99cd33 4963 },
16ded525
TI
4964#ifdef CONFIG_SND_DEBUG
4965 [ALC880_TEST] = {
e9edcee0
TI
4966 .mixers = { alc880_test_mixer },
4967 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4968 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4969 .dac_nids = alc880_test_dac_nids,
4970 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4971 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4972 .channel_mode = alc880_test_modes,
4973 .input_mux = &alc880_test_capture_source,
4974 },
4975#endif
4976};
4977
e9edcee0
TI
4978/*
4979 * Automatic parse of I/O pins from the BIOS configuration
4980 */
4981
e9edcee0
TI
4982enum {
4983 ALC_CTL_WIDGET_VOL,
4984 ALC_CTL_WIDGET_MUTE,
4985 ALC_CTL_BIND_MUTE,
4986};
c8b6bf9b 4987static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4988 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4989 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4990 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4991};
4992
4993/* add dynamic controls */
f12ab1e0 4994static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 4995 int cidx, unsigned long val)
e9edcee0 4996{
c8b6bf9b 4997 struct snd_kcontrol_new *knew;
e9edcee0 4998
603c4019
TI
4999 snd_array_init(&spec->kctls, sizeof(*knew), 32);
5000 knew = snd_array_new(&spec->kctls);
5001 if (!knew)
5002 return -ENOMEM;
e9edcee0 5003 *knew = alc880_control_templates[type];
543537bd 5004 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5005 if (!knew->name)
e9edcee0 5006 return -ENOMEM;
66ceeb6b 5007 knew->index = cidx;
4d02d1b6 5008 if (get_amp_nid_(val))
5e26dfd0 5009 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5010 knew->private_value = val;
e9edcee0
TI
5011 return 0;
5012}
5013
0afe5f89
TI
5014static int add_control_with_pfx(struct alc_spec *spec, int type,
5015 const char *pfx, const char *dir,
66ceeb6b 5016 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5017{
5018 char name[32];
5019 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5020 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5021}
5022
66ceeb6b
TI
5023#define add_pb_vol_ctrl(spec, type, pfx, val) \
5024 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5025#define add_pb_sw_ctrl(spec, type, pfx, val) \
5026 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5027#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5028 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5029#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5030 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5031
e9edcee0
TI
5032#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5033#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5034#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5035#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5036#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5037#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5038#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5039#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5040#define ALC880_PIN_CD_NID 0x1c
5041
5042/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5043static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5044 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5045{
5046 hda_nid_t nid;
5047 int assigned[4];
5048 int i, j;
5049
5050 memset(assigned, 0, sizeof(assigned));
b0af0de5 5051 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5052
5053 /* check the pins hardwired to audio widget */
5054 for (i = 0; i < cfg->line_outs; i++) {
5055 nid = cfg->line_out_pins[i];
5056 if (alc880_is_fixed_pin(nid)) {
5057 int idx = alc880_fixed_pin_idx(nid);
5014f193 5058 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5059 assigned[idx] = 1;
5060 }
5061 }
5062 /* left pins can be connect to any audio widget */
5063 for (i = 0; i < cfg->line_outs; i++) {
5064 nid = cfg->line_out_pins[i];
5065 if (alc880_is_fixed_pin(nid))
5066 continue;
5067 /* search for an empty channel */
5068 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
5069 if (!assigned[j]) {
5070 spec->multiout.dac_nids[i] =
5071 alc880_idx_to_dac(j);
e9edcee0
TI
5072 assigned[j] = 1;
5073 break;
5074 }
5075 }
5076 }
5077 spec->multiout.num_dacs = cfg->line_outs;
5078 return 0;
5079}
5080
bcb2f0f5
TI
5081static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5082 bool can_be_master)
5083{
5084 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5085 return "Master";
5086
5087 switch (cfg->line_out_type) {
5088 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5089 if (cfg->line_outs == 1)
5090 return "Speaker";
5091 break;
bcb2f0f5
TI
5092 case AUTO_PIN_HP_OUT:
5093 return "Headphone";
5094 default:
5095 if (cfg->line_outs == 1)
5096 return "PCM";
5097 break;
5098 }
5099 return NULL;
5100}
5101
e9edcee0 5102/* add playback controls from the parsed DAC table */
df694daa
KY
5103static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5104 const struct auto_pin_cfg *cfg)
e9edcee0 5105{
ea734963 5106 static const char * const chname[4] = {
f12ab1e0
TI
5107 "Front", "Surround", NULL /*CLFE*/, "Side"
5108 };
bcb2f0f5 5109 const char *pfx = alc_get_line_out_pfx(cfg, false);
e9edcee0
TI
5110 hda_nid_t nid;
5111 int i, err;
5112
5113 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 5114 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5115 continue;
5116 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5117 if (!pfx && i == 2) {
e9edcee0 5118 /* Center/LFE */
0afe5f89
TI
5119 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5120 "Center",
f12ab1e0
TI
5121 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5122 HDA_OUTPUT));
5123 if (err < 0)
e9edcee0 5124 return err;
0afe5f89
TI
5125 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5126 "LFE",
f12ab1e0
TI
5127 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5128 HDA_OUTPUT));
5129 if (err < 0)
e9edcee0 5130 return err;
0afe5f89
TI
5131 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5132 "Center",
f12ab1e0
TI
5133 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5134 HDA_INPUT));
5135 if (err < 0)
e9edcee0 5136 return err;
0afe5f89
TI
5137 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5138 "LFE",
f12ab1e0
TI
5139 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5140 HDA_INPUT));
5141 if (err < 0)
e9edcee0
TI
5142 return err;
5143 } else {
bcb2f0f5 5144 const char *name = pfx;
7e59e097
DH
5145 int index = i;
5146 if (!name) {
bcb2f0f5 5147 name = chname[i];
7e59e097
DH
5148 index = 0;
5149 }
bcb2f0f5 5150 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5151 name, index,
f12ab1e0
TI
5152 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5153 HDA_OUTPUT));
5154 if (err < 0)
e9edcee0 5155 return err;
bcb2f0f5 5156 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5157 name, index,
f12ab1e0
TI
5158 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5159 HDA_INPUT));
5160 if (err < 0)
e9edcee0
TI
5161 return err;
5162 }
5163 }
e9edcee0
TI
5164 return 0;
5165}
5166
8d88bc3d
TI
5167/* add playback controls for speaker and HP outputs */
5168static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5169 const char *pfx)
e9edcee0
TI
5170{
5171 hda_nid_t nid;
5172 int err;
5173
f12ab1e0 5174 if (!pin)
e9edcee0
TI
5175 return 0;
5176
5177 if (alc880_is_fixed_pin(pin)) {
5178 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5179 /* specify the DAC as the extra output */
f12ab1e0 5180 if (!spec->multiout.hp_nid)
e9edcee0 5181 spec->multiout.hp_nid = nid;
82bc955f
TI
5182 else
5183 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5184 /* control HP volume/switch on the output mixer amp */
5185 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5186 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5187 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5188 if (err < 0)
e9edcee0 5189 return err;
0afe5f89 5190 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5191 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5192 if (err < 0)
e9edcee0
TI
5193 return err;
5194 } else if (alc880_is_multi_pin(pin)) {
5195 /* set manual connection */
e9edcee0 5196 /* we have only a switch on HP-out PIN */
0afe5f89 5197 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5198 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5199 if (err < 0)
e9edcee0
TI
5200 return err;
5201 }
5202 return 0;
5203}
5204
5205/* create input playback/capture controls for the given pin */
f12ab1e0 5206static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5207 const char *ctlname, int ctlidx,
df694daa 5208 int idx, hda_nid_t mix_nid)
e9edcee0 5209{
df694daa 5210 int err;
e9edcee0 5211
66ceeb6b 5212 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5213 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5214 if (err < 0)
e9edcee0 5215 return err;
66ceeb6b 5216 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5217 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5218 if (err < 0)
e9edcee0
TI
5219 return err;
5220 return 0;
5221}
5222
05f5f477
TI
5223static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5224{
5225 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5226 return (pincap & AC_PINCAP_IN) != 0;
5227}
5228
e9edcee0 5229/* create playback/capture controls for input pins */
05f5f477
TI
5230static int alc_auto_create_input_ctls(struct hda_codec *codec,
5231 const struct auto_pin_cfg *cfg,
5232 hda_nid_t mixer,
5233 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5234{
05f5f477 5235 struct alc_spec *spec = codec->spec;
61b9b9b1 5236 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5237 int i, err, idx, type_idx = 0;
5238 const char *prev_label = NULL;
e9edcee0 5239
66ceeb6b 5240 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5241 hda_nid_t pin;
10a20af7 5242 const char *label;
05f5f477 5243
66ceeb6b 5244 pin = cfg->inputs[i].pin;
05f5f477
TI
5245 if (!alc_is_input_pin(codec, pin))
5246 continue;
5247
5322bf27
DH
5248 label = hda_get_autocfg_input_label(codec, cfg, i);
5249 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5250 type_idx++;
5251 else
5252 type_idx = 0;
5322bf27
DH
5253 prev_label = label;
5254
05f5f477
TI
5255 if (mixer) {
5256 idx = get_connection_index(codec, mixer, pin);
5257 if (idx >= 0) {
5258 err = new_analog_input(spec, pin,
10a20af7
TI
5259 label, type_idx,
5260 idx, mixer);
05f5f477
TI
5261 if (err < 0)
5262 return err;
5263 }
5264 }
5265
5266 if (!cap1)
5267 continue;
5268 idx = get_connection_index(codec, cap1, pin);
5269 if (idx < 0 && cap2)
5270 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5271 if (idx >= 0)
5272 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5273 }
5274 return 0;
5275}
5276
05f5f477
TI
5277static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5278 const struct auto_pin_cfg *cfg)
5279{
5280 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5281}
5282
f6c7e546
TI
5283static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5284 unsigned int pin_type)
5285{
5286 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5287 pin_type);
5288 /* unmute pin */
d260cdf6
TI
5289 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5290 AMP_OUT_UNMUTE);
f6c7e546
TI
5291}
5292
df694daa
KY
5293static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5294 hda_nid_t nid, int pin_type,
e9edcee0
TI
5295 int dac_idx)
5296{
f6c7e546 5297 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5298 /* need the manual connection? */
5299 if (alc880_is_multi_pin(nid)) {
5300 struct alc_spec *spec = codec->spec;
5301 int idx = alc880_multi_pin_idx(nid);
5302 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5303 AC_VERB_SET_CONNECT_SEL,
5304 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5305 }
5306}
5307
baba8ee9
TI
5308static int get_pin_type(int line_out_type)
5309{
5310 if (line_out_type == AUTO_PIN_HP_OUT)
5311 return PIN_HP;
5312 else
5313 return PIN_OUT;
5314}
5315
e9edcee0
TI
5316static void alc880_auto_init_multi_out(struct hda_codec *codec)
5317{
5318 struct alc_spec *spec = codec->spec;
5319 int i;
ea1fb29a 5320
e9edcee0
TI
5321 for (i = 0; i < spec->autocfg.line_outs; i++) {
5322 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5323 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5324 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5325 }
5326}
5327
8d88bc3d 5328static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5329{
5330 struct alc_spec *spec = codec->spec;
5331 hda_nid_t pin;
5332
82bc955f 5333 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5334 if (pin) /* connect to front */
5335 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5336 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5337 if (pin) /* connect to front */
5338 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5339}
5340
5341static void alc880_auto_init_analog_input(struct hda_codec *codec)
5342{
5343 struct alc_spec *spec = codec->spec;
66ceeb6b 5344 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5345 int i;
5346
66ceeb6b
TI
5347 for (i = 0; i < cfg->num_inputs; i++) {
5348 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5349 if (alc_is_input_pin(codec, nid)) {
30ea098f 5350 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5351 if (nid != ALC880_PIN_CD_NID &&
5352 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5353 snd_hda_codec_write(codec, nid, 0,
5354 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5355 AMP_OUT_MUTE);
5356 }
5357 }
5358}
5359
7f311a46
TI
5360static void alc880_auto_init_input_src(struct hda_codec *codec)
5361{
5362 struct alc_spec *spec = codec->spec;
5363 int c;
5364
5365 for (c = 0; c < spec->num_adc_nids; c++) {
5366 unsigned int mux_idx;
5367 const struct hda_input_mux *imux;
5368 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5369 imux = &spec->input_mux[mux_idx];
5370 if (!imux->num_items && mux_idx > 0)
5371 imux = &spec->input_mux[0];
5372 if (imux)
5373 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5374 AC_VERB_SET_CONNECT_SEL,
5375 imux->items[0].index);
5376 }
5377}
5378
e9edcee0 5379/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5380/* return 1 if successful, 0 if the proper config is not found,
5381 * or a negative error code
5382 */
e9edcee0
TI
5383static int alc880_parse_auto_config(struct hda_codec *codec)
5384{
5385 struct alc_spec *spec = codec->spec;
757899ac 5386 int err;
df694daa 5387 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5388
f12ab1e0
TI
5389 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5390 alc880_ignore);
5391 if (err < 0)
e9edcee0 5392 return err;
f12ab1e0 5393 if (!spec->autocfg.line_outs)
e9edcee0 5394 return 0; /* can't find valid BIOS pin config */
df694daa 5395
f12ab1e0
TI
5396 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5397 if (err < 0)
5398 return err;
5399 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5400 if (err < 0)
5401 return err;
5402 err = alc880_auto_create_extra_out(spec,
5403 spec->autocfg.speaker_pins[0],
5404 "Speaker");
5405 if (err < 0)
5406 return err;
5407 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5408 "Headphone");
5409 if (err < 0)
5410 return err;
05f5f477 5411 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5412 if (err < 0)
e9edcee0
TI
5413 return err;
5414
5415 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5416
757899ac 5417 alc_auto_parse_digital(codec);
e9edcee0 5418
603c4019 5419 if (spec->kctls.list)
d88897ea 5420 add_mixer(spec, spec->kctls.list);
e9edcee0 5421
d88897ea 5422 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5423
a1e8d2da 5424 spec->num_mux_defs = 1;
61b9b9b1 5425 spec->input_mux = &spec->private_imux[0];
e9edcee0 5426
6227cdce 5427 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5428
e9edcee0
TI
5429 return 1;
5430}
5431
ae6b813a
TI
5432/* additional initialization for auto-configuration model */
5433static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5434{
f6c7e546 5435 struct alc_spec *spec = codec->spec;
e9edcee0 5436 alc880_auto_init_multi_out(codec);
8d88bc3d 5437 alc880_auto_init_extra_out(codec);
e9edcee0 5438 alc880_auto_init_analog_input(codec);
7f311a46 5439 alc880_auto_init_input_src(codec);
757899ac 5440 alc_auto_init_digital(codec);
f6c7e546 5441 if (spec->unsol_event)
7fb0d78f 5442 alc_inithook(codec);
e9edcee0
TI
5443}
5444
b59bdf3b
TI
5445/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5446 * one of two digital mic pins, e.g. on ALC272
5447 */
5448static void fixup_automic_adc(struct hda_codec *codec)
5449{
5450 struct alc_spec *spec = codec->spec;
5451 int i;
5452
5453 for (i = 0; i < spec->num_adc_nids; i++) {
5454 hda_nid_t cap = spec->capsrc_nids ?
5455 spec->capsrc_nids[i] : spec->adc_nids[i];
5456 int iidx, eidx;
5457
5458 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5459 if (iidx < 0)
5460 continue;
5461 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5462 if (eidx < 0)
5463 continue;
5464 spec->int_mic.mux_idx = iidx;
5465 spec->ext_mic.mux_idx = eidx;
5466 if (spec->capsrc_nids)
5467 spec->capsrc_nids += i;
5468 spec->adc_nids += i;
5469 spec->num_adc_nids = 1;
5470 return;
5471 }
5472 snd_printd(KERN_INFO "hda_codec: %s: "
5473 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5474 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5475 spec->auto_mic = 0; /* disable auto-mic to be sure */
5476}
5477
748cce43
TI
5478/* select or unmute the given capsrc route */
5479static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5480 int idx)
5481{
5482 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5483 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5484 HDA_AMP_MUTE, 0);
5485 } else {
5486 snd_hda_codec_write_cache(codec, cap, 0,
5487 AC_VERB_SET_CONNECT_SEL, idx);
5488 }
5489}
5490
840b64c0
TI
5491/* set the default connection to that pin */
5492static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5493{
5494 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5495 int i;
5496
eaa9b3a7
TI
5497 for (i = 0; i < spec->num_adc_nids; i++) {
5498 hda_nid_t cap = spec->capsrc_nids ?
5499 spec->capsrc_nids[i] : spec->adc_nids[i];
5500 int idx;
5501
5502 idx = get_connection_index(codec, cap, pin);
5503 if (idx < 0)
5504 continue;
748cce43 5505 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5506 return i; /* return the found index */
5507 }
5508 return -1; /* not found */
5509}
5510
5511/* choose the ADC/MUX containing the input pin and initialize the setup */
5512static void fixup_single_adc(struct hda_codec *codec)
5513{
5514 struct alc_spec *spec = codec->spec;
66ceeb6b 5515 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5516 int i;
5517
5518 /* search for the input pin; there must be only one */
66ceeb6b 5519 if (cfg->num_inputs != 1)
eaa9b3a7 5520 return;
66ceeb6b 5521 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5522 if (i >= 0) {
5523 /* use only this ADC */
5524 if (spec->capsrc_nids)
5525 spec->capsrc_nids += i;
5526 spec->adc_nids += i;
5527 spec->num_adc_nids = 1;
584c0c4c 5528 spec->single_input_src = 1;
eaa9b3a7
TI
5529 }
5530}
5531
840b64c0
TI
5532/* initialize dual adcs */
5533static void fixup_dual_adc_switch(struct hda_codec *codec)
5534{
5535 struct alc_spec *spec = codec->spec;
5536 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5537 init_capsrc_for_pin(codec, spec->int_mic.pin);
5538}
5539
584c0c4c
TI
5540/* initialize some special cases for input sources */
5541static void alc_init_special_input_src(struct hda_codec *codec)
5542{
5543 struct alc_spec *spec = codec->spec;
5544 if (spec->dual_adc_switch)
5545 fixup_dual_adc_switch(codec);
5546 else if (spec->single_input_src)
5547 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5548}
5549
b59bdf3b 5550static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5551{
b59bdf3b 5552 struct alc_spec *spec = codec->spec;
a23b688f
TI
5553 static struct snd_kcontrol_new *caps[2][3] = {
5554 { alc_capture_mixer_nosrc1,
5555 alc_capture_mixer_nosrc2,
5556 alc_capture_mixer_nosrc3 },
5557 { alc_capture_mixer1,
5558 alc_capture_mixer2,
5559 alc_capture_mixer3 },
f9e336f6 5560 };
a23b688f 5561 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5562 int mux = 0;
840b64c0
TI
5563 int num_adcs = spec->num_adc_nids;
5564 if (spec->dual_adc_switch)
584c0c4c 5565 num_adcs = 1;
840b64c0 5566 else if (spec->auto_mic)
b59bdf3b 5567 fixup_automic_adc(codec);
eaa9b3a7
TI
5568 else if (spec->input_mux) {
5569 if (spec->input_mux->num_items > 1)
5570 mux = 1;
5571 else if (spec->input_mux->num_items == 1)
5572 fixup_single_adc(codec);
5573 }
840b64c0 5574 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5575 }
f9e336f6
TI
5576}
5577
6694635d
TI
5578/* fill adc_nids (and capsrc_nids) containing all active input pins */
5579static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5580 int num_nids)
5581{
5582 struct alc_spec *spec = codec->spec;
66ceeb6b 5583 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5584 int n;
5585 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5586
5587 for (n = 0; n < num_nids; n++) {
5588 hda_nid_t adc, cap;
5589 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5590 int nconns, i, j;
5591
5592 adc = nids[n];
5593 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5594 continue;
5595 cap = adc;
5596 nconns = snd_hda_get_connections(codec, cap, conn,
5597 ARRAY_SIZE(conn));
5598 if (nconns == 1) {
5599 cap = conn[0];
5600 nconns = snd_hda_get_connections(codec, cap, conn,
5601 ARRAY_SIZE(conn));
5602 }
5603 if (nconns <= 0)
5604 continue;
5605 if (!fallback_adc) {
5606 fallback_adc = adc;
5607 fallback_cap = cap;
5608 }
66ceeb6b
TI
5609 for (i = 0; i < cfg->num_inputs; i++) {
5610 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5611 for (j = 0; j < nconns; j++) {
5612 if (conn[j] == nid)
5613 break;
5614 }
5615 if (j >= nconns)
5616 break;
5617 }
66ceeb6b 5618 if (i >= cfg->num_inputs) {
6694635d
TI
5619 int num_adcs = spec->num_adc_nids;
5620 spec->private_adc_nids[num_adcs] = adc;
5621 spec->private_capsrc_nids[num_adcs] = cap;
5622 spec->num_adc_nids++;
5623 spec->adc_nids = spec->private_adc_nids;
5624 if (adc != cap)
5625 spec->capsrc_nids = spec->private_capsrc_nids;
5626 }
5627 }
5628 if (!spec->num_adc_nids) {
5629 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5630 " using fallback 0x%x\n",
5631 codec->chip_name, fallback_adc);
6694635d
TI
5632 spec->private_adc_nids[0] = fallback_adc;
5633 spec->adc_nids = spec->private_adc_nids;
5634 if (fallback_adc != fallback_cap) {
5635 spec->private_capsrc_nids[0] = fallback_cap;
5636 spec->capsrc_nids = spec->private_adc_nids;
5637 }
5638 }
5639}
5640
67d634c0 5641#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5642#define set_beep_amp(spec, nid, idx, dir) \
5643 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5644
5645static struct snd_pci_quirk beep_white_list[] = {
5646 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5647 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5648 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5649 {}
5650};
5651
5652static inline int has_cdefine_beep(struct hda_codec *codec)
5653{
5654 struct alc_spec *spec = codec->spec;
5655 const struct snd_pci_quirk *q;
5656 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5657 if (q)
5658 return q->value;
5659 return spec->cdefine.enable_pcbeep;
5660}
67d634c0
TI
5661#else
5662#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5663#define has_cdefine_beep(codec) 0
67d634c0 5664#endif
45bdd1c1
TI
5665
5666/*
5667 * OK, here we have finally the patch for ALC880
5668 */
5669
1da177e4
LT
5670static int patch_alc880(struct hda_codec *codec)
5671{
5672 struct alc_spec *spec;
5673 int board_config;
df694daa 5674 int err;
1da177e4 5675
e560d8d8 5676 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5677 if (spec == NULL)
5678 return -ENOMEM;
5679
5680 codec->spec = spec;
5681
f5fcc13c
TI
5682 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5683 alc880_models,
5684 alc880_cfg_tbl);
5685 if (board_config < 0) {
9a11f1aa
TI
5686 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5687 codec->chip_name);
e9edcee0 5688 board_config = ALC880_AUTO;
1da177e4 5689 }
1da177e4 5690
e9edcee0
TI
5691 if (board_config == ALC880_AUTO) {
5692 /* automatic parse from the BIOS config */
5693 err = alc880_parse_auto_config(codec);
5694 if (err < 0) {
5695 alc_free(codec);
5696 return err;
f12ab1e0 5697 } else if (!err) {
9c7f852e
TI
5698 printk(KERN_INFO
5699 "hda_codec: Cannot set up configuration "
5700 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5701 board_config = ALC880_3ST;
5702 }
1da177e4
LT
5703 }
5704
680cd536
KK
5705 err = snd_hda_attach_beep_device(codec, 0x1);
5706 if (err < 0) {
5707 alc_free(codec);
5708 return err;
5709 }
5710
df694daa 5711 if (board_config != ALC880_AUTO)
e9c364c0 5712 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5713
1da177e4
LT
5714 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5715 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5716 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5717
1da177e4
LT
5718 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5719 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5720
f12ab1e0 5721 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5722 /* check whether NID 0x07 is valid */
54d17403 5723 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5724 /* get type */
a22d543a 5725 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5726 if (wcap != AC_WID_AUD_IN) {
5727 spec->adc_nids = alc880_adc_nids_alt;
5728 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5729 } else {
5730 spec->adc_nids = alc880_adc_nids;
5731 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5732 }
5733 }
b59bdf3b 5734 set_capture_mixer(codec);
45bdd1c1 5735 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5736
2134ea4f
TI
5737 spec->vmaster_nid = 0x0c;
5738
1da177e4 5739 codec->patch_ops = alc_patch_ops;
e9edcee0 5740 if (board_config == ALC880_AUTO)
ae6b813a 5741 spec->init_hook = alc880_auto_init;
cb53c626
TI
5742#ifdef CONFIG_SND_HDA_POWER_SAVE
5743 if (!spec->loopback.amplist)
5744 spec->loopback.amplist = alc880_loopbacks;
5745#endif
1da177e4
LT
5746
5747 return 0;
5748}
5749
e9edcee0 5750
1da177e4
LT
5751/*
5752 * ALC260 support
5753 */
5754
e9edcee0
TI
5755static hda_nid_t alc260_dac_nids[1] = {
5756 /* front */
5757 0x02,
5758};
5759
5760static hda_nid_t alc260_adc_nids[1] = {
5761 /* ADC0 */
5762 0x04,
5763};
5764
df694daa 5765static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5766 /* ADC1 */
5767 0x05,
5768};
5769
d57fdac0
JW
5770/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5771 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5772 */
5773static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5774 /* ADC0, ADC1 */
5775 0x04, 0x05
5776};
5777
e9edcee0
TI
5778#define ALC260_DIGOUT_NID 0x03
5779#define ALC260_DIGIN_NID 0x06
5780
5781static struct hda_input_mux alc260_capture_source = {
5782 .num_items = 4,
5783 .items = {
5784 { "Mic", 0x0 },
5785 { "Front Mic", 0x1 },
5786 { "Line", 0x2 },
5787 { "CD", 0x4 },
5788 },
5789};
5790
17e7aec6 5791/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5792 * headphone jack and the internal CD lines since these are the only pins at
5793 * which audio can appear. For flexibility, also allow the option of
5794 * recording the mixer output on the second ADC (ADC0 doesn't have a
5795 * connection to the mixer output).
a9430dd8 5796 */
a1e8d2da
JW
5797static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5798 {
5799 .num_items = 3,
5800 .items = {
5801 { "Mic/Line", 0x0 },
5802 { "CD", 0x4 },
5803 { "Headphone", 0x2 },
5804 },
a9430dd8 5805 },
a1e8d2da
JW
5806 {
5807 .num_items = 4,
5808 .items = {
5809 { "Mic/Line", 0x0 },
5810 { "CD", 0x4 },
5811 { "Headphone", 0x2 },
5812 { "Mixer", 0x5 },
5813 },
5814 },
5815
a9430dd8
JW
5816};
5817
a1e8d2da
JW
5818/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5819 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5820 */
a1e8d2da
JW
5821static struct hda_input_mux alc260_acer_capture_sources[2] = {
5822 {
5823 .num_items = 4,
5824 .items = {
5825 { "Mic", 0x0 },
5826 { "Line", 0x2 },
5827 { "CD", 0x4 },
5828 { "Headphone", 0x5 },
5829 },
5830 },
5831 {
5832 .num_items = 5,
5833 .items = {
5834 { "Mic", 0x0 },
5835 { "Line", 0x2 },
5836 { "CD", 0x4 },
5837 { "Headphone", 0x6 },
5838 { "Mixer", 0x5 },
5839 },
0bfc90e9
JW
5840 },
5841};
cc959489
MS
5842
5843/* Maxdata Favorit 100XS */
5844static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5845 {
5846 .num_items = 2,
5847 .items = {
5848 { "Line/Mic", 0x0 },
5849 { "CD", 0x4 },
5850 },
5851 },
5852 {
5853 .num_items = 3,
5854 .items = {
5855 { "Line/Mic", 0x0 },
5856 { "CD", 0x4 },
5857 { "Mixer", 0x5 },
5858 },
5859 },
5860};
5861
1da177e4
LT
5862/*
5863 * This is just place-holder, so there's something for alc_build_pcms to look
5864 * at when it calculates the maximum number of channels. ALC260 has no mixer
5865 * element which allows changing the channel mode, so the verb list is
5866 * never used.
5867 */
d2a6d7dc 5868static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5869 { 2, NULL },
5870};
5871
df694daa
KY
5872
5873/* Mixer combinations
5874 *
5875 * basic: base_output + input + pc_beep + capture
5876 * HP: base_output + input + capture_alt
5877 * HP_3013: hp_3013 + input + capture
5878 * fujitsu: fujitsu + capture
0bfc90e9 5879 * acer: acer + capture
df694daa
KY
5880 */
5881
5882static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5883 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5884 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5885 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5886 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5887 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5888 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5889 { } /* end */
f12ab1e0 5890};
1da177e4 5891
df694daa 5892static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5893 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5894 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5895 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5896 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5898 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5899 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5900 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5901 { } /* end */
5902};
5903
bec15c3a
TI
5904/* update HP, line and mono out pins according to the master switch */
5905static void alc260_hp_master_update(struct hda_codec *codec,
5906 hda_nid_t hp, hda_nid_t line,
5907 hda_nid_t mono)
5908{
5909 struct alc_spec *spec = codec->spec;
5910 unsigned int val = spec->master_sw ? PIN_HP : 0;
5911 /* change HP and line-out pins */
30cde0aa 5912 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5913 val);
30cde0aa 5914 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5915 val);
5916 /* mono (speaker) depending on the HP jack sense */
5917 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5918 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5919 val);
5920}
5921
5922static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5923 struct snd_ctl_elem_value *ucontrol)
5924{
5925 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5926 struct alc_spec *spec = codec->spec;
5927 *ucontrol->value.integer.value = spec->master_sw;
5928 return 0;
5929}
5930
5931static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5932 struct snd_ctl_elem_value *ucontrol)
5933{
5934 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5935 struct alc_spec *spec = codec->spec;
5936 int val = !!*ucontrol->value.integer.value;
5937 hda_nid_t hp, line, mono;
5938
5939 if (val == spec->master_sw)
5940 return 0;
5941 spec->master_sw = val;
5942 hp = (kcontrol->private_value >> 16) & 0xff;
5943 line = (kcontrol->private_value >> 8) & 0xff;
5944 mono = kcontrol->private_value & 0xff;
5945 alc260_hp_master_update(codec, hp, line, mono);
5946 return 1;
5947}
5948
5949static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5950 {
5951 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5952 .name = "Master Playback Switch",
5b0cb1d8 5953 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5954 .info = snd_ctl_boolean_mono_info,
5955 .get = alc260_hp_master_sw_get,
5956 .put = alc260_hp_master_sw_put,
5957 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5958 },
5959 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5960 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5961 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5962 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5963 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5964 HDA_OUTPUT),
5965 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5966 { } /* end */
5967};
5968
5969static struct hda_verb alc260_hp_unsol_verbs[] = {
5970 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5971 {},
5972};
5973
5974static void alc260_hp_automute(struct hda_codec *codec)
5975{
5976 struct alc_spec *spec = codec->spec;
bec15c3a 5977
864f92be 5978 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5979 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5980}
5981
5982static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5983{
5984 if ((res >> 26) == ALC880_HP_EVENT)
5985 alc260_hp_automute(codec);
5986}
5987
df694daa 5988static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5989 {
5990 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5991 .name = "Master Playback Switch",
5b0cb1d8 5992 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5993 .info = snd_ctl_boolean_mono_info,
5994 .get = alc260_hp_master_sw_get,
5995 .put = alc260_hp_master_sw_put,
30cde0aa 5996 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5997 },
df694daa
KY
5998 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5999 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6000 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6001 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6002 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6004 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6005 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6006 { } /* end */
6007};
6008
3f878308
KY
6009static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6010 .ops = &snd_hda_bind_vol,
6011 .values = {
6012 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6013 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6014 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6015 0
6016 },
6017};
6018
6019static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6020 .ops = &snd_hda_bind_sw,
6021 .values = {
6022 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6023 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6024 0
6025 },
6026};
6027
6028static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6029 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6030 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6031 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6032 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6033 { } /* end */
6034};
6035
bec15c3a
TI
6036static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6037 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6038 {},
6039};
6040
6041static void alc260_hp_3013_automute(struct hda_codec *codec)
6042{
6043 struct alc_spec *spec = codec->spec;
bec15c3a 6044
864f92be 6045 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 6046 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
6047}
6048
6049static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6050 unsigned int res)
6051{
6052 if ((res >> 26) == ALC880_HP_EVENT)
6053 alc260_hp_3013_automute(codec);
6054}
6055
3f878308
KY
6056static void alc260_hp_3012_automute(struct hda_codec *codec)
6057{
864f92be 6058 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 6059
3f878308
KY
6060 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6061 bits);
6062 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6063 bits);
6064 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6065 bits);
6066}
6067
6068static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6069 unsigned int res)
6070{
6071 if ((res >> 26) == ALC880_HP_EVENT)
6072 alc260_hp_3012_automute(codec);
6073}
6074
6075/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6076 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6077 */
c8b6bf9b 6078static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6079 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6080 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6081 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6082 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6083 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6084 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6085 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6086 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6087 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6088 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6089 { } /* end */
6090};
6091
a1e8d2da
JW
6092/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6093 * versions of the ALC260 don't act on requests to enable mic bias from NID
6094 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6095 * datasheet doesn't mention this restriction. At this stage it's not clear
6096 * whether this behaviour is intentional or is a hardware bug in chip
6097 * revisions available in early 2006. Therefore for now allow the
6098 * "Headphone Jack Mode" control to span all choices, but if it turns out
6099 * that the lack of mic bias for this NID is intentional we could change the
6100 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6101 *
6102 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6103 * don't appear to make the mic bias available from the "line" jack, even
6104 * though the NID used for this jack (0x14) can supply it. The theory is
6105 * that perhaps Acer have included blocking capacitors between the ALC260
6106 * and the output jack. If this turns out to be the case for all such
6107 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6108 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6109 *
6110 * The C20x Tablet series have a mono internal speaker which is controlled
6111 * via the chip's Mono sum widget and pin complex, so include the necessary
6112 * controls for such models. On models without a "mono speaker" the control
6113 * won't do anything.
a1e8d2da 6114 */
0bfc90e9
JW
6115static struct snd_kcontrol_new alc260_acer_mixer[] = {
6116 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6117 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6118 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6119 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6120 HDA_OUTPUT),
31bffaa9 6121 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6122 HDA_INPUT),
0bfc90e9
JW
6123 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6124 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6125 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6126 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6127 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6128 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6129 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6130 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6131 { } /* end */
6132};
6133
cc959489
MS
6134/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6135 */
6136static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6137 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6138 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6139 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6140 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6141 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6142 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6143 { } /* end */
6144};
6145
bc9f98a9
KY
6146/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6147 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6148 */
6149static struct snd_kcontrol_new alc260_will_mixer[] = {
6150 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6151 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6152 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6153 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6154 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6155 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6156 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6157 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6158 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6159 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6160 { } /* end */
6161};
6162
6163/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6164 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6165 */
6166static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6167 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6168 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6170 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6171 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6172 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6173 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6174 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6175 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6176 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6177 { } /* end */
6178};
6179
df694daa
KY
6180/*
6181 * initialization verbs
6182 */
1da177e4
LT
6183static struct hda_verb alc260_init_verbs[] = {
6184 /* Line In pin widget for input */
05acb863 6185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6186 /* CD pin widget for input */
05acb863 6187 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6188 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6189 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6190 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6191 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6192 /* LINE-2 is used for line-out in rear */
05acb863 6193 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6194 /* select line-out */
fd56f2db 6195 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6196 /* LINE-OUT pin */
05acb863 6197 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6198 /* enable HP */
05acb863 6199 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6200 /* enable Mono */
05acb863
TI
6201 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6202 /* mute capture amp left and right */
16ded525 6203 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6204 /* set connection select to line in (default select for this ADC) */
6205 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6206 /* mute capture amp left and right */
6207 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6208 /* set connection select to line in (default select for this ADC) */
6209 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6210 /* set vol=0 Line-Out mixer amp left and right */
6211 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6212 /* unmute pin widget amp left and right (no gain on this amp) */
6213 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6214 /* set vol=0 HP mixer amp left and right */
6215 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6216 /* unmute pin widget amp left and right (no gain on this amp) */
6217 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6218 /* set vol=0 Mono mixer amp left and right */
6219 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6220 /* unmute pin widget amp left and right (no gain on this amp) */
6221 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6222 /* unmute LINE-2 out pin */
6223 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6224 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6225 * Line In 2 = 0x03
6226 */
cb53c626
TI
6227 /* mute analog inputs */
6228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6229 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6233 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6234 /* mute Front out path */
6235 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6236 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6237 /* mute Headphone out path */
6238 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6239 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6240 /* mute Mono out path */
6241 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6242 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6243 { }
6244};
6245
474167d6 6246#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6247static struct hda_verb alc260_hp_init_verbs[] = {
6248 /* Headphone and output */
6249 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6250 /* mono output */
6251 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6252 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6253 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6254 /* Mic2 (front panel) pin widget for input and vref at 80% */
6255 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6256 /* Line In pin widget for input */
6257 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6258 /* Line-2 pin widget for output */
6259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6260 /* CD pin widget for input */
6261 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6262 /* unmute amp left and right */
6263 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6264 /* set connection select to line in (default select for this ADC) */
6265 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6266 /* unmute Line-Out mixer amp left and right (volume = 0) */
6267 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6268 /* mute pin widget amp left and right (no gain on this amp) */
6269 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6270 /* unmute HP mixer amp left and right (volume = 0) */
6271 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6272 /* mute pin widget amp left and right (no gain on this amp) */
6273 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6274 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6275 * Line In 2 = 0x03
6276 */
cb53c626
TI
6277 /* mute analog inputs */
6278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6283 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6284 /* Unmute Front out path */
6285 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6286 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6287 /* Unmute Headphone out path */
6288 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6289 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6290 /* Unmute Mono out path */
6291 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6292 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6293 { }
6294};
474167d6 6295#endif
df694daa
KY
6296
6297static struct hda_verb alc260_hp_3013_init_verbs[] = {
6298 /* Line out and output */
6299 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6300 /* mono output */
6301 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6302 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6303 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6304 /* Mic2 (front panel) pin widget for input and vref at 80% */
6305 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6306 /* Line In pin widget for input */
6307 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6308 /* Headphone pin widget for output */
6309 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6310 /* CD pin widget for input */
6311 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6312 /* unmute amp left and right */
6313 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6314 /* set connection select to line in (default select for this ADC) */
6315 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6316 /* unmute Line-Out mixer amp left and right (volume = 0) */
6317 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6318 /* mute pin widget amp left and right (no gain on this amp) */
6319 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6320 /* unmute HP mixer amp left and right (volume = 0) */
6321 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6322 /* mute pin widget amp left and right (no gain on this amp) */
6323 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6324 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6325 * Line In 2 = 0x03
6326 */
cb53c626
TI
6327 /* mute analog inputs */
6328 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6333 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6334 /* Unmute Front out path */
6335 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6336 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6337 /* Unmute Headphone out path */
6338 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6339 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6340 /* Unmute Mono out path */
6341 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6342 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6343 { }
6344};
6345
a9430dd8 6346/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6347 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6348 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6349 */
6350static struct hda_verb alc260_fujitsu_init_verbs[] = {
6351 /* Disable all GPIOs */
6352 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6353 /* Internal speaker is connected to headphone pin */
6354 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6355 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6357 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6358 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6359 /* Ensure all other unused pins are disabled and muted. */
6360 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6361 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6362 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6363 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6364 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6365 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6368
6369 /* Disable digital (SPDIF) pins */
6370 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6371 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6372
ea1fb29a 6373 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6374 * when acting as an output.
6375 */
6376 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6377
f7ace40d 6378 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6379 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6380 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6381 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6382 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6383 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6384 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6385 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6386 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6387 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6388
f7ace40d
JW
6389 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6390 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6391 /* Unmute Line1 pin widget output buffer since it starts as an output.
6392 * If the pin mode is changed by the user the pin mode control will
6393 * take care of enabling the pin's input/output buffers as needed.
6394 * Therefore there's no need to enable the input buffer at this
6395 * stage.
cdcd9268 6396 */
f7ace40d 6397 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6398 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6399 * mixer ctrl)
6400 */
f7ace40d
JW
6401 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6402
6403 /* Mute capture amp left and right */
6404 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6405 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6406 * in (on mic1 pin)
6407 */
6408 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6409
6410 /* Do the same for the second ADC: mute capture input amp and
6411 * set ADC connection to line in (on mic1 pin)
6412 */
6413 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6414 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6415
6416 /* Mute all inputs to mixer widget (even unconnected ones) */
6417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6418 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6419 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6420 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6421 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6422 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6423 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6425
6426 { }
a9430dd8
JW
6427};
6428
0bfc90e9
JW
6429/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6430 * similar laptops (adapted from Fujitsu init verbs).
6431 */
6432static struct hda_verb alc260_acer_init_verbs[] = {
6433 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6434 * the headphone jack. Turn this on and rely on the standard mute
6435 * methods whenever the user wants to turn these outputs off.
6436 */
6437 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6438 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6439 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6440 /* Internal speaker/Headphone jack is connected to Line-out pin */
6441 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6442 /* Internal microphone/Mic jack is connected to Mic1 pin */
6443 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6444 /* Line In jack is connected to Line1 pin */
6445 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6446 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6447 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6448 /* Ensure all other unused pins are disabled and muted. */
6449 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6450 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6451 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6452 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6453 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6455 /* Disable digital (SPDIF) pins */
6456 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6457 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6458
ea1fb29a 6459 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6460 * bus when acting as outputs.
6461 */
6462 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6463 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6464
6465 /* Start with output sum widgets muted and their output gains at min */
6466 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6467 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6468 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6469 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6470 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6471 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6472 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6473 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6474 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6475
f12ab1e0
TI
6476 /* Unmute Line-out pin widget amp left and right
6477 * (no equiv mixer ctrl)
6478 */
0bfc90e9 6479 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6480 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6481 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6482 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6483 * inputs. If the pin mode is changed by the user the pin mode control
6484 * will take care of enabling the pin's input/output buffers as needed.
6485 * Therefore there's no need to enable the input buffer at this
6486 * stage.
6487 */
6488 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6489 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6490
6491 /* Mute capture amp left and right */
6492 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6493 /* Set ADC connection select to match default mixer setting - mic
6494 * (on mic1 pin)
6495 */
6496 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6497
6498 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6499 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6500 */
6501 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6502 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6503
6504 /* Mute all inputs to mixer widget (even unconnected ones) */
6505 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6506 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6508 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6510 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6511 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6512 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6513
6514 { }
6515};
6516
cc959489
MS
6517/* Initialisation sequence for Maxdata Favorit 100XS
6518 * (adapted from Acer init verbs).
6519 */
6520static struct hda_verb alc260_favorit100_init_verbs[] = {
6521 /* GPIO 0 enables the output jack.
6522 * Turn this on and rely on the standard mute
6523 * methods whenever the user wants to turn these outputs off.
6524 */
6525 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6526 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6527 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6528 /* Line/Mic input jack is connected to Mic1 pin */
6529 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6530 /* Ensure all other unused pins are disabled and muted. */
6531 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6532 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6533 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6534 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6535 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6536 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6537 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6538 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6539 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6541 /* Disable digital (SPDIF) pins */
6542 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6543 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6544
6545 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6546 * bus when acting as outputs.
6547 */
6548 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6549 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6550
6551 /* Start with output sum widgets muted and their output gains at min */
6552 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6553 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6555 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6556 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6557 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6558 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6559 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6560 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6561
6562 /* Unmute Line-out pin widget amp left and right
6563 * (no equiv mixer ctrl)
6564 */
6565 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6566 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6567 * inputs. If the pin mode is changed by the user the pin mode control
6568 * will take care of enabling the pin's input/output buffers as needed.
6569 * Therefore there's no need to enable the input buffer at this
6570 * stage.
6571 */
6572 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6573
6574 /* Mute capture amp left and right */
6575 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6576 /* Set ADC connection select to match default mixer setting - mic
6577 * (on mic1 pin)
6578 */
6579 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6580
6581 /* Do similar with the second ADC: mute capture input amp and
6582 * set ADC connection to mic to match ALSA's default state.
6583 */
6584 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6585 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6586
6587 /* Mute all inputs to mixer widget (even unconnected ones) */
6588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6589 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6593 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6594 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6596
6597 { }
6598};
6599
bc9f98a9
KY
6600static struct hda_verb alc260_will_verbs[] = {
6601 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6602 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6603 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6604 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6605 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6606 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6607 {}
6608};
6609
6610static struct hda_verb alc260_replacer_672v_verbs[] = {
6611 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6612 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6613 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6614
6615 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6616 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6617 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6618
6619 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6620 {}
6621};
6622
6623/* toggle speaker-output according to the hp-jack state */
6624static void alc260_replacer_672v_automute(struct hda_codec *codec)
6625{
6626 unsigned int present;
6627
6628 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6629 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6630 if (present) {
82beb8fd
TI
6631 snd_hda_codec_write_cache(codec, 0x01, 0,
6632 AC_VERB_SET_GPIO_DATA, 1);
6633 snd_hda_codec_write_cache(codec, 0x0f, 0,
6634 AC_VERB_SET_PIN_WIDGET_CONTROL,
6635 PIN_HP);
bc9f98a9 6636 } else {
82beb8fd
TI
6637 snd_hda_codec_write_cache(codec, 0x01, 0,
6638 AC_VERB_SET_GPIO_DATA, 0);
6639 snd_hda_codec_write_cache(codec, 0x0f, 0,
6640 AC_VERB_SET_PIN_WIDGET_CONTROL,
6641 PIN_OUT);
bc9f98a9
KY
6642 }
6643}
6644
6645static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6646 unsigned int res)
6647{
6648 if ((res >> 26) == ALC880_HP_EVENT)
6649 alc260_replacer_672v_automute(codec);
6650}
6651
3f878308
KY
6652static struct hda_verb alc260_hp_dc7600_verbs[] = {
6653 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6655 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6656 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6657 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6658 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6659 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6660 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6661 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6662 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6663 {}
6664};
6665
7cf51e48
JW
6666/* Test configuration for debugging, modelled after the ALC880 test
6667 * configuration.
6668 */
6669#ifdef CONFIG_SND_DEBUG
6670static hda_nid_t alc260_test_dac_nids[1] = {
6671 0x02,
6672};
6673static hda_nid_t alc260_test_adc_nids[2] = {
6674 0x04, 0x05,
6675};
a1e8d2da 6676/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6677 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6678 * is NID 0x04.
17e7aec6 6679 */
a1e8d2da
JW
6680static struct hda_input_mux alc260_test_capture_sources[2] = {
6681 {
6682 .num_items = 7,
6683 .items = {
6684 { "MIC1 pin", 0x0 },
6685 { "MIC2 pin", 0x1 },
6686 { "LINE1 pin", 0x2 },
6687 { "LINE2 pin", 0x3 },
6688 { "CD pin", 0x4 },
6689 { "LINE-OUT pin", 0x5 },
6690 { "HP-OUT pin", 0x6 },
6691 },
6692 },
6693 {
6694 .num_items = 8,
6695 .items = {
6696 { "MIC1 pin", 0x0 },
6697 { "MIC2 pin", 0x1 },
6698 { "LINE1 pin", 0x2 },
6699 { "LINE2 pin", 0x3 },
6700 { "CD pin", 0x4 },
6701 { "Mixer", 0x5 },
6702 { "LINE-OUT pin", 0x6 },
6703 { "HP-OUT pin", 0x7 },
6704 },
7cf51e48
JW
6705 },
6706};
6707static struct snd_kcontrol_new alc260_test_mixer[] = {
6708 /* Output driver widgets */
6709 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6710 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6711 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6712 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6713 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6714 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6715
a1e8d2da
JW
6716 /* Modes for retasking pin widgets
6717 * Note: the ALC260 doesn't seem to act on requests to enable mic
6718 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6719 * mention this restriction. At this stage it's not clear whether
6720 * this behaviour is intentional or is a hardware bug in chip
6721 * revisions available at least up until early 2006. Therefore for
6722 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6723 * choices, but if it turns out that the lack of mic bias for these
6724 * NIDs is intentional we could change their modes from
6725 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6726 */
7cf51e48
JW
6727 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6728 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6729 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6730 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6731 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6732 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6733
6734 /* Loopback mixer controls */
6735 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6736 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6737 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6738 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6739 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6740 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6741 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6742 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6743 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6744 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6745 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6746 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6747 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6748 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6749
6750 /* Controls for GPIO pins, assuming they are configured as outputs */
6751 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6752 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6753 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6754 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6755
92621f13
JW
6756 /* Switches to allow the digital IO pins to be enabled. The datasheet
6757 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6758 * make this output available should provide clarification.
92621f13
JW
6759 */
6760 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6761 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6762
f8225f6d
JW
6763 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6764 * this output to turn on an external amplifier.
6765 */
6766 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6767 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6768
7cf51e48
JW
6769 { } /* end */
6770};
6771static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6772 /* Enable all GPIOs as outputs with an initial value of 0 */
6773 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6774 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6775 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6776
7cf51e48
JW
6777 /* Enable retasking pins as output, initially without power amp */
6778 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6779 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6780 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6781 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6782 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6783 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6784
92621f13
JW
6785 /* Disable digital (SPDIF) pins initially, but users can enable
6786 * them via a mixer switch. In the case of SPDIF-out, this initverb
6787 * payload also sets the generation to 0, output to be in "consumer"
6788 * PCM format, copyright asserted, no pre-emphasis and no validity
6789 * control.
6790 */
7cf51e48
JW
6791 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6792 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6793
ea1fb29a 6794 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6795 * OUT1 sum bus when acting as an output.
6796 */
6797 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6798 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6799 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6800 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6801
6802 /* Start with output sum widgets muted and their output gains at min */
6803 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6804 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6805 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6806 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6807 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6808 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6809 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6810 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6811 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6812
cdcd9268
JW
6813 /* Unmute retasking pin widget output buffers since the default
6814 * state appears to be output. As the pin mode is changed by the
6815 * user the pin mode control will take care of enabling the pin's
6816 * input/output buffers as needed.
6817 */
7cf51e48
JW
6818 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6819 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6821 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6822 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6823 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6824 /* Also unmute the mono-out pin widget */
6825 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6826
7cf51e48
JW
6827 /* Mute capture amp left and right */
6828 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6829 /* Set ADC connection select to match default mixer setting (mic1
6830 * pin)
7cf51e48
JW
6831 */
6832 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6833
6834 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6835 * set ADC connection to mic1 pin
7cf51e48
JW
6836 */
6837 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6838 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6839
6840 /* Mute all inputs to mixer widget (even unconnected ones) */
6841 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6842 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6843 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6844 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6845 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6846 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6847 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6848 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6849
6850 { }
6851};
6852#endif
6853
6330079f
TI
6854#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6855#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6856
a3bcba38
TI
6857#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6858#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6859
df694daa
KY
6860/*
6861 * for BIOS auto-configuration
6862 */
16ded525 6863
df694daa 6864static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6865 const char *pfx, int *vol_bits)
df694daa
KY
6866{
6867 hda_nid_t nid_vol;
6868 unsigned long vol_val, sw_val;
df694daa
KY
6869 int err;
6870
6871 if (nid >= 0x0f && nid < 0x11) {
6872 nid_vol = nid - 0x7;
6873 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6874 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6875 } else if (nid == 0x11) {
6876 nid_vol = nid - 0x7;
6877 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6878 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6879 } else if (nid >= 0x12 && nid <= 0x15) {
6880 nid_vol = 0x08;
6881 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6882 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6883 } else
6884 return 0; /* N/A */
ea1fb29a 6885
863b4518
TI
6886 if (!(*vol_bits & (1 << nid_vol))) {
6887 /* first control for the volume widget */
0afe5f89 6888 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6889 if (err < 0)
6890 return err;
6891 *vol_bits |= (1 << nid_vol);
6892 }
0afe5f89 6893 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6894 if (err < 0)
df694daa
KY
6895 return err;
6896 return 1;
6897}
6898
6899/* add playback controls from the parsed DAC table */
6900static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6901 const struct auto_pin_cfg *cfg)
6902{
6903 hda_nid_t nid;
6904 int err;
863b4518 6905 int vols = 0;
df694daa
KY
6906
6907 spec->multiout.num_dacs = 1;
6908 spec->multiout.dac_nids = spec->private_dac_nids;
6909 spec->multiout.dac_nids[0] = 0x02;
6910
6911 nid = cfg->line_out_pins[0];
6912 if (nid) {
23112d6d
TI
6913 const char *pfx;
6914 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6915 pfx = "Master";
6916 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6917 pfx = "Speaker";
6918 else
6919 pfx = "Front";
6920 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6921 if (err < 0)
6922 return err;
6923 }
6924
82bc955f 6925 nid = cfg->speaker_pins[0];
df694daa 6926 if (nid) {
863b4518 6927 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6928 if (err < 0)
6929 return err;
6930 }
6931
eb06ed8f 6932 nid = cfg->hp_pins[0];
df694daa 6933 if (nid) {
863b4518
TI
6934 err = alc260_add_playback_controls(spec, nid, "Headphone",
6935 &vols);
df694daa
KY
6936 if (err < 0)
6937 return err;
6938 }
f12ab1e0 6939 return 0;
df694daa
KY
6940}
6941
6942/* create playback/capture controls for input pins */
05f5f477 6943static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6944 const struct auto_pin_cfg *cfg)
6945{
05f5f477 6946 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6947}
6948
6949static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6950 hda_nid_t nid, int pin_type,
6951 int sel_idx)
6952{
f6c7e546 6953 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6954 /* need the manual connection? */
6955 if (nid >= 0x12) {
6956 int idx = nid - 0x12;
6957 snd_hda_codec_write(codec, idx + 0x0b, 0,
6958 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6959 }
6960}
6961
6962static void alc260_auto_init_multi_out(struct hda_codec *codec)
6963{
6964 struct alc_spec *spec = codec->spec;
6965 hda_nid_t nid;
6966
f12ab1e0 6967 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6968 if (nid) {
6969 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6970 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6971 }
ea1fb29a 6972
82bc955f 6973 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6974 if (nid)
6975 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6976
eb06ed8f 6977 nid = spec->autocfg.hp_pins[0];
df694daa 6978 if (nid)
baba8ee9 6979 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6980}
df694daa
KY
6981
6982#define ALC260_PIN_CD_NID 0x16
6983static void alc260_auto_init_analog_input(struct hda_codec *codec)
6984{
6985 struct alc_spec *spec = codec->spec;
66ceeb6b 6986 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6987 int i;
6988
66ceeb6b
TI
6989 for (i = 0; i < cfg->num_inputs; i++) {
6990 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6991 if (nid >= 0x12) {
30ea098f 6992 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6993 if (nid != ALC260_PIN_CD_NID &&
6994 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6995 snd_hda_codec_write(codec, nid, 0,
6996 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6997 AMP_OUT_MUTE);
6998 }
6999 }
7000}
7001
7f311a46
TI
7002#define alc260_auto_init_input_src alc880_auto_init_input_src
7003
df694daa
KY
7004/*
7005 * generic initialization of ADC, input mixers and output mixers
7006 */
7007static struct hda_verb alc260_volume_init_verbs[] = {
7008 /*
7009 * Unmute ADC0-1 and set the default input to mic-in
7010 */
7011 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7012 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7013 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7014 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7015
df694daa
KY
7016 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7017 * mixer widget
f12ab1e0
TI
7018 * Note: PASD motherboards uses the Line In 2 as the input for
7019 * front panel mic (mic 2)
df694daa
KY
7020 */
7021 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7022 /* mute analog inputs */
7023 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7024 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7025 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7026 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7028
7029 /*
7030 * Set up output mixers (0x08 - 0x0a)
7031 */
7032 /* set vol=0 to output mixers */
7033 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7034 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7035 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7036 /* set up input amps for analog loopback */
7037 /* Amp Indices: DAC = 0, mixer = 1 */
7038 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7039 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7040 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7041 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7042 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7043 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7044
df694daa
KY
7045 { }
7046};
7047
7048static int alc260_parse_auto_config(struct hda_codec *codec)
7049{
7050 struct alc_spec *spec = codec->spec;
df694daa
KY
7051 int err;
7052 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7053
f12ab1e0
TI
7054 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7055 alc260_ignore);
7056 if (err < 0)
df694daa 7057 return err;
f12ab1e0
TI
7058 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7059 if (err < 0)
4a471b7d 7060 return err;
603c4019 7061 if (!spec->kctls.list)
df694daa 7062 return 0; /* can't find valid BIOS pin config */
05f5f477 7063 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7064 if (err < 0)
df694daa
KY
7065 return err;
7066
7067 spec->multiout.max_channels = 2;
7068
0852d7a6 7069 if (spec->autocfg.dig_outs)
df694daa 7070 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7071 if (spec->kctls.list)
d88897ea 7072 add_mixer(spec, spec->kctls.list);
df694daa 7073
d88897ea 7074 add_verb(spec, alc260_volume_init_verbs);
df694daa 7075
a1e8d2da 7076 spec->num_mux_defs = 1;
61b9b9b1 7077 spec->input_mux = &spec->private_imux[0];
df694daa 7078
6227cdce 7079 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7080
df694daa
KY
7081 return 1;
7082}
7083
ae6b813a
TI
7084/* additional initialization for auto-configuration model */
7085static void alc260_auto_init(struct hda_codec *codec)
df694daa 7086{
f6c7e546 7087 struct alc_spec *spec = codec->spec;
df694daa
KY
7088 alc260_auto_init_multi_out(codec);
7089 alc260_auto_init_analog_input(codec);
7f311a46 7090 alc260_auto_init_input_src(codec);
757899ac 7091 alc_auto_init_digital(codec);
f6c7e546 7092 if (spec->unsol_event)
7fb0d78f 7093 alc_inithook(codec);
df694daa
KY
7094}
7095
cb53c626
TI
7096#ifdef CONFIG_SND_HDA_POWER_SAVE
7097static struct hda_amp_list alc260_loopbacks[] = {
7098 { 0x07, HDA_INPUT, 0 },
7099 { 0x07, HDA_INPUT, 1 },
7100 { 0x07, HDA_INPUT, 2 },
7101 { 0x07, HDA_INPUT, 3 },
7102 { 0x07, HDA_INPUT, 4 },
7103 { } /* end */
7104};
7105#endif
7106
fc091769
TI
7107/*
7108 * Pin config fixes
7109 */
7110enum {
7111 PINFIX_HP_DC5750,
7112};
7113
fc091769
TI
7114static const struct alc_fixup alc260_fixups[] = {
7115 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7116 .type = ALC_FIXUP_PINS,
7117 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7118 { 0x11, 0x90130110 }, /* speaker */
7119 { }
7120 }
fc091769
TI
7121 },
7122};
7123
7124static struct snd_pci_quirk alc260_fixup_tbl[] = {
7125 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7126 {}
7127};
7128
df694daa
KY
7129/*
7130 * ALC260 configurations
7131 */
ea734963 7132static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7133 [ALC260_BASIC] = "basic",
7134 [ALC260_HP] = "hp",
7135 [ALC260_HP_3013] = "hp-3013",
2922c9af 7136 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7137 [ALC260_FUJITSU_S702X] = "fujitsu",
7138 [ALC260_ACER] = "acer",
bc9f98a9
KY
7139 [ALC260_WILL] = "will",
7140 [ALC260_REPLACER_672V] = "replacer",
cc959489 7141 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7142#ifdef CONFIG_SND_DEBUG
f5fcc13c 7143 [ALC260_TEST] = "test",
7cf51e48 7144#endif
f5fcc13c
TI
7145 [ALC260_AUTO] = "auto",
7146};
7147
7148static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7149 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7150 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7151 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7152 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7153 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7154 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7155 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7156 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7157 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7158 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7159 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7160 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7161 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7162 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7163 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7164 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7165 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7166 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7167 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7168 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7169 {}
7170};
7171
7172static struct alc_config_preset alc260_presets[] = {
7173 [ALC260_BASIC] = {
7174 .mixers = { alc260_base_output_mixer,
45bdd1c1 7175 alc260_input_mixer },
df694daa
KY
7176 .init_verbs = { alc260_init_verbs },
7177 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7178 .dac_nids = alc260_dac_nids,
f9e336f6 7179 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7180 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7181 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7182 .channel_mode = alc260_modes,
7183 .input_mux = &alc260_capture_source,
7184 },
7185 [ALC260_HP] = {
bec15c3a 7186 .mixers = { alc260_hp_output_mixer,
f9e336f6 7187 alc260_input_mixer },
bec15c3a
TI
7188 .init_verbs = { alc260_init_verbs,
7189 alc260_hp_unsol_verbs },
df694daa
KY
7190 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7191 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7192 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7193 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7194 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7195 .channel_mode = alc260_modes,
7196 .input_mux = &alc260_capture_source,
bec15c3a
TI
7197 .unsol_event = alc260_hp_unsol_event,
7198 .init_hook = alc260_hp_automute,
df694daa 7199 },
3f878308
KY
7200 [ALC260_HP_DC7600] = {
7201 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7202 alc260_input_mixer },
3f878308
KY
7203 .init_verbs = { alc260_init_verbs,
7204 alc260_hp_dc7600_verbs },
7205 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7206 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7207 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7208 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7209 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7210 .channel_mode = alc260_modes,
7211 .input_mux = &alc260_capture_source,
7212 .unsol_event = alc260_hp_3012_unsol_event,
7213 .init_hook = alc260_hp_3012_automute,
7214 },
df694daa
KY
7215 [ALC260_HP_3013] = {
7216 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7217 alc260_input_mixer },
bec15c3a
TI
7218 .init_verbs = { alc260_hp_3013_init_verbs,
7219 alc260_hp_3013_unsol_verbs },
df694daa
KY
7220 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7221 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7222 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7223 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7224 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7225 .channel_mode = alc260_modes,
7226 .input_mux = &alc260_capture_source,
bec15c3a
TI
7227 .unsol_event = alc260_hp_3013_unsol_event,
7228 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7229 },
7230 [ALC260_FUJITSU_S702X] = {
f9e336f6 7231 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7232 .init_verbs = { alc260_fujitsu_init_verbs },
7233 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7234 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7235 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7236 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7237 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7238 .channel_mode = alc260_modes,
a1e8d2da
JW
7239 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7240 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7241 },
0bfc90e9 7242 [ALC260_ACER] = {
f9e336f6 7243 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7244 .init_verbs = { alc260_acer_init_verbs },
7245 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7246 .dac_nids = alc260_dac_nids,
7247 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7248 .adc_nids = alc260_dual_adc_nids,
7249 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7250 .channel_mode = alc260_modes,
a1e8d2da
JW
7251 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7252 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7253 },
cc959489
MS
7254 [ALC260_FAVORIT100] = {
7255 .mixers = { alc260_favorit100_mixer },
7256 .init_verbs = { alc260_favorit100_init_verbs },
7257 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7258 .dac_nids = alc260_dac_nids,
7259 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7260 .adc_nids = alc260_dual_adc_nids,
7261 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7262 .channel_mode = alc260_modes,
7263 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7264 .input_mux = alc260_favorit100_capture_sources,
7265 },
bc9f98a9 7266 [ALC260_WILL] = {
f9e336f6 7267 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7268 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7269 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7270 .dac_nids = alc260_dac_nids,
7271 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7272 .adc_nids = alc260_adc_nids,
7273 .dig_out_nid = ALC260_DIGOUT_NID,
7274 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7275 .channel_mode = alc260_modes,
7276 .input_mux = &alc260_capture_source,
7277 },
7278 [ALC260_REPLACER_672V] = {
f9e336f6 7279 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7280 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7281 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7282 .dac_nids = alc260_dac_nids,
7283 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7284 .adc_nids = alc260_adc_nids,
7285 .dig_out_nid = ALC260_DIGOUT_NID,
7286 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7287 .channel_mode = alc260_modes,
7288 .input_mux = &alc260_capture_source,
7289 .unsol_event = alc260_replacer_672v_unsol_event,
7290 .init_hook = alc260_replacer_672v_automute,
7291 },
7cf51e48
JW
7292#ifdef CONFIG_SND_DEBUG
7293 [ALC260_TEST] = {
f9e336f6 7294 .mixers = { alc260_test_mixer },
7cf51e48
JW
7295 .init_verbs = { alc260_test_init_verbs },
7296 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7297 .dac_nids = alc260_test_dac_nids,
7298 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7299 .adc_nids = alc260_test_adc_nids,
7300 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7301 .channel_mode = alc260_modes,
a1e8d2da
JW
7302 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7303 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7304 },
7305#endif
df694daa
KY
7306};
7307
7308static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7309{
7310 struct alc_spec *spec;
df694daa 7311 int err, board_config;
1da177e4 7312
e560d8d8 7313 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7314 if (spec == NULL)
7315 return -ENOMEM;
7316
7317 codec->spec = spec;
7318
f5fcc13c
TI
7319 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7320 alc260_models,
7321 alc260_cfg_tbl);
7322 if (board_config < 0) {
9a11f1aa 7323 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7324 codec->chip_name);
df694daa 7325 board_config = ALC260_AUTO;
16ded525 7326 }
1da177e4 7327
b5bfbc67
TI
7328 if (board_config == ALC260_AUTO) {
7329 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7330 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7331 }
fc091769 7332
df694daa
KY
7333 if (board_config == ALC260_AUTO) {
7334 /* automatic parse from the BIOS config */
7335 err = alc260_parse_auto_config(codec);
7336 if (err < 0) {
7337 alc_free(codec);
7338 return err;
f12ab1e0 7339 } else if (!err) {
9c7f852e
TI
7340 printk(KERN_INFO
7341 "hda_codec: Cannot set up configuration "
7342 "from BIOS. Using base mode...\n");
df694daa
KY
7343 board_config = ALC260_BASIC;
7344 }
a9430dd8 7345 }
e9edcee0 7346
680cd536
KK
7347 err = snd_hda_attach_beep_device(codec, 0x1);
7348 if (err < 0) {
7349 alc_free(codec);
7350 return err;
7351 }
7352
df694daa 7353 if (board_config != ALC260_AUTO)
e9c364c0 7354 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7355
1da177e4
LT
7356 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7357 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7358 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7359
a3bcba38
TI
7360 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7361 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7362
4ef0ef19
TI
7363 if (!spec->adc_nids && spec->input_mux) {
7364 /* check whether NID 0x04 is valid */
7365 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7366 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7367 /* get type */
7368 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7369 spec->adc_nids = alc260_adc_nids_alt;
7370 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7371 } else {
7372 spec->adc_nids = alc260_adc_nids;
7373 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7374 }
7375 }
b59bdf3b 7376 set_capture_mixer(codec);
45bdd1c1 7377 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7378
b5bfbc67 7379 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7380
2134ea4f
TI
7381 spec->vmaster_nid = 0x08;
7382
1da177e4 7383 codec->patch_ops = alc_patch_ops;
df694daa 7384 if (board_config == ALC260_AUTO)
ae6b813a 7385 spec->init_hook = alc260_auto_init;
cb53c626
TI
7386#ifdef CONFIG_SND_HDA_POWER_SAVE
7387 if (!spec->loopback.amplist)
7388 spec->loopback.amplist = alc260_loopbacks;
7389#endif
1da177e4
LT
7390
7391 return 0;
7392}
7393
e9edcee0 7394
1da177e4 7395/*
4953550a 7396 * ALC882/883/885/888/889 support
1da177e4
LT
7397 *
7398 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7399 * configuration. Each pin widget can choose any input DACs and a mixer.
7400 * Each ADC is connected from a mixer of all inputs. This makes possible
7401 * 6-channel independent captures.
7402 *
7403 * In addition, an independent DAC for the multi-playback (not used in this
7404 * driver yet).
7405 */
df694daa
KY
7406#define ALC882_DIGOUT_NID 0x06
7407#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7408#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7409#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7410#define ALC1200_DIGOUT_NID 0x10
7411
1da177e4 7412
d2a6d7dc 7413static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7414 { 8, NULL }
7415};
7416
4953550a 7417/* DACs */
1da177e4
LT
7418static hda_nid_t alc882_dac_nids[4] = {
7419 /* front, rear, clfe, rear_surr */
7420 0x02, 0x03, 0x04, 0x05
7421};
4953550a 7422#define alc883_dac_nids alc882_dac_nids
1da177e4 7423
4953550a 7424/* ADCs */
df694daa
KY
7425#define alc882_adc_nids alc880_adc_nids
7426#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7427#define alc883_adc_nids alc882_adc_nids_alt
7428static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7429static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7430#define alc889_adc_nids alc880_adc_nids
1da177e4 7431
e1406348
TI
7432static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7433static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7434#define alc883_capsrc_nids alc882_capsrc_nids_alt
7435static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7436#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7437
1da177e4
LT
7438/* input MUX */
7439/* FIXME: should be a matrix-type input source selection */
7440
7441static struct hda_input_mux alc882_capture_source = {
7442 .num_items = 4,
7443 .items = {
7444 { "Mic", 0x0 },
7445 { "Front Mic", 0x1 },
7446 { "Line", 0x2 },
7447 { "CD", 0x4 },
7448 },
7449};
41d5545d 7450
4953550a
TI
7451#define alc883_capture_source alc882_capture_source
7452
87a8c370
JK
7453static struct hda_input_mux alc889_capture_source = {
7454 .num_items = 3,
7455 .items = {
7456 { "Front Mic", 0x0 },
7457 { "Mic", 0x3 },
7458 { "Line", 0x2 },
7459 },
7460};
7461
41d5545d
KS
7462static struct hda_input_mux mb5_capture_source = {
7463 .num_items = 3,
7464 .items = {
7465 { "Mic", 0x1 },
b8f171e7 7466 { "Line", 0x7 },
41d5545d
KS
7467 { "CD", 0x4 },
7468 },
7469};
7470
e458b1fa
LY
7471static struct hda_input_mux macmini3_capture_source = {
7472 .num_items = 2,
7473 .items = {
7474 { "Line", 0x2 },
7475 { "CD", 0x4 },
7476 },
7477};
7478
4953550a
TI
7479static struct hda_input_mux alc883_3stack_6ch_intel = {
7480 .num_items = 4,
7481 .items = {
7482 { "Mic", 0x1 },
7483 { "Front Mic", 0x0 },
7484 { "Line", 0x2 },
7485 { "CD", 0x4 },
7486 },
7487};
7488
7489static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7490 .num_items = 2,
7491 .items = {
7492 { "Mic", 0x1 },
7493 { "Line", 0x2 },
7494 },
7495};
7496
7497static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7498 .num_items = 4,
7499 .items = {
7500 { "Mic", 0x0 },
28c4edb7 7501 { "Internal Mic", 0x1 },
4953550a
TI
7502 { "Line", 0x2 },
7503 { "CD", 0x4 },
7504 },
7505};
7506
7507static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7508 .num_items = 2,
7509 .items = {
7510 { "Mic", 0x0 },
28c4edb7 7511 { "Internal Mic", 0x1 },
4953550a
TI
7512 },
7513};
7514
7515static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7516 .num_items = 3,
7517 .items = {
7518 { "Mic", 0x0 },
7519 { "Front Mic", 0x1 },
7520 { "Line", 0x4 },
7521 },
7522};
7523
7524static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7525 .num_items = 2,
7526 .items = {
7527 { "Mic", 0x0 },
7528 { "Line", 0x2 },
7529 },
7530};
7531
7532static struct hda_input_mux alc889A_mb31_capture_source = {
7533 .num_items = 2,
7534 .items = {
7535 { "Mic", 0x0 },
7536 /* Front Mic (0x01) unused */
7537 { "Line", 0x2 },
7538 /* Line 2 (0x03) unused */
af901ca1 7539 /* CD (0x04) unused? */
4953550a
TI
7540 },
7541};
7542
b7cccc52
JM
7543static struct hda_input_mux alc889A_imac91_capture_source = {
7544 .num_items = 2,
7545 .items = {
7546 { "Mic", 0x01 },
7547 { "Line", 0x2 }, /* Not sure! */
7548 },
7549};
7550
4953550a
TI
7551/*
7552 * 2ch mode
7553 */
7554static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7555 { 2, NULL }
7556};
7557
272a527c
KY
7558/*
7559 * 2ch mode
7560 */
7561static struct hda_verb alc882_3ST_ch2_init[] = {
7562 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7563 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7564 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7565 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7566 { } /* end */
7567};
7568
4953550a
TI
7569/*
7570 * 4ch mode
7571 */
7572static struct hda_verb alc882_3ST_ch4_init[] = {
7573 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7574 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7575 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7576 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7577 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7578 { } /* end */
7579};
7580
272a527c
KY
7581/*
7582 * 6ch mode
7583 */
7584static struct hda_verb alc882_3ST_ch6_init[] = {
7585 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7586 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7587 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7588 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7589 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7590 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7591 { } /* end */
7592};
7593
4953550a 7594static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7595 { 2, alc882_3ST_ch2_init },
4953550a 7596 { 4, alc882_3ST_ch4_init },
272a527c
KY
7597 { 6, alc882_3ST_ch6_init },
7598};
7599
4953550a
TI
7600#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7601
a65cc60f 7602/*
7603 * 2ch mode
7604 */
7605static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7606 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7607 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7608 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7609 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7610 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7611 { } /* end */
7612};
7613
7614/*
7615 * 4ch mode
7616 */
7617static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7618 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7619 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7620 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7621 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7622 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7623 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7624 { } /* end */
7625};
7626
7627/*
7628 * 6ch mode
7629 */
7630static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7631 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7632 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7633 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7634 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7635 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7636 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7637 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7638 { } /* end */
7639};
7640
7641static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7642 { 2, alc883_3ST_ch2_clevo_init },
7643 { 4, alc883_3ST_ch4_clevo_init },
7644 { 6, alc883_3ST_ch6_clevo_init },
7645};
7646
7647
df694daa
KY
7648/*
7649 * 6ch mode
7650 */
7651static struct hda_verb alc882_sixstack_ch6_init[] = {
7652 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7653 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7654 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7655 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7656 { } /* end */
7657};
7658
7659/*
7660 * 8ch mode
7661 */
7662static struct hda_verb alc882_sixstack_ch8_init[] = {
7663 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7664 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7665 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7666 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7667 { } /* end */
7668};
7669
7670static struct hda_channel_mode alc882_sixstack_modes[2] = {
7671 { 6, alc882_sixstack_ch6_init },
7672 { 8, alc882_sixstack_ch8_init },
7673};
7674
76e6f5a9
RH
7675
7676/* Macbook Air 2,1 */
7677
7678static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7679 { 2, NULL },
7680};
7681
87350ad0 7682/*
def319f9 7683 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7684 */
7685
7686/*
7687 * 2ch mode
7688 */
7689static struct hda_verb alc885_mbp_ch2_init[] = {
7690 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7691 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7692 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7693 { } /* end */
7694};
7695
7696/*
a3f730af 7697 * 4ch mode
87350ad0 7698 */
a3f730af 7699static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7700 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7701 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7702 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7703 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7704 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7705 { } /* end */
7706};
7707
a3f730af 7708static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7709 { 2, alc885_mbp_ch2_init },
a3f730af 7710 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7711};
7712
92b9de83
KS
7713/*
7714 * 2ch
7715 * Speakers/Woofer/HP = Front
7716 * LineIn = Input
7717 */
7718static struct hda_verb alc885_mb5_ch2_init[] = {
7719 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7720 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7721 { } /* end */
7722};
7723
7724/*
7725 * 6ch mode
7726 * Speakers/HP = Front
7727 * Woofer = LFE
7728 * LineIn = Surround
7729 */
7730static struct hda_verb alc885_mb5_ch6_init[] = {
7731 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7732 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7733 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7734 { } /* end */
7735};
7736
7737static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7738 { 2, alc885_mb5_ch2_init },
7739 { 6, alc885_mb5_ch6_init },
7740};
87350ad0 7741
d01aecdf 7742#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7743
7744/*
7745 * 2ch mode
7746 */
7747static struct hda_verb alc883_4ST_ch2_init[] = {
7748 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7749 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7750 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7751 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7752 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7753 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7754 { } /* end */
7755};
7756
7757/*
7758 * 4ch mode
7759 */
7760static struct hda_verb alc883_4ST_ch4_init[] = {
7761 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7762 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7763 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7764 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7765 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7766 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7767 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7768 { } /* end */
7769};
7770
7771/*
7772 * 6ch mode
7773 */
7774static struct hda_verb alc883_4ST_ch6_init[] = {
7775 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7776 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7777 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7778 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7779 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7780 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7781 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7782 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7783 { } /* end */
7784};
7785
7786/*
7787 * 8ch mode
7788 */
7789static struct hda_verb alc883_4ST_ch8_init[] = {
7790 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7791 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7792 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7793 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7794 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7795 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7796 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7797 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7798 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7799 { } /* end */
7800};
7801
7802static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7803 { 2, alc883_4ST_ch2_init },
7804 { 4, alc883_4ST_ch4_init },
7805 { 6, alc883_4ST_ch6_init },
7806 { 8, alc883_4ST_ch8_init },
7807};
7808
7809
7810/*
7811 * 2ch mode
7812 */
7813static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7814 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7815 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7816 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7817 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7818 { } /* end */
7819};
7820
7821/*
7822 * 4ch mode
7823 */
7824static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7825 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7826 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7827 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7828 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7829 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7830 { } /* end */
7831};
7832
7833/*
7834 * 6ch mode
7835 */
7836static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7837 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7838 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7839 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7840 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7841 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7842 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7843 { } /* end */
7844};
7845
7846static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7847 { 2, alc883_3ST_ch2_intel_init },
7848 { 4, alc883_3ST_ch4_intel_init },
7849 { 6, alc883_3ST_ch6_intel_init },
7850};
7851
dd7714c9
WF
7852/*
7853 * 2ch mode
7854 */
7855static struct hda_verb alc889_ch2_intel_init[] = {
7856 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7857 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7858 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7859 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7860 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7861 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7862 { } /* end */
7863};
7864
87a8c370
JK
7865/*
7866 * 6ch mode
7867 */
7868static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7869 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7870 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7871 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7872 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7873 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7874 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7875 { } /* end */
7876};
7877
7878/*
7879 * 8ch mode
7880 */
7881static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7882 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7883 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7884 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7885 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7886 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7887 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7888 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7889 { } /* end */
7890};
7891
dd7714c9
WF
7892static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7893 { 2, alc889_ch2_intel_init },
87a8c370
JK
7894 { 6, alc889_ch6_intel_init },
7895 { 8, alc889_ch8_intel_init },
7896};
7897
4953550a
TI
7898/*
7899 * 6ch mode
7900 */
7901static struct hda_verb alc883_sixstack_ch6_init[] = {
7902 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7903 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7904 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7905 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7906 { } /* end */
7907};
7908
7909/*
7910 * 8ch mode
7911 */
7912static struct hda_verb alc883_sixstack_ch8_init[] = {
7913 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7914 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7915 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7916 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7917 { } /* end */
7918};
7919
7920static struct hda_channel_mode alc883_sixstack_modes[2] = {
7921 { 6, alc883_sixstack_ch6_init },
7922 { 8, alc883_sixstack_ch8_init },
7923};
7924
7925
1da177e4
LT
7926/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7927 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7928 */
c8b6bf9b 7929static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7930 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7931 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7932 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7933 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7934 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7935 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7936 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7937 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7938 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7939 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7940 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7941 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7942 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7943 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7944 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7945 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 7946 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
7947 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7948 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 7949 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 7950 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7951 { } /* end */
7952};
7953
76e6f5a9
RH
7954/* Macbook Air 2,1 same control for HP and internal Speaker */
7955
7956static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7957 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7958 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7959 { }
7960};
7961
7962
87350ad0 7963static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7964 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7965 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7966 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7967 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7968 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7970 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7972 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
7973 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7974 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
7975 { } /* end */
7976};
41d5545d
KS
7977
7978static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7980 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7981 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7982 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7983 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7984 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7985 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7986 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7988 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7990 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
7991 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7992 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
7993 { } /* end */
7994};
92b9de83 7995
e458b1fa
LY
7996static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7997 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7998 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7999 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8000 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8001 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8002 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8003 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8004 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8005 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8006 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8007 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8008 { } /* end */
8009};
8010
4b7e1803 8011static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8012 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8013 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8014 { } /* end */
8015};
8016
8017
bdd148a3
KY
8018static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8019 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8020 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8021 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8022 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8023 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8024 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8025 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8026 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8027 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8028 { } /* end */
8029};
8030
272a527c
KY
8031static struct snd_kcontrol_new alc882_targa_mixer[] = {
8032 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8033 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8034 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8035 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8036 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8037 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8038 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8039 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8040 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8041 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8042 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8043 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8044 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8045 { } /* end */
8046};
8047
8048/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8049 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8050 */
8051static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8052 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8053 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8054 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8055 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8056 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8057 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8058 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8059 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8060 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8061 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8063 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8064 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8065 { } /* end */
8066};
8067
914759b7
TI
8068static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8069 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8070 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8072 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8073 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8077 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8078 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8079 { } /* end */
8080};
8081
df694daa
KY
8082static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8083 {
8084 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8085 .name = "Channel Mode",
8086 .info = alc_ch_mode_info,
8087 .get = alc_ch_mode_get,
8088 .put = alc_ch_mode_put,
8089 },
8090 { } /* end */
8091};
8092
4953550a 8093static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8094 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8095 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8096 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8097 /* Rear mixer */
05acb863
TI
8098 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8099 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8100 /* CLFE mixer */
05acb863
TI
8101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8102 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8103 /* Side mixer */
05acb863
TI
8104 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8105 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8106
e9edcee0 8107 /* Front Pin: output 0 (0x0c) */
05acb863 8108 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8109 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8110 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8111 /* Rear Pin: output 1 (0x0d) */
05acb863 8112 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8113 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8114 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8115 /* CLFE Pin: output 2 (0x0e) */
05acb863 8116 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8117 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8118 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8119 /* Side Pin: output 3 (0x0f) */
05acb863 8120 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8121 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8122 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8123 /* Mic (rear) pin: input vref at 80% */
16ded525 8124 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8125 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8126 /* Front Mic pin: input vref at 80% */
16ded525 8127 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8128 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8129 /* Line In pin: input */
05acb863 8130 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8131 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8132 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8133 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8134 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8135 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8136 /* CD pin widget for input */
05acb863 8137 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8138
8139 /* FIXME: use matrix-type input source selection */
8140 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8141 /* Input mixer2 */
05acb863 8142 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8143 /* Input mixer3 */
05acb863 8144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8145 /* ADC2: mute amp left and right */
8146 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8147 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8148 /* ADC3: mute amp left and right */
8149 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8150 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8151
8152 { }
8153};
8154
4953550a
TI
8155static struct hda_verb alc882_adc1_init_verbs[] = {
8156 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8157 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8158 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8159 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8160 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8161 /* ADC1: mute amp left and right */
8162 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8163 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8164 { }
8165};
8166
4b146cb0
TI
8167static struct hda_verb alc882_eapd_verbs[] = {
8168 /* change to EAPD mode */
8169 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8170 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8171 { }
4b146cb0
TI
8172};
8173
87a8c370
JK
8174static struct hda_verb alc889_eapd_verbs[] = {
8175 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8176 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8177 { }
8178};
8179
6732bd0d
WF
8180static struct hda_verb alc_hp15_unsol_verbs[] = {
8181 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8183 {}
8184};
87a8c370
JK
8185
8186static struct hda_verb alc885_init_verbs[] = {
8187 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8189 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8190 /* Rear mixer */
88102f3f
KY
8191 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8192 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8193 /* CLFE mixer */
88102f3f
KY
8194 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8195 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8196 /* Side mixer */
88102f3f
KY
8197 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8198 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8199
8200 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8201 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8202 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8204 /* Front Pin: output 0 (0x0c) */
8205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8206 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8207 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8208 /* Rear Pin: output 1 (0x0d) */
8209 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8210 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8211 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8212 /* CLFE Pin: output 2 (0x0e) */
8213 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8214 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8215 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8216 /* Side Pin: output 3 (0x0f) */
8217 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8218 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8219 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8220 /* Mic (rear) pin: input vref at 80% */
8221 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8223 /* Front Mic pin: input vref at 80% */
8224 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8225 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8226 /* Line In pin: input */
8227 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8228 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8229
8230 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8231 /* Input mixer1 */
88102f3f 8232 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8233 /* Input mixer2 */
8234 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8235 /* Input mixer3 */
88102f3f 8236 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8237 /* ADC2: mute amp left and right */
8238 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8239 /* ADC3: mute amp left and right */
8240 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8241
8242 { }
8243};
8244
8245static struct hda_verb alc885_init_input_verbs[] = {
8246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8247 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8248 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8249 { }
8250};
8251
8252
8253/* Unmute Selector 24h and set the default input to front mic */
8254static struct hda_verb alc889_init_input_verbs[] = {
8255 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8256 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8257 { }
8258};
8259
8260
4953550a
TI
8261#define alc883_init_verbs alc882_base_init_verbs
8262
9102cd1c
TD
8263/* Mac Pro test */
8264static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8265 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8266 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8267 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8268 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8269 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8270 /* FIXME: this looks suspicious...
d355c82a
JK
8271 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8272 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8273 */
9102cd1c
TD
8274 { } /* end */
8275};
8276
8277static struct hda_verb alc882_macpro_init_verbs[] = {
8278 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8279 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8280 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8281 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8282 /* Front Pin: output 0 (0x0c) */
8283 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8284 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8285 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8286 /* Front Mic pin: input vref at 80% */
8287 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8288 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8289 /* Speaker: output */
8290 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8291 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8292 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8293 /* Headphone output (output 0 - 0x0c) */
8294 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8295 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8296 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8297
8298 /* FIXME: use matrix-type input source selection */
8299 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8300 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8303 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8304 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8305 /* Input mixer2 */
8306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8310 /* Input mixer3 */
8311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8315 /* ADC1: mute amp left and right */
8316 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8317 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8318 /* ADC2: mute amp left and right */
8319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8320 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8321 /* ADC3: mute amp left and right */
8322 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8323 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8324
8325 { }
8326};
f12ab1e0 8327
41d5545d
KS
8328/* Macbook 5,1 */
8329static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8330 /* DACs */
8331 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8332 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8333 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8334 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8335 /* Front mixer */
41d5545d
KS
8336 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8337 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8338 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8339 /* Surround mixer */
8340 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8341 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8342 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8343 /* LFE mixer */
8344 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8345 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8346 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8347 /* HP mixer */
8348 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8349 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8350 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8351 /* Front Pin (0x0c) */
41d5545d
KS
8352 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8353 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8354 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8355 /* LFE Pin (0x0e) */
8356 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8357 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8358 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8359 /* HP Pin (0x0f) */
41d5545d
KS
8360 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8361 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8362 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8363 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8364 /* Front Mic pin: input vref at 80% */
8365 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8366 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8367 /* Line In pin */
8368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8369 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8370
b8f171e7
AM
8371 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8372 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8373 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8374 { }
8375};
8376
e458b1fa
LY
8377/* Macmini 3,1 */
8378static struct hda_verb alc885_macmini3_init_verbs[] = {
8379 /* DACs */
8380 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8381 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8382 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8383 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8384 /* Front mixer */
8385 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8387 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8388 /* Surround mixer */
8389 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8390 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8391 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8392 /* LFE mixer */
8393 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8394 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8395 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8396 /* HP mixer */
8397 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8398 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8399 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8400 /* Front Pin (0x0c) */
8401 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8402 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8403 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8404 /* LFE Pin (0x0e) */
8405 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8406 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8407 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8408 /* HP Pin (0x0f) */
8409 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8410 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8411 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8412 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8413 /* Line In pin */
8414 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8415 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8416
8417 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8418 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8419 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8420 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8421 { }
8422};
8423
76e6f5a9
RH
8424
8425static struct hda_verb alc885_mba21_init_verbs[] = {
8426 /*Internal and HP Speaker Mixer*/
8427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8428 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8430 /*Internal Speaker Pin (0x0c)*/
8431 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8433 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8434 /* HP Pin: output 0 (0x0e) */
8435 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8436 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8437 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8438 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8439 /* Line in (is hp when jack connected)*/
8440 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8441 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8442
8443 { }
8444 };
8445
8446
87350ad0
TI
8447/* Macbook Pro rev3 */
8448static struct hda_verb alc885_mbp3_init_verbs[] = {
8449 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8451 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8452 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8453 /* Rear mixer */
8454 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8455 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8456 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8457 /* HP mixer */
8458 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8459 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8460 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8461 /* Front Pin: output 0 (0x0c) */
8462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8463 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8464 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8465 /* HP Pin: output 0 (0x0e) */
87350ad0 8466 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8467 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8468 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8469 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8470 /* Mic (rear) pin: input vref at 80% */
8471 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8472 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8473 /* Front Mic pin: input vref at 80% */
8474 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8475 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8476 /* Line In pin: use output 1 when in LineOut mode */
8477 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8478 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8479 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8480
8481 /* FIXME: use matrix-type input source selection */
8482 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8483 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8484 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8485 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8486 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8487 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8488 /* Input mixer2 */
8489 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8490 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8491 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8492 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8493 /* Input mixer3 */
8494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8496 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8498 /* ADC1: mute amp left and right */
8499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8500 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8501 /* ADC2: mute amp left and right */
8502 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8503 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8504 /* ADC3: mute amp left and right */
8505 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8506 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8507
8508 { }
8509};
8510
4b7e1803
JM
8511/* iMac 9,1 */
8512static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8513 /* Internal Speaker Pin (0x0c) */
8514 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8515 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8516 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8517 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8518 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8519 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8520 /* HP Pin: Rear */
4b7e1803
JM
8521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8523 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8524 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8525 /* Line in Rear */
8526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8528 /* Front Mic pin: input vref at 80% */
8529 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8530 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8531 /* Rear mixer */
8532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8533 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8534 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8535 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8537 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8538 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8539 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8540 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8541 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8542 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8544 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8545 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8546 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8547 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8548 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8549 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8550 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8551 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8552 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8553 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8554 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8555 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8556 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8557 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8558 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8559 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8560 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8561 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8562 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8563 { }
8564};
8565
c54728d8
NF
8566/* iMac 24 mixer. */
8567static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8568 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8569 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8570 { } /* end */
8571};
8572
8573/* iMac 24 init verbs. */
8574static struct hda_verb alc885_imac24_init_verbs[] = {
8575 /* Internal speakers: output 0 (0x0c) */
8576 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8577 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8578 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8579 /* Internal speakers: output 0 (0x0c) */
8580 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8581 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8582 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8583 /* Headphone: output 0 (0x0c) */
8584 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8585 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8586 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8587 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8588 /* Front Mic: input vref at 80% */
8589 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8590 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8591 { }
8592};
8593
8594/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8595static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8596{
a9fd4f3f 8597 struct alc_spec *spec = codec->spec;
c54728d8 8598
a9fd4f3f
TI
8599 spec->autocfg.hp_pins[0] = 0x14;
8600 spec->autocfg.speaker_pins[0] = 0x18;
8601 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8602}
8603
9d54f08b
TI
8604#define alc885_mb5_setup alc885_imac24_setup
8605#define alc885_macmini3_setup alc885_imac24_setup
8606
76e6f5a9
RH
8607/* Macbook Air 2,1 */
8608static void alc885_mba21_setup(struct hda_codec *codec)
8609{
8610 struct alc_spec *spec = codec->spec;
8611
8612 spec->autocfg.hp_pins[0] = 0x14;
8613 spec->autocfg.speaker_pins[0] = 0x18;
8614}
8615
8616
8617
4f5d1706 8618static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8619{
a9fd4f3f 8620 struct alc_spec *spec = codec->spec;
87350ad0 8621
a9fd4f3f
TI
8622 spec->autocfg.hp_pins[0] = 0x15;
8623 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8624}
8625
9d54f08b 8626static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8627{
9d54f08b 8628 struct alc_spec *spec = codec->spec;
4b7e1803 8629
9d54f08b 8630 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8631 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8632 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8633}
87350ad0 8634
272a527c
KY
8635static struct hda_verb alc882_targa_verbs[] = {
8636 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8637 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8638
8639 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8640 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8641
272a527c
KY
8642 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8643 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8644 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8645
8646 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8647 { } /* end */
8648};
8649
8650/* toggle speaker-output according to the hp-jack state */
8651static void alc882_targa_automute(struct hda_codec *codec)
8652{
a9fd4f3f
TI
8653 struct alc_spec *spec = codec->spec;
8654 alc_automute_amp(codec);
82beb8fd 8655 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8656 spec->jack_present ? 1 : 3);
8657}
8658
4f5d1706 8659static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8660{
8661 struct alc_spec *spec = codec->spec;
8662
8663 spec->autocfg.hp_pins[0] = 0x14;
8664 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8665}
8666
8667static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8668{
a9fd4f3f 8669 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8670 alc882_targa_automute(codec);
272a527c
KY
8671}
8672
8673static struct hda_verb alc882_asus_a7j_verbs[] = {
8674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8675 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8676
8677 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8679 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8680
272a527c
KY
8681 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8682 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8683 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8684
8685 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8686 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8687 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8688 { } /* end */
8689};
8690
914759b7
TI
8691static struct hda_verb alc882_asus_a7m_verbs[] = {
8692 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8693 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8694
8695 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8696 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8697 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8698
914759b7
TI
8699 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8700 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8701 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8702
8703 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8704 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8705 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8706 { } /* end */
8707};
8708
9102cd1c
TD
8709static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8710{
8711 unsigned int gpiostate, gpiomask, gpiodir;
8712
8713 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8714 AC_VERB_GET_GPIO_DATA, 0);
8715
8716 if (!muted)
8717 gpiostate |= (1 << pin);
8718 else
8719 gpiostate &= ~(1 << pin);
8720
8721 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8722 AC_VERB_GET_GPIO_MASK, 0);
8723 gpiomask |= (1 << pin);
8724
8725 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8726 AC_VERB_GET_GPIO_DIRECTION, 0);
8727 gpiodir |= (1 << pin);
8728
8729
8730 snd_hda_codec_write(codec, codec->afg, 0,
8731 AC_VERB_SET_GPIO_MASK, gpiomask);
8732 snd_hda_codec_write(codec, codec->afg, 0,
8733 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8734
8735 msleep(1);
8736
8737 snd_hda_codec_write(codec, codec->afg, 0,
8738 AC_VERB_SET_GPIO_DATA, gpiostate);
8739}
8740
7debbe51
TI
8741/* set up GPIO at initialization */
8742static void alc885_macpro_init_hook(struct hda_codec *codec)
8743{
8744 alc882_gpio_mute(codec, 0, 0);
8745 alc882_gpio_mute(codec, 1, 0);
8746}
8747
8748/* set up GPIO and update auto-muting at initialization */
8749static void alc885_imac24_init_hook(struct hda_codec *codec)
8750{
8751 alc885_macpro_init_hook(codec);
4f5d1706 8752 alc_automute_amp(codec);
7debbe51
TI
8753}
8754
df694daa
KY
8755/*
8756 * generic initialization of ADC, input mixers and output mixers
8757 */
4953550a 8758static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8759 /*
8760 * Unmute ADC0-2 and set the default input to mic-in
8761 */
4953550a
TI
8762 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8763 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8764 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8765 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8766
4953550a
TI
8767 /*
8768 * Set up output mixers (0x0c - 0x0f)
8769 */
8770 /* set vol=0 to output mixers */
8771 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8772 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8773 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8774 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8775 /* set up input amps for analog loopback */
8776 /* Amp Indices: DAC = 0, mixer = 1 */
8777 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8778 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8779 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8780 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8781 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8782 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8783 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8784 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8785 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8786 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8787
4953550a
TI
8788 /* FIXME: use matrix-type input source selection */
8789 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8790 /* Input mixer2 */
88102f3f 8791 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8792 /* Input mixer3 */
88102f3f 8793 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8794 { }
9c7f852e
TI
8795};
8796
eb4c41d3
TS
8797/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8798static struct hda_verb alc889A_mb31_ch2_init[] = {
8799 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8800 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8801 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8802 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8803 { } /* end */
8804};
8805
8806/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8807static struct hda_verb alc889A_mb31_ch4_init[] = {
8808 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8809 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8810 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8811 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8812 { } /* end */
8813};
8814
8815/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8816static struct hda_verb alc889A_mb31_ch5_init[] = {
8817 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8818 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8819 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8820 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8821 { } /* end */
8822};
8823
8824/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8825static struct hda_verb alc889A_mb31_ch6_init[] = {
8826 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8827 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8828 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8829 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8830 { } /* end */
8831};
8832
8833static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8834 { 2, alc889A_mb31_ch2_init },
8835 { 4, alc889A_mb31_ch4_init },
8836 { 5, alc889A_mb31_ch5_init },
8837 { 6, alc889A_mb31_ch6_init },
8838};
8839
b373bdeb
AN
8840static struct hda_verb alc883_medion_eapd_verbs[] = {
8841 /* eanable EAPD on medion laptop */
8842 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8843 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8844 { }
8845};
8846
4953550a 8847#define alc883_base_mixer alc882_base_mixer
834be88d 8848
a8848bd6
AS
8849static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8850 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8851 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8852 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8853 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8854 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8855 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8856 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8858 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8859 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8860 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8861 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8862 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8863 { } /* end */
8864};
8865
0c4cc443 8866static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8867 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8868 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8869 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8870 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8871 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8872 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8873 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8874 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8875 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8876 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8877 { } /* end */
8878};
8879
fb97dc67
J
8880static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8881 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8882 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8883 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8884 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8886 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8887 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8888 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8889 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8890 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8891 { } /* end */
8892};
8893
9c7f852e
TI
8894static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8895 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8896 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8898 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8899 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8902 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8903 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8904 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8905 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8906 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8907 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8908 { } /* end */
8909};
df694daa 8910
9c7f852e
TI
8911static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8912 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8913 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8914 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8915 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8916 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8917 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8918 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8919 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8920 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8921 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8922 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8923 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8924 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8925 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8926 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8927 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8928 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8929 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8930 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8931 { } /* end */
8932};
8933
17bba1b7
J
8934static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8935 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8936 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8937 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8938 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8939 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8940 HDA_OUTPUT),
8941 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8942 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8943 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8944 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8945 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8946 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8947 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8948 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8949 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8950 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
8951 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8952 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8953 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 8954 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8955 { } /* end */
8956};
8957
87a8c370
JK
8958static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8959 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8960 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8961 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8962 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8963 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8964 HDA_OUTPUT),
8965 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8966 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8967 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8968 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8969 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8970 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8971 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8972 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8973 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 8974 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
8975 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8977 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
8978 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8979 { } /* end */
8980};
8981
d1d985f0 8982static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8983 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8984 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8985 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8986 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8987 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8992 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8993 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8994 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8995 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8996 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8997 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
8998 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9000 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9001 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9002 { } /* end */
9003};
9004
c259249f 9005static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9006 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9007 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9008 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9009 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9010 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9011 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9012 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9013 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9014 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9015 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9016 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9017 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9018 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9019 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9020 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9021 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9022 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9023 { } /* end */
f12ab1e0 9024};
ccc656ce 9025
c259249f 9026static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9027 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9028 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9030 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9031 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9032 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9033 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9034 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9036 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9037 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9038 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9039 { } /* end */
f12ab1e0 9040};
ccc656ce 9041
b99dba34
TI
9042static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9043 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9044 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9045 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9046 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9047 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9048 { } /* end */
9049};
9050
bc9f98a9
KY
9051static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9052 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9053 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9054 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9055 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9056 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9057 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9058 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9059 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9060 { } /* end */
f12ab1e0 9061};
bc9f98a9 9062
272a527c
KY
9063static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9064 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9065 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9066 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9067 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9068 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9069 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9070 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9071 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9072 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9073 { } /* end */
ea1fb29a 9074};
272a527c 9075
7ad7b218
MC
9076static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9077 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9078 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9079 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9080 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9081 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9082 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9083 { } /* end */
9084};
9085
9086static struct hda_verb alc883_medion_wim2160_verbs[] = {
9087 /* Unmute front mixer */
9088 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9089 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9090
9091 /* Set speaker pin to front mixer */
9092 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9093
9094 /* Init headphone pin */
9095 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9096 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9097 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9098 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9099
9100 { } /* end */
9101};
9102
9103/* toggle speaker-output according to the hp-jack state */
9104static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9105{
9106 struct alc_spec *spec = codec->spec;
9107
9108 spec->autocfg.hp_pins[0] = 0x1a;
9109 spec->autocfg.speaker_pins[0] = 0x15;
9110}
9111
2880a867 9112static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9113 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9114 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9116 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9117 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9118 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9119 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9121 { } /* end */
d1a991a6 9122};
2880a867 9123
d2fd4b09
TV
9124static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9125 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9126 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9127 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9128 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9129 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9130 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9132 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9133 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9134 { } /* end */
9135};
9136
e2757d5e
KY
9137static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9138 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9139 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9140 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9141 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9142 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9143 0x0d, 1, 0x0, HDA_OUTPUT),
9144 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9145 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9146 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9147 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9148 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9149 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9150 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9151 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9152 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9153 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9154 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9155 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9156 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9157 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9158 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9159 { } /* end */
9160};
9161
eb4c41d3
TS
9162static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9163 /* Output mixers */
9164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9165 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9166 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9167 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9168 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9169 HDA_OUTPUT),
9170 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9171 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9172 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9173 /* Output switches */
9174 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9175 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9176 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9177 /* Boost mixers */
5f99f86a
DH
9178 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9179 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9180 /* Input mixers */
9181 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9182 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9183 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9184 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9185 { } /* end */
9186};
9187
3e1647c5
GG
9188static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9189 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9190 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9191 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9192 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9194 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9195 { } /* end */
9196};
9197
e2757d5e
KY
9198static struct hda_bind_ctls alc883_bind_cap_vol = {
9199 .ops = &snd_hda_bind_vol,
9200 .values = {
9201 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9202 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9203 0
9204 },
9205};
9206
9207static struct hda_bind_ctls alc883_bind_cap_switch = {
9208 .ops = &snd_hda_bind_sw,
9209 .values = {
9210 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9211 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9212 0
9213 },
9214};
9215
9216static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9217 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9218 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9219 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9220 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9221 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9222 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9223 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9224 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9225 { } /* end */
9226};
df694daa 9227
4953550a
TI
9228static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9229 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9230 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9231 {
9232 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9233 /* .name = "Capture Source", */
9234 .name = "Input Source",
9235 .count = 1,
9236 .info = alc_mux_enum_info,
9237 .get = alc_mux_enum_get,
9238 .put = alc_mux_enum_put,
9239 },
9240 { } /* end */
9241};
9c7f852e 9242
4953550a
TI
9243static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9244 {
9245 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9246 .name = "Channel Mode",
9247 .info = alc_ch_mode_info,
9248 .get = alc_ch_mode_get,
9249 .put = alc_ch_mode_put,
9250 },
9251 { } /* end */
9c7f852e
TI
9252};
9253
a8848bd6 9254/* toggle speaker-output according to the hp-jack state */
4f5d1706 9255static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9256{
a9fd4f3f 9257 struct alc_spec *spec = codec->spec;
a8848bd6 9258
a9fd4f3f
TI
9259 spec->autocfg.hp_pins[0] = 0x15;
9260 spec->autocfg.speaker_pins[0] = 0x14;
9261 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9262}
9263
a8848bd6
AS
9264static struct hda_verb alc883_mitac_verbs[] = {
9265 /* HP */
9266 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9268 /* Subwoofer */
9269 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9270 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9271
9272 /* enable unsolicited event */
9273 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9274 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9275
9276 { } /* end */
9277};
9278
a65cc60f 9279static struct hda_verb alc883_clevo_m540r_verbs[] = {
9280 /* HP */
9281 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9283 /* Int speaker */
9284 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9285
9286 /* enable unsolicited event */
9287 /*
9288 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9289 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9290 */
9291
9292 { } /* end */
9293};
9294
0c4cc443 9295static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9296 /* HP */
9297 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9298 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9299 /* Int speaker */
9300 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9302
9303 /* enable unsolicited event */
9304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9305 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9306
9307 { } /* end */
9308};
9309
fb97dc67
J
9310static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9311 /* HP */
9312 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9313 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9314 /* Subwoofer */
9315 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9316 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9317
9318 /* enable unsolicited event */
9319 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9320
9321 { } /* end */
9322};
9323
c259249f 9324static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9326 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9327
9328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9329 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9330
64a8be74
DH
9331/* Connect Line-Out side jack (SPDIF) to Side */
9332 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9333 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9334 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9335/* Connect Mic jack to CLFE */
9336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9338 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9339/* Connect Line-in jack to Surround */
9340 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9341 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9342 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9343/* Connect HP out jack to Front */
9344 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9345 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9346 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9347
9348 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9349
9350 { } /* end */
9351};
9352
bc9f98a9
KY
9353static struct hda_verb alc883_lenovo_101e_verbs[] = {
9354 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9355 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9356 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9357 { } /* end */
9358};
9359
272a527c
KY
9360static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9361 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9362 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9363 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9364 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9365 { } /* end */
9366};
9367
9368static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9371 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9372 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9373 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9374 { } /* end */
9375};
9376
189609ae
KY
9377static struct hda_verb alc883_haier_w66_verbs[] = {
9378 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9379 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9380
9381 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9382
9383 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9384 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9385 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9386 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9387 { } /* end */
9388};
9389
e2757d5e
KY
9390static struct hda_verb alc888_lenovo_sky_verbs[] = {
9391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9394 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9395 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9396 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9397 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9398 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9399 { } /* end */
9400};
9401
8718b700
HRK
9402static struct hda_verb alc888_6st_dell_verbs[] = {
9403 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9404 { }
9405};
9406
3e1647c5
GG
9407static struct hda_verb alc883_vaiott_verbs[] = {
9408 /* HP */
9409 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9410 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9411
9412 /* enable unsolicited event */
9413 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9414
9415 { } /* end */
9416};
9417
4f5d1706 9418static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9419{
a9fd4f3f 9420 struct alc_spec *spec = codec->spec;
8718b700 9421
a9fd4f3f
TI
9422 spec->autocfg.hp_pins[0] = 0x1b;
9423 spec->autocfg.speaker_pins[0] = 0x14;
9424 spec->autocfg.speaker_pins[1] = 0x16;
9425 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9426}
9427
4723c022 9428static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9429 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9430 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9431 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9432 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9433 { } /* end */
5795b9e6
CM
9434};
9435
3ea0d7cf
HRK
9436/*
9437 * 2ch mode
9438 */
4723c022 9439static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9440 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9441 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9442 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9443 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9444 { } /* end */
8341de60
CM
9445};
9446
3ea0d7cf
HRK
9447/*
9448 * 4ch mode
9449 */
9450static struct hda_verb alc888_3st_hp_4ch_init[] = {
9451 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9452 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9453 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9454 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9455 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9456 { } /* end */
9457};
9458
9459/*
9460 * 6ch mode
9461 */
4723c022 9462static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9463 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9464 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9465 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9466 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9467 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9468 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9469 { } /* end */
8341de60
CM
9470};
9471
3ea0d7cf 9472static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9473 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9474 { 4, alc888_3st_hp_4ch_init },
4723c022 9475 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9476};
9477
272a527c
KY
9478/* toggle front-jack and RCA according to the hp-jack state */
9479static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9480{
864f92be 9481 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9482
47fd830a
TI
9483 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9484 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9485 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9486 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9487}
9488
9489/* toggle RCA according to the front-jack state */
9490static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9491{
864f92be 9492 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9493
47fd830a
TI
9494 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9495 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9496}
47fd830a 9497
272a527c
KY
9498static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9499 unsigned int res)
9500{
9501 if ((res >> 26) == ALC880_HP_EVENT)
9502 alc888_lenovo_ms7195_front_automute(codec);
9503 if ((res >> 26) == ALC880_FRONT_EVENT)
9504 alc888_lenovo_ms7195_rca_automute(codec);
9505}
9506
272a527c 9507/* toggle speaker-output according to the hp-jack state */
dc427170 9508static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9509{
a9fd4f3f 9510 struct alc_spec *spec = codec->spec;
272a527c 9511
a9fd4f3f
TI
9512 spec->autocfg.hp_pins[0] = 0x14;
9513 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9514}
9515
ccc656ce 9516/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9517#define alc883_targa_init_hook alc882_targa_init_hook
9518#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9519
4f5d1706 9520static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9521{
a9fd4f3f
TI
9522 struct alc_spec *spec = codec->spec;
9523
9524 spec->autocfg.hp_pins[0] = 0x15;
9525 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9526}
9527
9528static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9529{
a9fd4f3f 9530 alc_automute_amp(codec);
eeb43387 9531 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9532}
9533
9534static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9535 unsigned int res)
9536{
0c4cc443 9537 switch (res >> 26) {
0c4cc443 9538 case ALC880_MIC_EVENT:
eeb43387 9539 alc88x_simple_mic_automute(codec);
0c4cc443 9540 break;
a9fd4f3f
TI
9541 default:
9542 alc_automute_amp_unsol_event(codec, res);
9543 break;
0c4cc443 9544 }
368c7a95
J
9545}
9546
fb97dc67 9547/* toggle speaker-output according to the hp-jack state */
4f5d1706 9548static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9549{
a9fd4f3f 9550 struct alc_spec *spec = codec->spec;
fb97dc67 9551
a9fd4f3f
TI
9552 spec->autocfg.hp_pins[0] = 0x14;
9553 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9554}
9555
4f5d1706 9556static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9557{
a9fd4f3f 9558 struct alc_spec *spec = codec->spec;
189609ae 9559
a9fd4f3f
TI
9560 spec->autocfg.hp_pins[0] = 0x1b;
9561 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9562}
9563
bc9f98a9
KY
9564static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9565{
864f92be 9566 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9567
47fd830a
TI
9568 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9569 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9570}
9571
9572static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9573{
864f92be 9574 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9575
47fd830a
TI
9576 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9577 HDA_AMP_MUTE, bits);
9578 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9579 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9580}
9581
9582static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9583 unsigned int res)
9584{
9585 if ((res >> 26) == ALC880_HP_EVENT)
9586 alc883_lenovo_101e_all_automute(codec);
9587 if ((res >> 26) == ALC880_FRONT_EVENT)
9588 alc883_lenovo_101e_ispeaker_automute(codec);
9589}
9590
676a9b53 9591/* toggle speaker-output according to the hp-jack state */
4f5d1706 9592static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9593{
a9fd4f3f 9594 struct alc_spec *spec = codec->spec;
676a9b53 9595
a9fd4f3f
TI
9596 spec->autocfg.hp_pins[0] = 0x14;
9597 spec->autocfg.speaker_pins[0] = 0x15;
9598 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9599}
9600
d1a991a6
KY
9601static struct hda_verb alc883_acer_eapd_verbs[] = {
9602 /* HP Pin: output 0 (0x0c) */
9603 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9604 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9605 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9606 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9607 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9608 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9609 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9610 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9611 /* eanable EAPD on medion laptop */
9612 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9613 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9614 /* enable unsolicited event */
9615 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9616 { }
9617};
9618
4f5d1706 9619static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9620{
a9fd4f3f 9621 struct alc_spec *spec = codec->spec;
5795b9e6 9622
a9fd4f3f
TI
9623 spec->autocfg.hp_pins[0] = 0x1b;
9624 spec->autocfg.speaker_pins[0] = 0x14;
9625 spec->autocfg.speaker_pins[1] = 0x15;
9626 spec->autocfg.speaker_pins[2] = 0x16;
9627 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9628}
9629
4f5d1706 9630static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9631{
a9fd4f3f 9632 struct alc_spec *spec = codec->spec;
e2757d5e 9633
a9fd4f3f
TI
9634 spec->autocfg.hp_pins[0] = 0x1b;
9635 spec->autocfg.speaker_pins[0] = 0x14;
9636 spec->autocfg.speaker_pins[1] = 0x15;
9637 spec->autocfg.speaker_pins[2] = 0x16;
9638 spec->autocfg.speaker_pins[3] = 0x17;
9639 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9640}
9641
4f5d1706 9642static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9643{
9644 struct alc_spec *spec = codec->spec;
9645
9646 spec->autocfg.hp_pins[0] = 0x15;
9647 spec->autocfg.speaker_pins[0] = 0x14;
9648 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9649}
9650
e2757d5e
KY
9651static struct hda_verb alc888_asus_m90v_verbs[] = {
9652 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9653 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9655 /* enable unsolicited event */
9656 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9657 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9658 { } /* end */
9659};
9660
4f5d1706 9661static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9662{
a9fd4f3f 9663 struct alc_spec *spec = codec->spec;
e2757d5e 9664
a9fd4f3f
TI
9665 spec->autocfg.hp_pins[0] = 0x1b;
9666 spec->autocfg.speaker_pins[0] = 0x14;
9667 spec->autocfg.speaker_pins[1] = 0x15;
9668 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9669 spec->ext_mic.pin = 0x18;
9670 spec->int_mic.pin = 0x19;
9671 spec->ext_mic.mux_idx = 0;
9672 spec->int_mic.mux_idx = 1;
9673 spec->auto_mic = 1;
e2757d5e
KY
9674}
9675
9676static struct hda_verb alc888_asus_eee1601_verbs[] = {
9677 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9678 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9679 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9680 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9681 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9682 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9683 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9684 /* enable unsolicited event */
9685 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9686 { } /* end */
9687};
9688
e2757d5e
KY
9689static void alc883_eee1601_inithook(struct hda_codec *codec)
9690{
a9fd4f3f
TI
9691 struct alc_spec *spec = codec->spec;
9692
9693 spec->autocfg.hp_pins[0] = 0x14;
9694 spec->autocfg.speaker_pins[0] = 0x1b;
9695 alc_automute_pin(codec);
e2757d5e
KY
9696}
9697
eb4c41d3
TS
9698static struct hda_verb alc889A_mb31_verbs[] = {
9699 /* Init rear pin (used as headphone output) */
9700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9701 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9702 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9703 /* Init line pin (used as output in 4ch and 6ch mode) */
9704 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9705 /* Init line 2 pin (used as headphone out by default) */
9706 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9707 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9708 { } /* end */
9709};
9710
9711/* Mute speakers according to the headphone jack state */
9712static void alc889A_mb31_automute(struct hda_codec *codec)
9713{
9714 unsigned int present;
9715
9716 /* Mute only in 2ch or 4ch mode */
9717 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9718 == 0x00) {
864f92be 9719 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9720 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9721 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9722 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9723 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9724 }
9725}
9726
9727static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9728{
9729 if ((res >> 26) == ALC880_HP_EVENT)
9730 alc889A_mb31_automute(codec);
9731}
9732
4953550a 9733
cb53c626 9734#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9735#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9736#endif
9737
def319f9 9738/* pcm configuration: identical with ALC880 */
4953550a
TI
9739#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9740#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9741#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9742#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9743
9744static hda_nid_t alc883_slave_dig_outs[] = {
9745 ALC1200_DIGOUT_NID, 0,
9746};
9747
9748static hda_nid_t alc1200_slave_dig_outs[] = {
9749 ALC883_DIGOUT_NID, 0,
9750};
9c7f852e
TI
9751
9752/*
9753 * configuration and preset
9754 */
ea734963 9755static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9756 [ALC882_3ST_DIG] = "3stack-dig",
9757 [ALC882_6ST_DIG] = "6stack-dig",
9758 [ALC882_ARIMA] = "arima",
9759 [ALC882_W2JC] = "w2jc",
9760 [ALC882_TARGA] = "targa",
9761 [ALC882_ASUS_A7J] = "asus-a7j",
9762 [ALC882_ASUS_A7M] = "asus-a7m",
9763 [ALC885_MACPRO] = "macpro",
9764 [ALC885_MB5] = "mb5",
e458b1fa 9765 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9766 [ALC885_MBA21] = "mba21",
4953550a
TI
9767 [ALC885_MBP3] = "mbp3",
9768 [ALC885_IMAC24] = "imac24",
4b7e1803 9769 [ALC885_IMAC91] = "imac91",
4953550a 9770 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9771 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9772 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9773 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9774 [ALC883_TARGA_DIG] = "targa-dig",
9775 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9776 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9777 [ALC883_ACER] = "acer",
2880a867 9778 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9779 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9780 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9781 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9782 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9783 [ALC883_MEDION] = "medion",
7ad7b218 9784 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9785 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9786 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9787 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9788 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9789 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9790 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9791 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9792 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9793 [ALC883_MITAC] = "mitac",
a65cc60f 9794 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9795 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9796 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9797 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9798 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9799 [ALC889A_INTEL] = "intel-alc889a",
9800 [ALC889_INTEL] = "intel-x58",
3ab90935 9801 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9802 [ALC889A_MB31] = "mb31",
3e1647c5 9803 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9804 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9805};
9806
4953550a
TI
9807static struct snd_pci_quirk alc882_cfg_tbl[] = {
9808 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9809
ac3e3741 9810 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9811 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9812 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9813 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9814 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9815 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9816 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9817 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9818 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9819 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9820 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9821 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9822 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9823 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9824 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9825 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9826 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9827 ALC888_ACER_ASPIRE_6530G),
cc374c47 9828 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9829 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9830 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9831 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9832 /* default Acer -- disabled as it causes more problems.
9833 * model=auto should work fine now
9834 */
9835 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9836
5795b9e6 9837 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9838
febe3375 9839 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9840 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9841 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9842 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9843 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9844 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9845
9846 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9847 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9848 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9849 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9850 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9851 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9852 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9853 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9854 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9855 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9856 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9857
9858 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9859 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9860 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9861 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9862 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9863 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9864 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9865 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a 9866
6f3bf657 9867 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9868 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9869 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9870 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9871 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9872 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9873 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9874 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9875 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9876 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9877 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9878 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9879 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9880 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9881 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9882 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9883 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9884 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9885 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9886 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9887 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9888 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9889 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9890 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9891 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9892 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9893 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9894 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9895 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9896 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9897 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9898
ac3e3741 9899 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9900 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9901 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9902 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9903 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9904 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9905 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9906 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9907 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9908 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9909 ALC883_FUJITSU_PI2515),
bfb53037 9910 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9911 ALC888_FUJITSU_XA3530),
272a527c 9912 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9913 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9914 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9915 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9916 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9917 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9918 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9919 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9920
17bba1b7
J
9921 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9922 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9923 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9924 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9925 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9926 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9927 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9928
4953550a 9929 {}
f3cd3f5d
WF
9930};
9931
4953550a
TI
9932/* codec SSID table for Intel Mac */
9933static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9934 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9935 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9936 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9937 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9938 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9939 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9940 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9941 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9942 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9943 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9944 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9945 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9946 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9947 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9948 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9949 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9950 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9951 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9952 * so apparently no perfect solution yet
4953550a
TI
9953 */
9954 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9955 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9956 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9957 {} /* terminator */
b25c9da1
WF
9958};
9959
4953550a
TI
9960static struct alc_config_preset alc882_presets[] = {
9961 [ALC882_3ST_DIG] = {
9962 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9963 .init_verbs = { alc882_base_init_verbs,
9964 alc882_adc1_init_verbs },
4953550a
TI
9965 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9966 .dac_nids = alc882_dac_nids,
9967 .dig_out_nid = ALC882_DIGOUT_NID,
9968 .dig_in_nid = ALC882_DIGIN_NID,
9969 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9970 .channel_mode = alc882_ch_modes,
9971 .need_dac_fix = 1,
9972 .input_mux = &alc882_capture_source,
9973 },
9974 [ALC882_6ST_DIG] = {
9975 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9976 .init_verbs = { alc882_base_init_verbs,
9977 alc882_adc1_init_verbs },
4953550a
TI
9978 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9979 .dac_nids = alc882_dac_nids,
9980 .dig_out_nid = ALC882_DIGOUT_NID,
9981 .dig_in_nid = ALC882_DIGIN_NID,
9982 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9983 .channel_mode = alc882_sixstack_modes,
9984 .input_mux = &alc882_capture_source,
9985 },
9986 [ALC882_ARIMA] = {
9987 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9988 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9989 alc882_eapd_verbs },
4953550a
TI
9990 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9991 .dac_nids = alc882_dac_nids,
9992 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9993 .channel_mode = alc882_sixstack_modes,
9994 .input_mux = &alc882_capture_source,
9995 },
9996 [ALC882_W2JC] = {
9997 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9998 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9999 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10000 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10001 .dac_nids = alc882_dac_nids,
10002 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10003 .channel_mode = alc880_threestack_modes,
10004 .need_dac_fix = 1,
10005 .input_mux = &alc882_capture_source,
10006 .dig_out_nid = ALC882_DIGOUT_NID,
10007 },
76e6f5a9
RH
10008 [ALC885_MBA21] = {
10009 .mixers = { alc885_mba21_mixer },
10010 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10011 .num_dacs = 2,
10012 .dac_nids = alc882_dac_nids,
10013 .channel_mode = alc885_mba21_ch_modes,
10014 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10015 .input_mux = &alc882_capture_source,
10016 .unsol_event = alc_automute_amp_unsol_event,
10017 .setup = alc885_mba21_setup,
10018 .init_hook = alc_automute_amp,
10019 },
4953550a
TI
10020 [ALC885_MBP3] = {
10021 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10022 .init_verbs = { alc885_mbp3_init_verbs,
10023 alc880_gpio1_init_verbs },
be0ae923 10024 .num_dacs = 2,
4953550a 10025 .dac_nids = alc882_dac_nids,
be0ae923
TI
10026 .hp_nid = 0x04,
10027 .channel_mode = alc885_mbp_4ch_modes,
10028 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10029 .input_mux = &alc882_capture_source,
10030 .dig_out_nid = ALC882_DIGOUT_NID,
10031 .dig_in_nid = ALC882_DIGIN_NID,
10032 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10033 .setup = alc885_mbp3_setup,
10034 .init_hook = alc_automute_amp,
4953550a
TI
10035 },
10036 [ALC885_MB5] = {
10037 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10038 .init_verbs = { alc885_mb5_init_verbs,
10039 alc880_gpio1_init_verbs },
10040 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10041 .dac_nids = alc882_dac_nids,
10042 .channel_mode = alc885_mb5_6ch_modes,
10043 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10044 .input_mux = &mb5_capture_source,
10045 .dig_out_nid = ALC882_DIGOUT_NID,
10046 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10047 .unsol_event = alc_automute_amp_unsol_event,
10048 .setup = alc885_mb5_setup,
10049 .init_hook = alc_automute_amp,
4953550a 10050 },
e458b1fa
LY
10051 [ALC885_MACMINI3] = {
10052 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10053 .init_verbs = { alc885_macmini3_init_verbs,
10054 alc880_gpio1_init_verbs },
10055 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10056 .dac_nids = alc882_dac_nids,
10057 .channel_mode = alc885_macmini3_6ch_modes,
10058 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10059 .input_mux = &macmini3_capture_source,
10060 .dig_out_nid = ALC882_DIGOUT_NID,
10061 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10062 .unsol_event = alc_automute_amp_unsol_event,
10063 .setup = alc885_macmini3_setup,
10064 .init_hook = alc_automute_amp,
e458b1fa 10065 },
4953550a
TI
10066 [ALC885_MACPRO] = {
10067 .mixers = { alc882_macpro_mixer },
10068 .init_verbs = { alc882_macpro_init_verbs },
10069 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10070 .dac_nids = alc882_dac_nids,
10071 .dig_out_nid = ALC882_DIGOUT_NID,
10072 .dig_in_nid = ALC882_DIGIN_NID,
10073 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10074 .channel_mode = alc882_ch_modes,
10075 .input_mux = &alc882_capture_source,
10076 .init_hook = alc885_macpro_init_hook,
10077 },
10078 [ALC885_IMAC24] = {
10079 .mixers = { alc885_imac24_mixer },
10080 .init_verbs = { alc885_imac24_init_verbs },
10081 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10082 .dac_nids = alc882_dac_nids,
10083 .dig_out_nid = ALC882_DIGOUT_NID,
10084 .dig_in_nid = ALC882_DIGIN_NID,
10085 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10086 .channel_mode = alc882_ch_modes,
10087 .input_mux = &alc882_capture_source,
10088 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 10089 .setup = alc885_imac24_setup,
4953550a
TI
10090 .init_hook = alc885_imac24_init_hook,
10091 },
4b7e1803 10092 [ALC885_IMAC91] = {
b7cccc52 10093 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10094 .init_verbs = { alc885_imac91_init_verbs,
10095 alc880_gpio1_init_verbs },
10096 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10097 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10098 .channel_mode = alc885_mba21_ch_modes,
10099 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10100 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10101 .dig_out_nid = ALC882_DIGOUT_NID,
10102 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10103 .unsol_event = alc_automute_amp_unsol_event,
10104 .setup = alc885_imac91_setup,
10105 .init_hook = alc_automute_amp,
4b7e1803 10106 },
4953550a
TI
10107 [ALC882_TARGA] = {
10108 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10109 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10110 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10111 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10112 .dac_nids = alc882_dac_nids,
10113 .dig_out_nid = ALC882_DIGOUT_NID,
10114 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10115 .adc_nids = alc882_adc_nids,
10116 .capsrc_nids = alc882_capsrc_nids,
10117 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10118 .channel_mode = alc882_3ST_6ch_modes,
10119 .need_dac_fix = 1,
10120 .input_mux = &alc882_capture_source,
10121 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10122 .setup = alc882_targa_setup,
10123 .init_hook = alc882_targa_automute,
4953550a
TI
10124 },
10125 [ALC882_ASUS_A7J] = {
10126 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10127 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10128 alc882_asus_a7j_verbs},
4953550a
TI
10129 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10130 .dac_nids = alc882_dac_nids,
10131 .dig_out_nid = ALC882_DIGOUT_NID,
10132 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10133 .adc_nids = alc882_adc_nids,
10134 .capsrc_nids = alc882_capsrc_nids,
10135 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10136 .channel_mode = alc882_3ST_6ch_modes,
10137 .need_dac_fix = 1,
10138 .input_mux = &alc882_capture_source,
10139 },
10140 [ALC882_ASUS_A7M] = {
10141 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10142 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10143 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10144 alc882_asus_a7m_verbs },
10145 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10146 .dac_nids = alc882_dac_nids,
10147 .dig_out_nid = ALC882_DIGOUT_NID,
10148 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10149 .channel_mode = alc880_threestack_modes,
10150 .need_dac_fix = 1,
10151 .input_mux = &alc882_capture_source,
10152 },
9c7f852e
TI
10153 [ALC883_3ST_2ch_DIG] = {
10154 .mixers = { alc883_3ST_2ch_mixer },
10155 .init_verbs = { alc883_init_verbs },
10156 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10157 .dac_nids = alc883_dac_nids,
10158 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10159 .dig_in_nid = ALC883_DIGIN_NID,
10160 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10161 .channel_mode = alc883_3ST_2ch_modes,
10162 .input_mux = &alc883_capture_source,
10163 },
10164 [ALC883_3ST_6ch_DIG] = {
10165 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10166 .init_verbs = { alc883_init_verbs },
10167 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10168 .dac_nids = alc883_dac_nids,
10169 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10170 .dig_in_nid = ALC883_DIGIN_NID,
10171 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10172 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10173 .need_dac_fix = 1,
9c7f852e 10174 .input_mux = &alc883_capture_source,
f12ab1e0 10175 },
9c7f852e
TI
10176 [ALC883_3ST_6ch] = {
10177 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10178 .init_verbs = { alc883_init_verbs },
10179 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10180 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10181 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10182 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10183 .need_dac_fix = 1,
9c7f852e 10184 .input_mux = &alc883_capture_source,
f12ab1e0 10185 },
17bba1b7
J
10186 [ALC883_3ST_6ch_INTEL] = {
10187 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10188 .init_verbs = { alc883_init_verbs },
10189 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10190 .dac_nids = alc883_dac_nids,
10191 .dig_out_nid = ALC883_DIGOUT_NID,
10192 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10193 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10194 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10195 .channel_mode = alc883_3ST_6ch_intel_modes,
10196 .need_dac_fix = 1,
10197 .input_mux = &alc883_3stack_6ch_intel,
10198 },
87a8c370
JK
10199 [ALC889A_INTEL] = {
10200 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10201 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10202 alc_hp15_unsol_verbs },
87a8c370
JK
10203 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10204 .dac_nids = alc883_dac_nids,
10205 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10206 .adc_nids = alc889_adc_nids,
10207 .dig_out_nid = ALC883_DIGOUT_NID,
10208 .dig_in_nid = ALC883_DIGIN_NID,
10209 .slave_dig_outs = alc883_slave_dig_outs,
10210 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10211 .channel_mode = alc889_8ch_intel_modes,
10212 .capsrc_nids = alc889_capsrc_nids,
10213 .input_mux = &alc889_capture_source,
4f5d1706
TI
10214 .setup = alc889_automute_setup,
10215 .init_hook = alc_automute_amp,
6732bd0d 10216 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10217 .need_dac_fix = 1,
10218 },
10219 [ALC889_INTEL] = {
10220 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10221 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10222 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10223 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10224 .dac_nids = alc883_dac_nids,
10225 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10226 .adc_nids = alc889_adc_nids,
10227 .dig_out_nid = ALC883_DIGOUT_NID,
10228 .dig_in_nid = ALC883_DIGIN_NID,
10229 .slave_dig_outs = alc883_slave_dig_outs,
10230 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10231 .channel_mode = alc889_8ch_intel_modes,
10232 .capsrc_nids = alc889_capsrc_nids,
10233 .input_mux = &alc889_capture_source,
4f5d1706 10234 .setup = alc889_automute_setup,
6732bd0d
WF
10235 .init_hook = alc889_intel_init_hook,
10236 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10237 .need_dac_fix = 1,
10238 },
9c7f852e
TI
10239 [ALC883_6ST_DIG] = {
10240 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10241 .init_verbs = { alc883_init_verbs },
10242 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10243 .dac_nids = alc883_dac_nids,
10244 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10245 .dig_in_nid = ALC883_DIGIN_NID,
10246 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10247 .channel_mode = alc883_sixstack_modes,
10248 .input_mux = &alc883_capture_source,
10249 },
ccc656ce 10250 [ALC883_TARGA_DIG] = {
c259249f 10251 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10252 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10253 alc883_targa_verbs},
ccc656ce
KY
10254 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10255 .dac_nids = alc883_dac_nids,
10256 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10257 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10258 .channel_mode = alc883_3ST_6ch_modes,
10259 .need_dac_fix = 1,
10260 .input_mux = &alc883_capture_source,
c259249f 10261 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10262 .setup = alc882_targa_setup,
10263 .init_hook = alc882_targa_automute,
ccc656ce
KY
10264 },
10265 [ALC883_TARGA_2ch_DIG] = {
c259249f 10266 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10267 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10268 alc883_targa_verbs},
ccc656ce
KY
10269 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10270 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10271 .adc_nids = alc883_adc_nids_alt,
10272 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10273 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10274 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10275 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10276 .channel_mode = alc883_3ST_2ch_modes,
10277 .input_mux = &alc883_capture_source,
c259249f 10278 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10279 .setup = alc882_targa_setup,
10280 .init_hook = alc882_targa_automute,
ccc656ce 10281 },
64a8be74 10282 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10283 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10284 alc883_chmode_mixer },
64a8be74 10285 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10286 alc883_targa_verbs },
64a8be74
DH
10287 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10288 .dac_nids = alc883_dac_nids,
10289 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10290 .adc_nids = alc883_adc_nids_rev,
10291 .capsrc_nids = alc883_capsrc_nids_rev,
10292 .dig_out_nid = ALC883_DIGOUT_NID,
10293 .dig_in_nid = ALC883_DIGIN_NID,
10294 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10295 .channel_mode = alc883_4ST_8ch_modes,
10296 .need_dac_fix = 1,
10297 .input_mux = &alc883_capture_source,
c259249f 10298 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10299 .setup = alc882_targa_setup,
10300 .init_hook = alc882_targa_automute,
64a8be74 10301 },
bab282b9 10302 [ALC883_ACER] = {
676a9b53 10303 .mixers = { alc883_base_mixer },
bab282b9
VA
10304 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10305 * and the headphone jack. Turn this on and rely on the
10306 * standard mute methods whenever the user wants to turn
10307 * these outputs off.
10308 */
10309 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10310 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10311 .dac_nids = alc883_dac_nids,
bab282b9
VA
10312 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10313 .channel_mode = alc883_3ST_2ch_modes,
10314 .input_mux = &alc883_capture_source,
10315 },
2880a867 10316 [ALC883_ACER_ASPIRE] = {
676a9b53 10317 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10318 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10319 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10320 .dac_nids = alc883_dac_nids,
10321 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10322 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10323 .channel_mode = alc883_3ST_2ch_modes,
10324 .input_mux = &alc883_capture_source,
a9fd4f3f 10325 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10326 .setup = alc883_acer_aspire_setup,
10327 .init_hook = alc_automute_amp,
d1a991a6 10328 },
5b2d1eca 10329 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10330 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10331 alc883_chmode_mixer },
10332 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10333 alc888_acer_aspire_4930g_verbs },
10334 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10335 .dac_nids = alc883_dac_nids,
10336 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10337 .adc_nids = alc883_adc_nids_rev,
10338 .capsrc_nids = alc883_capsrc_nids_rev,
10339 .dig_out_nid = ALC883_DIGOUT_NID,
10340 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10341 .channel_mode = alc883_3ST_6ch_modes,
10342 .need_dac_fix = 1,
973b8cb0 10343 .const_channel_count = 6,
5b2d1eca 10344 .num_mux_defs =
ef8ef5fb
VP
10345 ARRAY_SIZE(alc888_2_capture_sources),
10346 .input_mux = alc888_2_capture_sources,
d2fd4b09 10347 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10348 .setup = alc888_acer_aspire_4930g_setup,
10349 .init_hook = alc_automute_amp,
d2fd4b09
TV
10350 },
10351 [ALC888_ACER_ASPIRE_6530G] = {
10352 .mixers = { alc888_acer_aspire_6530_mixer },
10353 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10354 alc888_acer_aspire_6530g_verbs },
10355 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10356 .dac_nids = alc883_dac_nids,
10357 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10358 .adc_nids = alc883_adc_nids_rev,
10359 .capsrc_nids = alc883_capsrc_nids_rev,
10360 .dig_out_nid = ALC883_DIGOUT_NID,
10361 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10362 .channel_mode = alc883_3ST_2ch_modes,
10363 .num_mux_defs =
10364 ARRAY_SIZE(alc888_2_capture_sources),
10365 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10366 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10367 .setup = alc888_acer_aspire_6530g_setup,
10368 .init_hook = alc_automute_amp,
5b2d1eca 10369 },
3b315d70 10370 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10371 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10372 alc883_chmode_mixer },
10373 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10374 alc889_acer_aspire_8930g_verbs,
10375 alc889_eapd_verbs},
3b315d70
HM
10376 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10377 .dac_nids = alc883_dac_nids,
018df418
HM
10378 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10379 .adc_nids = alc889_adc_nids,
10380 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10381 .dig_out_nid = ALC883_DIGOUT_NID,
10382 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10383 .channel_mode = alc883_3ST_6ch_modes,
10384 .need_dac_fix = 1,
10385 .const_channel_count = 6,
10386 .num_mux_defs =
018df418
HM
10387 ARRAY_SIZE(alc889_capture_sources),
10388 .input_mux = alc889_capture_sources,
3b315d70 10389 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10390 .setup = alc889_acer_aspire_8930g_setup,
10391 .init_hook = alc_automute_amp,
f5de24b0 10392#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10393 .power_hook = alc_power_eapd,
f5de24b0 10394#endif
3b315d70 10395 },
fc86f954
DK
10396 [ALC888_ACER_ASPIRE_7730G] = {
10397 .mixers = { alc883_3ST_6ch_mixer,
10398 alc883_chmode_mixer },
10399 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10400 alc888_acer_aspire_7730G_verbs },
10401 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10402 .dac_nids = alc883_dac_nids,
10403 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10404 .adc_nids = alc883_adc_nids_rev,
10405 .capsrc_nids = alc883_capsrc_nids_rev,
10406 .dig_out_nid = ALC883_DIGOUT_NID,
10407 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10408 .channel_mode = alc883_3ST_6ch_modes,
10409 .need_dac_fix = 1,
10410 .const_channel_count = 6,
10411 .input_mux = &alc883_capture_source,
10412 .unsol_event = alc_automute_amp_unsol_event,
d9477207 10413 .setup = alc888_acer_aspire_7730g_setup,
fc86f954
DK
10414 .init_hook = alc_automute_amp,
10415 },
c07584c8
TD
10416 [ALC883_MEDION] = {
10417 .mixers = { alc883_fivestack_mixer,
10418 alc883_chmode_mixer },
10419 .init_verbs = { alc883_init_verbs,
b373bdeb 10420 alc883_medion_eapd_verbs },
c07584c8
TD
10421 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10422 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10423 .adc_nids = alc883_adc_nids_alt,
10424 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10425 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10426 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10427 .channel_mode = alc883_sixstack_modes,
10428 .input_mux = &alc883_capture_source,
b373bdeb 10429 },
7ad7b218
MC
10430 [ALC883_MEDION_WIM2160] = {
10431 .mixers = { alc883_medion_wim2160_mixer },
10432 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10433 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10434 .dac_nids = alc883_dac_nids,
10435 .dig_out_nid = ALC883_DIGOUT_NID,
10436 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10437 .adc_nids = alc883_adc_nids,
10438 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10439 .channel_mode = alc883_3ST_2ch_modes,
10440 .input_mux = &alc883_capture_source,
10441 .unsol_event = alc_automute_amp_unsol_event,
10442 .setup = alc883_medion_wim2160_setup,
10443 .init_hook = alc_automute_amp,
10444 },
b373bdeb 10445 [ALC883_LAPTOP_EAPD] = {
676a9b53 10446 .mixers = { alc883_base_mixer },
b373bdeb
AN
10447 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10448 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10449 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10450 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10451 .channel_mode = alc883_3ST_2ch_modes,
10452 .input_mux = &alc883_capture_source,
10453 },
a65cc60f 10454 [ALC883_CLEVO_M540R] = {
10455 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10456 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10457 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10458 .dac_nids = alc883_dac_nids,
10459 .dig_out_nid = ALC883_DIGOUT_NID,
10460 .dig_in_nid = ALC883_DIGIN_NID,
10461 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10462 .channel_mode = alc883_3ST_6ch_clevo_modes,
10463 .need_dac_fix = 1,
10464 .input_mux = &alc883_capture_source,
10465 /* This machine has the hardware HP auto-muting, thus
10466 * we need no software mute via unsol event
10467 */
10468 },
0c4cc443
HRK
10469 [ALC883_CLEVO_M720] = {
10470 .mixers = { alc883_clevo_m720_mixer },
10471 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10472 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10473 .dac_nids = alc883_dac_nids,
10474 .dig_out_nid = ALC883_DIGOUT_NID,
10475 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10476 .channel_mode = alc883_3ST_2ch_modes,
10477 .input_mux = &alc883_capture_source,
0c4cc443 10478 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10479 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10480 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10481 },
bc9f98a9
KY
10482 [ALC883_LENOVO_101E_2ch] = {
10483 .mixers = { alc883_lenovo_101e_2ch_mixer},
10484 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10485 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10486 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10487 .adc_nids = alc883_adc_nids_alt,
10488 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10489 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10490 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10491 .channel_mode = alc883_3ST_2ch_modes,
10492 .input_mux = &alc883_lenovo_101e_capture_source,
10493 .unsol_event = alc883_lenovo_101e_unsol_event,
10494 .init_hook = alc883_lenovo_101e_all_automute,
10495 },
272a527c
KY
10496 [ALC883_LENOVO_NB0763] = {
10497 .mixers = { alc883_lenovo_nb0763_mixer },
10498 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10499 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10500 .dac_nids = alc883_dac_nids,
272a527c
KY
10501 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10502 .channel_mode = alc883_3ST_2ch_modes,
10503 .need_dac_fix = 1,
10504 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10505 .unsol_event = alc_automute_amp_unsol_event,
dc427170 10506 .setup = alc883_lenovo_nb0763_setup,
4f5d1706 10507 .init_hook = alc_automute_amp,
272a527c
KY
10508 },
10509 [ALC888_LENOVO_MS7195_DIG] = {
10510 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10511 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10512 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10513 .dac_nids = alc883_dac_nids,
10514 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10515 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10516 .channel_mode = alc883_3ST_6ch_modes,
10517 .need_dac_fix = 1,
10518 .input_mux = &alc883_capture_source,
10519 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10520 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10521 },
10522 [ALC883_HAIER_W66] = {
c259249f 10523 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10524 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10525 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10526 .dac_nids = alc883_dac_nids,
10527 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10528 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10529 .channel_mode = alc883_3ST_2ch_modes,
10530 .input_mux = &alc883_capture_source,
a9fd4f3f 10531 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10532 .setup = alc883_haier_w66_setup,
10533 .init_hook = alc_automute_amp,
eea6419e 10534 },
4723c022 10535 [ALC888_3ST_HP] = {
eea6419e 10536 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10537 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10538 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10539 .dac_nids = alc883_dac_nids,
4723c022
CM
10540 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10541 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10542 .need_dac_fix = 1,
10543 .input_mux = &alc883_capture_source,
a9fd4f3f 10544 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10545 .setup = alc888_3st_hp_setup,
10546 .init_hook = alc_automute_amp,
8341de60 10547 },
5795b9e6 10548 [ALC888_6ST_DELL] = {
f24dbdc6 10549 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10550 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10551 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10552 .dac_nids = alc883_dac_nids,
10553 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10554 .dig_in_nid = ALC883_DIGIN_NID,
10555 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10556 .channel_mode = alc883_sixstack_modes,
10557 .input_mux = &alc883_capture_source,
a9fd4f3f 10558 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10559 .setup = alc888_6st_dell_setup,
10560 .init_hook = alc_automute_amp,
5795b9e6 10561 },
a8848bd6
AS
10562 [ALC883_MITAC] = {
10563 .mixers = { alc883_mitac_mixer },
10564 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10565 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10566 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10567 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10568 .channel_mode = alc883_3ST_2ch_modes,
10569 .input_mux = &alc883_capture_source,
a9fd4f3f 10570 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10571 .setup = alc883_mitac_setup,
10572 .init_hook = alc_automute_amp,
a8848bd6 10573 },
fb97dc67
J
10574 [ALC883_FUJITSU_PI2515] = {
10575 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10576 .init_verbs = { alc883_init_verbs,
10577 alc883_2ch_fujitsu_pi2515_verbs},
10578 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10579 .dac_nids = alc883_dac_nids,
10580 .dig_out_nid = ALC883_DIGOUT_NID,
10581 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10582 .channel_mode = alc883_3ST_2ch_modes,
10583 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10584 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10585 .setup = alc883_2ch_fujitsu_pi2515_setup,
10586 .init_hook = alc_automute_amp,
fb97dc67 10587 },
ef8ef5fb
VP
10588 [ALC888_FUJITSU_XA3530] = {
10589 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10590 .init_verbs = { alc883_init_verbs,
10591 alc888_fujitsu_xa3530_verbs },
10592 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10593 .dac_nids = alc883_dac_nids,
10594 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10595 .adc_nids = alc883_adc_nids_rev,
10596 .capsrc_nids = alc883_capsrc_nids_rev,
10597 .dig_out_nid = ALC883_DIGOUT_NID,
10598 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10599 .channel_mode = alc888_4ST_8ch_intel_modes,
10600 .num_mux_defs =
10601 ARRAY_SIZE(alc888_2_capture_sources),
10602 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10603 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10604 .setup = alc888_fujitsu_xa3530_setup,
10605 .init_hook = alc_automute_amp,
ef8ef5fb 10606 },
e2757d5e
KY
10607 [ALC888_LENOVO_SKY] = {
10608 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10609 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10610 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10611 .dac_nids = alc883_dac_nids,
10612 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10613 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10614 .channel_mode = alc883_sixstack_modes,
10615 .need_dac_fix = 1,
10616 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10617 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10618 .setup = alc888_lenovo_sky_setup,
10619 .init_hook = alc_automute_amp,
e2757d5e
KY
10620 },
10621 [ALC888_ASUS_M90V] = {
10622 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10623 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10624 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10625 .dac_nids = alc883_dac_nids,
10626 .dig_out_nid = ALC883_DIGOUT_NID,
10627 .dig_in_nid = ALC883_DIGIN_NID,
10628 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10629 .channel_mode = alc883_3ST_6ch_modes,
10630 .need_dac_fix = 1,
10631 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10632 .unsol_event = alc_sku_unsol_event,
10633 .setup = alc883_mode2_setup,
10634 .init_hook = alc_inithook,
e2757d5e
KY
10635 },
10636 [ALC888_ASUS_EEE1601] = {
10637 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10638 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10639 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10641 .dac_nids = alc883_dac_nids,
10642 .dig_out_nid = ALC883_DIGOUT_NID,
10643 .dig_in_nid = ALC883_DIGIN_NID,
10644 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10645 .channel_mode = alc883_3ST_2ch_modes,
10646 .need_dac_fix = 1,
10647 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10648 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10649 .init_hook = alc883_eee1601_inithook,
10650 },
3ab90935
WF
10651 [ALC1200_ASUS_P5Q] = {
10652 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10653 .init_verbs = { alc883_init_verbs },
10654 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10655 .dac_nids = alc883_dac_nids,
10656 .dig_out_nid = ALC1200_DIGOUT_NID,
10657 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10658 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10659 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10660 .channel_mode = alc883_sixstack_modes,
10661 .input_mux = &alc883_capture_source,
10662 },
eb4c41d3
TS
10663 [ALC889A_MB31] = {
10664 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10665 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10666 alc880_gpio1_init_verbs },
10667 .adc_nids = alc883_adc_nids,
10668 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10669 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10670 .dac_nids = alc883_dac_nids,
10671 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10672 .channel_mode = alc889A_mb31_6ch_modes,
10673 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10674 .input_mux = &alc889A_mb31_capture_source,
10675 .dig_out_nid = ALC883_DIGOUT_NID,
10676 .unsol_event = alc889A_mb31_unsol_event,
10677 .init_hook = alc889A_mb31_automute,
10678 },
3e1647c5
GG
10679 [ALC883_SONY_VAIO_TT] = {
10680 .mixers = { alc883_vaiott_mixer },
10681 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10682 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10683 .dac_nids = alc883_dac_nids,
10684 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10685 .channel_mode = alc883_3ST_2ch_modes,
10686 .input_mux = &alc883_capture_source,
10687 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10688 .setup = alc883_vaiott_setup,
10689 .init_hook = alc_automute_amp,
3e1647c5 10690 },
9c7f852e
TI
10691};
10692
10693
4953550a
TI
10694/*
10695 * Pin config fixes
10696 */
10697enum {
954a29c8 10698 PINFIX_ABIT_AW9D_MAX,
32eea388 10699 PINFIX_LENOVO_Y530,
954a29c8 10700 PINFIX_PB_M5210,
c3d226ab 10701 PINFIX_ACER_ASPIRE_7736,
c6b35874 10702 PINFIX_GIGABYTE_880GM,
4953550a
TI
10703};
10704
f8f25ba3
TI
10705static const struct alc_fixup alc882_fixups[] = {
10706 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10707 .type = ALC_FIXUP_PINS,
10708 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10709 { 0x15, 0x01080104 }, /* side */
10710 { 0x16, 0x01011012 }, /* rear */
10711 { 0x17, 0x01016011 }, /* clfe */
10712 { }
10713 }
f8f25ba3 10714 },
32eea388
DH
10715 [PINFIX_LENOVO_Y530] = {
10716 .type = ALC_FIXUP_PINS,
10717 .v.pins = (const struct alc_pincfg[]) {
10718 { 0x15, 0x99130112 }, /* rear int speakers */
10719 { 0x16, 0x99130111 }, /* subwoofer */
10720 { }
10721 }
10722 },
954a29c8 10723 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10724 .type = ALC_FIXUP_VERBS,
10725 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10726 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10727 {}
10728 }
954a29c8 10729 },
c3d226ab 10730 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10731 .type = ALC_FIXUP_SKU,
10732 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10733 },
c6b35874
TI
10734 [PINFIX_GIGABYTE_880GM] = {
10735 .type = ALC_FIXUP_PINS,
10736 .v.pins = (const struct alc_pincfg[]) {
10737 { 0x14, 0x1114410 }, /* set as speaker */
10738 { }
10739 }
10740 },
4953550a
TI
10741};
10742
f8f25ba3 10743static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10744 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10745 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10746 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10747 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
c6b35874 10748 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM),
4953550a
TI
10749 {}
10750};
10751
9c7f852e
TI
10752/*
10753 * BIOS auto configuration
10754 */
05f5f477
TI
10755static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10756 const struct auto_pin_cfg *cfg)
10757{
10758 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10759}
10760
4953550a 10761static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10762 hda_nid_t nid, int pin_type,
489008cd 10763 hda_nid_t dac)
9c7f852e 10764{
f12ab1e0
TI
10765 int idx;
10766
489008cd 10767 /* set as output */
f6c7e546 10768 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10769
10770 if (dac == 0x25)
9c7f852e 10771 idx = 4;
489008cd
TI
10772 else if (dac >= 0x02 && dac <= 0x05)
10773 idx = dac - 2;
f9700d5a 10774 else
489008cd 10775 return;
9c7f852e 10776 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10777}
10778
4953550a 10779static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10780{
10781 struct alc_spec *spec = codec->spec;
10782 int i;
10783
10784 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10785 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10786 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10787 if (nid)
4953550a 10788 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10789 spec->multiout.dac_nids[i]);
9c7f852e
TI
10790 }
10791}
10792
4953550a 10793static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10794{
10795 struct alc_spec *spec = codec->spec;
489008cd 10796 hda_nid_t pin, dac;
5855fb80 10797 int i;
9c7f852e 10798
0a3fabe3
DH
10799 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
10800 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10801 pin = spec->autocfg.hp_pins[i];
10802 if (!pin)
10803 break;
10804 dac = spec->multiout.hp_nid;
10805 if (!dac)
10806 dac = spec->multiout.dac_nids[0]; /* to front */
10807 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10808 }
489008cd 10809 }
0a3fabe3
DH
10810
10811 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
10812 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10813 pin = spec->autocfg.speaker_pins[i];
10814 if (!pin)
10815 break;
10816 dac = spec->multiout.extra_out_nid[0];
10817 if (!dac)
10818 dac = spec->multiout.dac_nids[0]; /* to front */
10819 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10820 }
489008cd 10821 }
9c7f852e
TI
10822}
10823
4953550a 10824static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10825{
10826 struct alc_spec *spec = codec->spec;
66ceeb6b 10827 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10828 int i;
10829
66ceeb6b
TI
10830 for (i = 0; i < cfg->num_inputs; i++) {
10831 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10832 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10833 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10834 snd_hda_codec_write(codec, nid, 0,
10835 AC_VERB_SET_AMP_GAIN_MUTE,
10836 AMP_OUT_MUTE);
10837 }
10838}
10839
10840static void alc882_auto_init_input_src(struct hda_codec *codec)
10841{
10842 struct alc_spec *spec = codec->spec;
10843 int c;
10844
10845 for (c = 0; c < spec->num_adc_nids; c++) {
10846 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10847 hda_nid_t nid = spec->capsrc_nids[c];
10848 unsigned int mux_idx;
10849 const struct hda_input_mux *imux;
10850 int conns, mute, idx, item;
10851
10852 conns = snd_hda_get_connections(codec, nid, conn_list,
10853 ARRAY_SIZE(conn_list));
10854 if (conns < 0)
10855 continue;
10856 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10857 imux = &spec->input_mux[mux_idx];
5311114d
TI
10858 if (!imux->num_items && mux_idx > 0)
10859 imux = &spec->input_mux[0];
4953550a
TI
10860 for (idx = 0; idx < conns; idx++) {
10861 /* if the current connection is the selected one,
10862 * unmute it as default - otherwise mute it
10863 */
10864 mute = AMP_IN_MUTE(idx);
10865 for (item = 0; item < imux->num_items; item++) {
10866 if (imux->items[item].index == idx) {
10867 if (spec->cur_mux[c] == item)
10868 mute = AMP_IN_UNMUTE(idx);
10869 break;
10870 }
10871 }
10872 /* check if we have a selector or mixer
10873 * we could check for the widget type instead, but
10874 * just check for Amp-In presence (in case of mixer
10875 * without amp-in there is something wrong, this
10876 * function shouldn't be used or capsrc nid is wrong)
10877 */
10878 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10879 snd_hda_codec_write(codec, nid, 0,
10880 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10881 mute);
10882 else if (mute != AMP_IN_MUTE(idx))
10883 snd_hda_codec_write(codec, nid, 0,
10884 AC_VERB_SET_CONNECT_SEL,
10885 idx);
9c7f852e
TI
10886 }
10887 }
10888}
10889
4953550a
TI
10890/* add mic boosts if needed */
10891static int alc_auto_add_mic_boost(struct hda_codec *codec)
10892{
10893 struct alc_spec *spec = codec->spec;
66ceeb6b 10894 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10895 int i, err;
53e8c323 10896 int type_idx = 0;
4953550a 10897 hda_nid_t nid;
5322bf27 10898 const char *prev_label = NULL;
4953550a 10899
66ceeb6b 10900 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10901 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10902 break;
10903 nid = cfg->inputs[i].pin;
10904 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10905 const char *label;
10906 char boost_label[32];
10907
10908 label = hda_get_autocfg_input_label(codec, cfg, i);
10909 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10910 type_idx++;
10911 else
10912 type_idx = 0;
5322bf27
DH
10913 prev_label = label;
10914
10915 snprintf(boost_label, sizeof(boost_label),
10916 "%s Boost Volume", label);
10917 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10918 boost_label, type_idx,
4953550a 10919 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10920 if (err < 0)
10921 return err;
10922 }
4953550a
TI
10923 }
10924 return 0;
10925}
f511b01c 10926
9c7f852e 10927/* almost identical with ALC880 parser... */
4953550a 10928static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10929{
10930 struct alc_spec *spec = codec->spec;
05f5f477 10931 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10932 int err;
9c7f852e 10933
05f5f477
TI
10934 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10935 alc882_ignore);
9c7f852e
TI
10936 if (err < 0)
10937 return err;
05f5f477
TI
10938 if (!spec->autocfg.line_outs)
10939 return 0; /* can't find valid BIOS pin config */
776e184e 10940
05f5f477
TI
10941 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10942 if (err < 0)
10943 return err;
569ed348 10944 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10945 if (err < 0)
10946 return err;
10947 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10948 "Headphone");
05f5f477
TI
10949 if (err < 0)
10950 return err;
10951 err = alc880_auto_create_extra_out(spec,
10952 spec->autocfg.speaker_pins[0],
10953 "Speaker");
10954 if (err < 0)
10955 return err;
05f5f477 10956 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10957 if (err < 0)
10958 return err;
10959
05f5f477
TI
10960 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10961
757899ac 10962 alc_auto_parse_digital(codec);
05f5f477
TI
10963
10964 if (spec->kctls.list)
10965 add_mixer(spec, spec->kctls.list);
10966
10967 add_verb(spec, alc883_auto_init_verbs);
4953550a 10968 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10969 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10970 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10971
05f5f477
TI
10972 spec->num_mux_defs = 1;
10973 spec->input_mux = &spec->private_imux[0];
10974
6227cdce 10975 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10976
10977 err = alc_auto_add_mic_boost(codec);
10978 if (err < 0)
10979 return err;
61b9b9b1 10980
776e184e 10981 return 1; /* config found */
9c7f852e
TI
10982}
10983
10984/* additional initialization for auto-configuration model */
4953550a 10985static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10986{
f6c7e546 10987 struct alc_spec *spec = codec->spec;
4953550a
TI
10988 alc882_auto_init_multi_out(codec);
10989 alc882_auto_init_hp_out(codec);
10990 alc882_auto_init_analog_input(codec);
10991 alc882_auto_init_input_src(codec);
757899ac 10992 alc_auto_init_digital(codec);
f6c7e546 10993 if (spec->unsol_event)
7fb0d78f 10994 alc_inithook(codec);
9c7f852e
TI
10995}
10996
4953550a 10997static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10998{
10999 struct alc_spec *spec;
11000 int err, board_config;
11001
11002 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11003 if (spec == NULL)
11004 return -ENOMEM;
11005
11006 codec->spec = spec;
11007
4953550a
TI
11008 switch (codec->vendor_id) {
11009 case 0x10ec0882:
11010 case 0x10ec0885:
11011 break;
11012 default:
11013 /* ALC883 and variants */
11014 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11015 break;
11016 }
2c3bf9ab 11017
4953550a
TI
11018 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11019 alc882_models,
11020 alc882_cfg_tbl);
11021
11022 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11023 board_config = snd_hda_check_board_codec_sid_config(codec,
11024 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11025
11026 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11027 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11028 codec->chip_name);
11029 board_config = ALC882_AUTO;
9c7f852e
TI
11030 }
11031
b5bfbc67
TI
11032 if (board_config == ALC882_AUTO) {
11033 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11034 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11035 }
4953550a 11036
90622917
DH
11037 alc_auto_parse_customize_define(codec);
11038
4953550a 11039 if (board_config == ALC882_AUTO) {
9c7f852e 11040 /* automatic parse from the BIOS config */
4953550a 11041 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11042 if (err < 0) {
11043 alc_free(codec);
11044 return err;
f12ab1e0 11045 } else if (!err) {
9c7f852e
TI
11046 printk(KERN_INFO
11047 "hda_codec: Cannot set up configuration "
11048 "from BIOS. Using base mode...\n");
4953550a 11049 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11050 }
11051 }
11052
dc1eae25 11053 if (has_cdefine_beep(codec)) {
8af2591d
TI
11054 err = snd_hda_attach_beep_device(codec, 0x1);
11055 if (err < 0) {
11056 alc_free(codec);
11057 return err;
11058 }
680cd536
KK
11059 }
11060
4953550a 11061 if (board_config != ALC882_AUTO)
e9c364c0 11062 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11063
4953550a
TI
11064 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11065 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11066 /* FIXME: setup DAC5 */
11067 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11068 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11069
11070 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11071 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11072
4953550a 11073 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11074 int i, j;
4953550a
TI
11075 spec->num_adc_nids = 0;
11076 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11077 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11078 hda_nid_t cap;
d11f74c6 11079 hda_nid_t items[16];
4953550a
TI
11080 hda_nid_t nid = alc882_adc_nids[i];
11081 unsigned int wcap = get_wcaps(codec, nid);
11082 /* get type */
a22d543a 11083 wcap = get_wcaps_type(wcap);
4953550a
TI
11084 if (wcap != AC_WID_AUD_IN)
11085 continue;
11086 spec->private_adc_nids[spec->num_adc_nids] = nid;
11087 err = snd_hda_get_connections(codec, nid, &cap, 1);
11088 if (err < 0)
11089 continue;
d11f74c6
TI
11090 err = snd_hda_get_connections(codec, cap, items,
11091 ARRAY_SIZE(items));
11092 if (err < 0)
11093 continue;
11094 for (j = 0; j < imux->num_items; j++)
11095 if (imux->items[j].index >= err)
11096 break;
11097 if (j < imux->num_items)
11098 continue;
4953550a
TI
11099 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11100 spec->num_adc_nids++;
61b9b9b1 11101 }
4953550a
TI
11102 spec->adc_nids = spec->private_adc_nids;
11103 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11104 }
11105
b59bdf3b 11106 set_capture_mixer(codec);
da00c244 11107
dc1eae25 11108 if (has_cdefine_beep(codec))
da00c244 11109 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11110
b5bfbc67 11111 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11112
2134ea4f
TI
11113 spec->vmaster_nid = 0x0c;
11114
9c7f852e 11115 codec->patch_ops = alc_patch_ops;
4953550a
TI
11116 if (board_config == ALC882_AUTO)
11117 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11118
11119 alc_init_jacks(codec);
cb53c626
TI
11120#ifdef CONFIG_SND_HDA_POWER_SAVE
11121 if (!spec->loopback.amplist)
4953550a 11122 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11123#endif
9c7f852e
TI
11124
11125 return 0;
11126}
11127
4953550a 11128
9c7f852e
TI
11129/*
11130 * ALC262 support
11131 */
11132
11133#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11134#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11135
11136#define alc262_dac_nids alc260_dac_nids
11137#define alc262_adc_nids alc882_adc_nids
11138#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11139#define alc262_capsrc_nids alc882_capsrc_nids
11140#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11141
11142#define alc262_modes alc260_modes
11143#define alc262_capture_source alc882_capture_source
11144
4e555fe5
KY
11145static hda_nid_t alc262_dmic_adc_nids[1] = {
11146 /* ADC0 */
11147 0x09
11148};
11149
11150static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11151
9c7f852e
TI
11152static struct snd_kcontrol_new alc262_base_mixer[] = {
11153 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11154 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11155 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11156 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11157 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11158 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11159 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11160 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11161 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11162 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11163 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11164 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11165 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11167 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11168 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11169 { } /* end */
11170};
11171
ce875f07
TI
11172/* update HP, line and mono-out pins according to the master switch */
11173static void alc262_hp_master_update(struct hda_codec *codec)
11174{
11175 struct alc_spec *spec = codec->spec;
11176 int val = spec->master_sw;
11177
11178 /* HP & line-out */
11179 snd_hda_codec_write_cache(codec, 0x1b, 0,
11180 AC_VERB_SET_PIN_WIDGET_CONTROL,
11181 val ? PIN_HP : 0);
11182 snd_hda_codec_write_cache(codec, 0x15, 0,
11183 AC_VERB_SET_PIN_WIDGET_CONTROL,
11184 val ? PIN_HP : 0);
11185 /* mono (speaker) depending on the HP jack sense */
11186 val = val && !spec->jack_present;
11187 snd_hda_codec_write_cache(codec, 0x16, 0,
11188 AC_VERB_SET_PIN_WIDGET_CONTROL,
11189 val ? PIN_OUT : 0);
11190}
11191
11192static void alc262_hp_bpc_automute(struct hda_codec *codec)
11193{
11194 struct alc_spec *spec = codec->spec;
864f92be
WF
11195
11196 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11197 alc262_hp_master_update(codec);
11198}
11199
11200static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11201{
11202 if ((res >> 26) != ALC880_HP_EVENT)
11203 return;
11204 alc262_hp_bpc_automute(codec);
11205}
11206
11207static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11208{
11209 struct alc_spec *spec = codec->spec;
864f92be
WF
11210
11211 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11212 alc262_hp_master_update(codec);
11213}
11214
11215static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11216 unsigned int res)
11217{
11218 if ((res >> 26) != ALC880_HP_EVENT)
11219 return;
11220 alc262_hp_wildwest_automute(codec);
11221}
11222
b72519b5 11223#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11224
11225static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11226 struct snd_ctl_elem_value *ucontrol)
11227{
11228 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11229 struct alc_spec *spec = codec->spec;
11230 int val = !!*ucontrol->value.integer.value;
11231
11232 if (val == spec->master_sw)
11233 return 0;
11234 spec->master_sw = val;
11235 alc262_hp_master_update(codec);
11236 return 1;
11237}
11238
b72519b5
TI
11239#define ALC262_HP_MASTER_SWITCH \
11240 { \
11241 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11242 .name = "Master Playback Switch", \
11243 .info = snd_ctl_boolean_mono_info, \
11244 .get = alc262_hp_master_sw_get, \
11245 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11246 }, \
11247 { \
11248 .iface = NID_MAPPING, \
11249 .name = "Master Playback Switch", \
11250 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11251 }
11252
5b0cb1d8 11253
9c7f852e 11254static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11255 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11256 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11257 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11259 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11260 HDA_OUTPUT),
11261 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11262 HDA_OUTPUT),
9c7f852e
TI
11263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11264 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11265 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11266 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11267 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11268 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11269 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11270 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11271 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11272 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11273 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11274 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11275 { } /* end */
11276};
11277
cd7509a4 11278static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11279 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11280 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11281 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11282 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11283 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11284 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11285 HDA_OUTPUT),
11286 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11287 HDA_OUTPUT),
cd7509a4
KY
11288 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11289 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11290 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11291 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11292 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11293 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11294 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11295 { } /* end */
11296};
11297
11298static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11299 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11300 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11301 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11302 { } /* end */
11303};
11304
66d2a9d6 11305/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11306static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11307{
11308 struct alc_spec *spec = codec->spec;
66d2a9d6 11309
a9fd4f3f 11310 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11311 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11312}
11313
66d2a9d6 11314static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11315 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11316 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11317 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11318 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11321 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11322 { } /* end */
11323};
11324
11325static struct hda_verb alc262_hp_t5735_verbs[] = {
11326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11328
11329 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11330 { }
11331};
11332
8c427226 11333static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11334 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11335 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11336 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11337 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11338 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11339 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11340 { } /* end */
11341};
11342
11343static struct hda_verb alc262_hp_rp5700_verbs[] = {
11344 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11345 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11346 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11347 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11348 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11349 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11350 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11351 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11352 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11354 {}
11355};
11356
11357static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11358 .num_items = 1,
11359 .items = {
11360 { "Line", 0x1 },
11361 },
11362};
11363
42171c17
TI
11364/* bind hp and internal speaker mute (with plug check) as master switch */
11365static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11366{
42171c17
TI
11367 struct alc_spec *spec = codec->spec;
11368 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11369 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11370 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11371 unsigned int mute;
0724ea2a 11372
42171c17
TI
11373 /* HP */
11374 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11375 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11376 HDA_AMP_MUTE, mute);
11377 /* mute internal speaker per jack sense */
11378 if (spec->jack_present)
11379 mute = HDA_AMP_MUTE;
11380 if (line_nid)
11381 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11382 HDA_AMP_MUTE, mute);
11383 if (speaker_nid && speaker_nid != line_nid)
11384 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11385 HDA_AMP_MUTE, mute);
42171c17
TI
11386}
11387
11388#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11389
11390static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11391 struct snd_ctl_elem_value *ucontrol)
11392{
11393 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11394 struct alc_spec *spec = codec->spec;
11395 int val = !!*ucontrol->value.integer.value;
11396
11397 if (val == spec->master_sw)
11398 return 0;
11399 spec->master_sw = val;
11400 alc262_hippo_master_update(codec);
11401 return 1;
11402}
11403
11404#define ALC262_HIPPO_MASTER_SWITCH \
11405 { \
11406 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11407 .name = "Master Playback Switch", \
11408 .info = snd_ctl_boolean_mono_info, \
11409 .get = alc262_hippo_master_sw_get, \
11410 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11411 }, \
11412 { \
11413 .iface = NID_MAPPING, \
11414 .name = "Master Playback Switch", \
11415 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11416 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11417 }
42171c17
TI
11418
11419static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11420 ALC262_HIPPO_MASTER_SWITCH,
11421 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11422 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11423 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11424 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11425 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11427 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11428 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11429 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11430 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11431 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11432 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11433 { } /* end */
11434};
11435
11436static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11437 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11438 ALC262_HIPPO_MASTER_SWITCH,
11439 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11440 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11441 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11442 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11443 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11444 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11445 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11446 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11447 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11448 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11449 { } /* end */
11450};
11451
11452/* mute/unmute internal speaker according to the hp jack and mute state */
11453static void alc262_hippo_automute(struct hda_codec *codec)
11454{
11455 struct alc_spec *spec = codec->spec;
11456 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11457
864f92be 11458 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11459 alc262_hippo_master_update(codec);
0724ea2a 11460}
5b31954e 11461
42171c17
TI
11462static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11463{
11464 if ((res >> 26) != ALC880_HP_EVENT)
11465 return;
11466 alc262_hippo_automute(codec);
11467}
11468
4f5d1706 11469static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11470{
11471 struct alc_spec *spec = codec->spec;
11472
11473 spec->autocfg.hp_pins[0] = 0x15;
11474 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11475}
11476
4f5d1706 11477static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11478{
11479 struct alc_spec *spec = codec->spec;
11480
11481 spec->autocfg.hp_pins[0] = 0x1b;
11482 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11483}
11484
11485
272a527c 11486static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11487 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11488 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11489 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11490 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11491 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11492 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11493 { } /* end */
11494};
11495
83c34218 11496static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11497 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11498 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11499 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11500 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11501 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11502 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11503 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11504 { } /* end */
11505};
272a527c 11506
ba340e82
TV
11507static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11508 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11509 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11510 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11511 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11512 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11513 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11517 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11518 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11519 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11520 { } /* end */
11521};
11522
11523static struct hda_verb alc262_tyan_verbs[] = {
11524 /* Headphone automute */
11525 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11526 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11527 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11528
11529 /* P11 AUX_IN, white 4-pin connector */
11530 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11531 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11532 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11533 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11534
11535 {}
11536};
11537
11538/* unsolicited event for HP jack sensing */
4f5d1706 11539static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11540{
a9fd4f3f 11541 struct alc_spec *spec = codec->spec;
ba340e82 11542
a9fd4f3f
TI
11543 spec->autocfg.hp_pins[0] = 0x1b;
11544 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11545}
11546
ba340e82 11547
9c7f852e
TI
11548#define alc262_capture_mixer alc882_capture_mixer
11549#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11550
11551/*
11552 * generic initialization of ADC, input mixers and output mixers
11553 */
11554static struct hda_verb alc262_init_verbs[] = {
11555 /*
11556 * Unmute ADC0-2 and set the default input to mic-in
11557 */
11558 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11559 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11560 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11562 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11563 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11564
cb53c626 11565 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11566 * mixer widget
f12ab1e0
TI
11567 * Note: PASD motherboards uses the Line In 2 as the input for
11568 * front panel mic (mic 2)
9c7f852e
TI
11569 */
11570 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11571 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11572 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11573 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11576
11577 /*
df694daa
KY
11578 * Set up output mixers (0x0c - 0x0e)
11579 */
11580 /* set vol=0 to output mixers */
11581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11582 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11583 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11584 /* set up input amps for analog loopback */
11585 /* Amp Indices: DAC = 0, mixer = 1 */
11586 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11587 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11588 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11589 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11590 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11591 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11592
11593 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11594 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11595 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11596 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11597 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11598 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11599
11600 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11601 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11602 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11603 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11604 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11605
df694daa
KY
11606 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11607 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11608
df694daa
KY
11609 /* FIXME: use matrix-type input source selection */
11610 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11611 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11612 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11613 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11614 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11615 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11616 /* Input mixer2 */
11617 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11618 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11619 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11620 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11621 /* Input mixer3 */
11622 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11623 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11624 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11625 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11626
11627 { }
11628};
1da177e4 11629
4e555fe5
KY
11630static struct hda_verb alc262_eapd_verbs[] = {
11631 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11632 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11633 { }
11634};
11635
ccc656ce
KY
11636static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11637 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11638 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11639 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11640
11641 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11642 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11643 {}
11644};
11645
272a527c
KY
11646static struct hda_verb alc262_sony_unsol_verbs[] = {
11647 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11648 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11649 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11650
11651 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11653 {}
272a527c
KY
11654};
11655
4e555fe5
KY
11656static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11657 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11658 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11659 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11662 { } /* end */
11663};
11664
11665static struct hda_verb alc262_toshiba_s06_verbs[] = {
11666 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11667 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11668 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11669 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11670 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11671 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11672 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11673 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11674 {}
11675};
11676
4f5d1706 11677static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11678{
a9fd4f3f
TI
11679 struct alc_spec *spec = codec->spec;
11680
11681 spec->autocfg.hp_pins[0] = 0x15;
11682 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11683 spec->ext_mic.pin = 0x18;
11684 spec->ext_mic.mux_idx = 0;
11685 spec->int_mic.pin = 0x12;
11686 spec->int_mic.mux_idx = 9;
11687 spec->auto_mic = 1;
4e555fe5
KY
11688}
11689
e8f9ae2a
PT
11690/*
11691 * nec model
11692 * 0x15 = headphone
11693 * 0x16 = internal speaker
11694 * 0x18 = external mic
11695 */
11696
11697static struct snd_kcontrol_new alc262_nec_mixer[] = {
11698 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11699 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11700
11701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11702 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11703 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11704
11705 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11706 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11707 { } /* end */
11708};
11709
11710static struct hda_verb alc262_nec_verbs[] = {
11711 /* Unmute Speaker */
11712 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11713
11714 /* Headphone */
11715 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11716 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11717
11718 /* External mic to headphone */
11719 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11720 /* External mic to speaker */
11721 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11722 {}
11723};
11724
834be88d
TI
11725/*
11726 * fujitsu model
5d9fab2d
TV
11727 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11728 * 0x1b = port replicator headphone out
834be88d
TI
11729 */
11730
11731#define ALC_HP_EVENT 0x37
11732
11733static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11734 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11735 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11736 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11737 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11738 {}
11739};
11740
0e31daf7
J
11741static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11742 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11743 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11744 {}
11745};
11746
e2595322
DC
11747static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11748 /* Front Mic pin: input vref at 50% */
11749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11751 {}
11752};
11753
834be88d 11754static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11755 .num_items = 3,
834be88d
TI
11756 .items = {
11757 { "Mic", 0x0 },
28c4edb7 11758 { "Internal Mic", 0x1 },
834be88d
TI
11759 { "CD", 0x4 },
11760 },
11761};
11762
9c7f852e
TI
11763static struct hda_input_mux alc262_HP_capture_source = {
11764 .num_items = 5,
11765 .items = {
11766 { "Mic", 0x0 },
accbe498 11767 { "Front Mic", 0x1 },
9c7f852e
TI
11768 { "Line", 0x2 },
11769 { "CD", 0x4 },
11770 { "AUX IN", 0x6 },
11771 },
11772};
11773
accbe498 11774static struct hda_input_mux alc262_HP_D7000_capture_source = {
11775 .num_items = 4,
11776 .items = {
11777 { "Mic", 0x0 },
11778 { "Front Mic", 0x2 },
11779 { "Line", 0x1 },
11780 { "CD", 0x4 },
11781 },
11782};
11783
ebc7a406 11784/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11785static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11786{
11787 struct alc_spec *spec = codec->spec;
11788 unsigned int mute;
11789
f12ab1e0 11790 if (force || !spec->sense_updated) {
864f92be
WF
11791 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11792 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11793 spec->sense_updated = 1;
11794 }
ebc7a406
TI
11795 /* unmute internal speaker only if both HPs are unplugged and
11796 * master switch is on
11797 */
11798 if (spec->jack_present)
11799 mute = HDA_AMP_MUTE;
11800 else
834be88d 11801 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11802 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11803 HDA_AMP_MUTE, mute);
834be88d
TI
11804}
11805
11806/* unsolicited event for HP jack sensing */
11807static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11808 unsigned int res)
11809{
11810 if ((res >> 26) != ALC_HP_EVENT)
11811 return;
11812 alc262_fujitsu_automute(codec, 1);
11813}
11814
ebc7a406
TI
11815static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11816{
11817 alc262_fujitsu_automute(codec, 1);
11818}
11819
834be88d 11820/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11821static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11822 .ops = &snd_hda_bind_vol,
11823 .values = {
11824 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11825 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11826 0
11827 },
11828};
834be88d 11829
0e31daf7
J
11830/* mute/unmute internal speaker according to the hp jack and mute state */
11831static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11832{
11833 struct alc_spec *spec = codec->spec;
11834 unsigned int mute;
11835
11836 if (force || !spec->sense_updated) {
864f92be 11837 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11838 spec->sense_updated = 1;
11839 }
11840 if (spec->jack_present) {
11841 /* mute internal speaker */
11842 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11843 HDA_AMP_MUTE, HDA_AMP_MUTE);
11844 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11845 HDA_AMP_MUTE, HDA_AMP_MUTE);
11846 } else {
11847 /* unmute internal speaker if necessary */
11848 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11849 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11850 HDA_AMP_MUTE, mute);
11851 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11852 HDA_AMP_MUTE, mute);
11853 }
11854}
11855
11856/* unsolicited event for HP jack sensing */
11857static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11858 unsigned int res)
11859{
11860 if ((res >> 26) != ALC_HP_EVENT)
11861 return;
11862 alc262_lenovo_3000_automute(codec, 1);
11863}
11864
8de56b7d
TI
11865static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11866 int dir, int idx, long *valp)
11867{
11868 int i, change = 0;
11869
11870 for (i = 0; i < 2; i++, valp++)
11871 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11872 HDA_AMP_MUTE,
11873 *valp ? 0 : HDA_AMP_MUTE);
11874 return change;
11875}
11876
834be88d
TI
11877/* bind hp and internal speaker mute (with plug check) */
11878static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11879 struct snd_ctl_elem_value *ucontrol)
11880{
11881 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11882 long *valp = ucontrol->value.integer.value;
11883 int change;
11884
8de56b7d
TI
11885 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11886 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11887 if (change)
11888 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11889 return change;
11890}
11891
11892static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11893 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11894 {
11895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11896 .name = "Master Playback Switch",
5e26dfd0 11897 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11898 .info = snd_hda_mixer_amp_switch_info,
11899 .get = snd_hda_mixer_amp_switch_get,
11900 .put = alc262_fujitsu_master_sw_put,
11901 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11902 },
5b0cb1d8
JK
11903 {
11904 .iface = NID_MAPPING,
11905 .name = "Master Playback Switch",
11906 .private_value = 0x1b,
11907 },
834be88d
TI
11908 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11909 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11910 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11912 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11913 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11914 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11915 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11916 { } /* end */
11917};
11918
0e31daf7
J
11919/* bind hp and internal speaker mute (with plug check) */
11920static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11921 struct snd_ctl_elem_value *ucontrol)
11922{
11923 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11924 long *valp = ucontrol->value.integer.value;
11925 int change;
11926
8de56b7d 11927 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11928 if (change)
11929 alc262_lenovo_3000_automute(codec, 0);
11930 return change;
11931}
11932
11933static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11934 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11935 {
11936 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11937 .name = "Master Playback Switch",
5e26dfd0 11938 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11939 .info = snd_hda_mixer_amp_switch_info,
11940 .get = snd_hda_mixer_amp_switch_get,
11941 .put = alc262_lenovo_3000_master_sw_put,
11942 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11943 },
11944 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11945 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11946 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11947 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11948 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11949 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11950 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11951 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11952 { } /* end */
11953};
11954
9f99a638
HM
11955static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11956 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11957 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11958 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11959 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11960 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11961 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11962 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11963 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11964 { } /* end */
11965};
11966
304dcaac
TI
11967/* additional init verbs for Benq laptops */
11968static struct hda_verb alc262_EAPD_verbs[] = {
11969 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11970 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11971 {}
11972};
11973
83c34218
KY
11974static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11975 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11976 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11977
11978 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11979 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11980 {}
11981};
11982
f651b50b
TD
11983/* Samsung Q1 Ultra Vista model setup */
11984static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11985 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11986 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11987 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11988 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11989 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11990 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11991 { } /* end */
11992};
11993
11994static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11995 /* output mixer */
11996 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11997 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11999 /* speaker */
12000 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12001 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12002 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12003 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12004 /* HP */
f651b50b 12005 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
12006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12009 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12010 /* internal mic */
12011 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12013 /* ADC, choose mic */
12014 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12015 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12016 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12017 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12018 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12019 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12020 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12021 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12024 {}
12025};
12026
f651b50b
TD
12027/* mute/unmute internal speaker according to the hp jack and mute state */
12028static void alc262_ultra_automute(struct hda_codec *codec)
12029{
12030 struct alc_spec *spec = codec->spec;
12031 unsigned int mute;
f651b50b 12032
bb9f76cd
TI
12033 mute = 0;
12034 /* auto-mute only when HP is used as HP */
12035 if (!spec->cur_mux[0]) {
864f92be 12036 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12037 if (spec->jack_present)
12038 mute = HDA_AMP_MUTE;
f651b50b 12039 }
bb9f76cd
TI
12040 /* mute/unmute internal speaker */
12041 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12042 HDA_AMP_MUTE, mute);
12043 /* mute/unmute HP */
12044 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12045 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12046}
12047
12048/* unsolicited event for HP jack sensing */
12049static void alc262_ultra_unsol_event(struct hda_codec *codec,
12050 unsigned int res)
12051{
12052 if ((res >> 26) != ALC880_HP_EVENT)
12053 return;
12054 alc262_ultra_automute(codec);
12055}
12056
bb9f76cd
TI
12057static struct hda_input_mux alc262_ultra_capture_source = {
12058 .num_items = 2,
12059 .items = {
12060 { "Mic", 0x1 },
12061 { "Headphone", 0x7 },
12062 },
12063};
12064
12065static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12066 struct snd_ctl_elem_value *ucontrol)
12067{
12068 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12069 struct alc_spec *spec = codec->spec;
12070 int ret;
12071
54cbc9ab 12072 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12073 if (!ret)
12074 return 0;
12075 /* reprogram the HP pin as mic or HP according to the input source */
12076 snd_hda_codec_write_cache(codec, 0x15, 0,
12077 AC_VERB_SET_PIN_WIDGET_CONTROL,
12078 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12079 alc262_ultra_automute(codec); /* mute/unmute HP */
12080 return ret;
12081}
12082
12083static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12084 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12085 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12086 {
12087 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12088 .name = "Capture Source",
54cbc9ab
TI
12089 .info = alc_mux_enum_info,
12090 .get = alc_mux_enum_get,
bb9f76cd
TI
12091 .put = alc262_ultra_mux_enum_put,
12092 },
5b0cb1d8
JK
12093 {
12094 .iface = NID_MAPPING,
12095 .name = "Capture Source",
12096 .private_value = 0x15,
12097 },
bb9f76cd
TI
12098 { } /* end */
12099};
12100
c3fc1f50
TI
12101/* We use two mixers depending on the output pin; 0x16 is a mono output
12102 * and thus it's bound with a different mixer.
12103 * This function returns which mixer amp should be used.
12104 */
12105static int alc262_check_volbit(hda_nid_t nid)
12106{
12107 if (!nid)
12108 return 0;
12109 else if (nid == 0x16)
12110 return 2;
12111 else
12112 return 1;
12113}
12114
12115static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12116 const char *pfx, int *vbits, int idx)
c3fc1f50 12117{
c3fc1f50
TI
12118 unsigned long val;
12119 int vbit;
12120
12121 vbit = alc262_check_volbit(nid);
12122 if (!vbit)
12123 return 0;
12124 if (*vbits & vbit) /* a volume control for this mixer already there */
12125 return 0;
12126 *vbits |= vbit;
c3fc1f50
TI
12127 if (vbit == 2)
12128 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12129 else
12130 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12131 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12132}
12133
12134static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12135 const char *pfx, int idx)
c3fc1f50 12136{
c3fc1f50
TI
12137 unsigned long val;
12138
12139 if (!nid)
12140 return 0;
c3fc1f50
TI
12141 if (nid == 0x16)
12142 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12143 else
12144 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12145 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12146}
12147
df694daa 12148/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12149static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12150 const struct auto_pin_cfg *cfg)
df694daa 12151{
c3fc1f50
TI
12152 const char *pfx;
12153 int vbits;
033688a5 12154 int i, err;
df694daa
KY
12155
12156 spec->multiout.num_dacs = 1; /* only use one dac */
12157 spec->multiout.dac_nids = spec->private_dac_nids;
12158 spec->multiout.dac_nids[0] = 2;
12159
bcb2f0f5
TI
12160 pfx = alc_get_line_out_pfx(cfg, true);
12161 if (!pfx)
c3fc1f50 12162 pfx = "Front";
033688a5
TI
12163 for (i = 0; i < 2; i++) {
12164 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12165 if (err < 0)
12166 return err;
12167 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12168 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12169 "Speaker", i);
12170 if (err < 0)
12171 return err;
12172 }
12173 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12174 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12175 "Headphone", i);
12176 if (err < 0)
12177 return err;
12178 }
12179 }
df694daa 12180
c3fc1f50
TI
12181 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12182 alc262_check_volbit(cfg->speaker_pins[0]) |
12183 alc262_check_volbit(cfg->hp_pins[0]);
12184 if (vbits == 1 || vbits == 2)
12185 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12186 vbits = 0;
033688a5
TI
12187 for (i = 0; i < 2; i++) {
12188 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12189 &vbits, i);
12190 if (err < 0)
12191 return err;
12192 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12193 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12194 "Speaker", &vbits, i);
12195 if (err < 0)
12196 return err;
12197 }
12198 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12199 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12200 "Headphone", &vbits, i);
12201 if (err < 0)
12202 return err;
12203 }
12204 }
f12ab1e0 12205 return 0;
df694daa
KY
12206}
12207
05f5f477 12208#define alc262_auto_create_input_ctls \
eaa9b3a7 12209 alc882_auto_create_input_ctls
df694daa
KY
12210
12211/*
12212 * generic initialization of ADC, input mixers and output mixers
12213 */
12214static struct hda_verb alc262_volume_init_verbs[] = {
12215 /*
12216 * Unmute ADC0-2 and set the default input to mic-in
12217 */
12218 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12219 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12220 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12221 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12222 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12223 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12224
cb53c626 12225 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12226 * mixer widget
f12ab1e0
TI
12227 * Note: PASD motherboards uses the Line In 2 as the input for
12228 * front panel mic (mic 2)
df694daa
KY
12229 */
12230 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12231 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12232 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12233 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12234 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12235 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12236
12237 /*
12238 * Set up output mixers (0x0c - 0x0f)
12239 */
12240 /* set vol=0 to output mixers */
12241 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12242 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12243 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12244
df694daa
KY
12245 /* set up input amps for analog loopback */
12246 /* Amp Indices: DAC = 0, mixer = 1 */
12247 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12248 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12249 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12250 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12251 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12253
12254 /* FIXME: use matrix-type input source selection */
12255 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12256 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12257 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12258 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12259 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12260 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12261 /* Input mixer2 */
12262 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12263 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12264 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12265 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12266 /* Input mixer3 */
12267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12268 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12269 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12270 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12271
12272 { }
12273};
12274
9c7f852e
TI
12275static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12276 /*
12277 * Unmute ADC0-2 and set the default input to mic-in
12278 */
12279 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12281 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12282 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12283 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12284 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12285
cb53c626 12286 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12287 * mixer widget
f12ab1e0
TI
12288 * Note: PASD motherboards uses the Line In 2 as the input for
12289 * front panel mic (mic 2)
9c7f852e
TI
12290 */
12291 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12292 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12293 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12294 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12295 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12296 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12297 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12298 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12299
9c7f852e
TI
12300 /*
12301 * Set up output mixers (0x0c - 0x0e)
12302 */
12303 /* set vol=0 to output mixers */
12304 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12305 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12306 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12307
12308 /* set up input amps for analog loopback */
12309 /* Amp Indices: DAC = 0, mixer = 1 */
12310 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12312 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12313 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12314 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12315 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12316
ce875f07 12317 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12318 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12319 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12320
12321 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12322 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12323
12324 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12325 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12326
12327 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12328 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12329 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12330 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12331 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12332
0e4835c1 12333 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12334 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12335 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12336 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12337 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12338 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12339
12340
12341 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12342 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12343 /* Input mixer1: only unmute Mic */
9c7f852e 12344 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12345 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12346 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12348 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12349 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12350 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12351 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12353 /* Input mixer2 */
12354 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12355 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12356 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12357 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12358 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12359 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12361 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12363 /* Input mixer3 */
12364 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12365 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12366 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12367 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12368 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12369 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12370 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12373
ce875f07
TI
12374 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12375
9c7f852e
TI
12376 { }
12377};
12378
cd7509a4
KY
12379static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12380 /*
12381 * Unmute ADC0-2 and set the default input to mic-in
12382 */
12383 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12385 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12386 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12387 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12388 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12389
cb53c626 12390 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12391 * mixer widget
12392 * Note: PASD motherboards uses the Line In 2 as the input for front
12393 * panel mic (mic 2)
12394 */
12395 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12396 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12404 /*
12405 * Set up output mixers (0x0c - 0x0e)
12406 */
12407 /* set vol=0 to output mixers */
12408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12409 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12410 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12411
12412 /* set up input amps for analog loopback */
12413 /* Amp Indices: DAC = 0, mixer = 1 */
12414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12420
12421
12422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12427 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12428 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12429
12430 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12431 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12432
12433 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12434 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12435
12436 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12437 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12438 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12439 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12440 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12441 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12442
12443 /* FIXME: use matrix-type input source selection */
12444 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12445 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12451 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12453 /* Input mixer2 */
12454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12455 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12456 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12457 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12458 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12459 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12461 /* Input mixer3 */
12462 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12463 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12464 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12466 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12467 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12469
ce875f07
TI
12470 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12471
cd7509a4
KY
12472 { }
12473};
12474
9f99a638
HM
12475static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12476
12477 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12478 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12479 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12480
12481 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12482 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12483 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12484 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12485
12486 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12487 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12488 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12489 {}
12490};
12491
18675e42
TI
12492/*
12493 * Pin config fixes
12494 */
12495enum {
12496 PINFIX_FSC_H270,
12497};
12498
12499static const struct alc_fixup alc262_fixups[] = {
12500 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12501 .type = ALC_FIXUP_PINS,
12502 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12503 { 0x14, 0x99130110 }, /* speaker */
12504 { 0x15, 0x0221142f }, /* front HP */
12505 { 0x1b, 0x0121141f }, /* rear HP */
12506 { }
12507 }
12508 },
18675e42
TI
12509};
12510
12511static struct snd_pci_quirk alc262_fixup_tbl[] = {
12512 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12513 {}
12514};
12515
9f99a638 12516
cb53c626
TI
12517#ifdef CONFIG_SND_HDA_POWER_SAVE
12518#define alc262_loopbacks alc880_loopbacks
12519#endif
12520
def319f9 12521/* pcm configuration: identical with ALC880 */
df694daa
KY
12522#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12523#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12524#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12525#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12526
12527/*
12528 * BIOS auto configuration
12529 */
12530static int alc262_parse_auto_config(struct hda_codec *codec)
12531{
12532 struct alc_spec *spec = codec->spec;
12533 int err;
12534 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12535
f12ab1e0
TI
12536 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12537 alc262_ignore);
12538 if (err < 0)
df694daa 12539 return err;
e64f14f4 12540 if (!spec->autocfg.line_outs) {
0852d7a6 12541 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12542 spec->multiout.max_channels = 2;
12543 spec->no_analog = 1;
12544 goto dig_only;
12545 }
df694daa 12546 return 0; /* can't find valid BIOS pin config */
e64f14f4 12547 }
f12ab1e0
TI
12548 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12549 if (err < 0)
12550 return err;
05f5f477 12551 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12552 if (err < 0)
df694daa
KY
12553 return err;
12554
12555 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12556
e64f14f4 12557 dig_only:
757899ac 12558 alc_auto_parse_digital(codec);
df694daa 12559
603c4019 12560 if (spec->kctls.list)
d88897ea 12561 add_mixer(spec, spec->kctls.list);
df694daa 12562
d88897ea 12563 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12564 spec->num_mux_defs = 1;
61b9b9b1 12565 spec->input_mux = &spec->private_imux[0];
df694daa 12566
776e184e
TI
12567 err = alc_auto_add_mic_boost(codec);
12568 if (err < 0)
12569 return err;
12570
6227cdce 12571 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12572
df694daa
KY
12573 return 1;
12574}
12575
12576#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12577#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12578#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12579#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12580
12581
12582/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12583static void alc262_auto_init(struct hda_codec *codec)
df694daa 12584{
f6c7e546 12585 struct alc_spec *spec = codec->spec;
df694daa
KY
12586 alc262_auto_init_multi_out(codec);
12587 alc262_auto_init_hp_out(codec);
12588 alc262_auto_init_analog_input(codec);
f511b01c 12589 alc262_auto_init_input_src(codec);
757899ac 12590 alc_auto_init_digital(codec);
f6c7e546 12591 if (spec->unsol_event)
7fb0d78f 12592 alc_inithook(codec);
df694daa
KY
12593}
12594
12595/*
12596 * configuration and preset
12597 */
ea734963 12598static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12599 [ALC262_BASIC] = "basic",
12600 [ALC262_HIPPO] = "hippo",
12601 [ALC262_HIPPO_1] = "hippo_1",
12602 [ALC262_FUJITSU] = "fujitsu",
12603 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12604 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12605 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12606 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12607 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12608 [ALC262_BENQ_T31] = "benq-t31",
12609 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12610 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12611 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12612 [ALC262_ULTRA] = "ultra",
0e31daf7 12613 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12614 [ALC262_NEC] = "nec",
ba340e82 12615 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12616 [ALC262_AUTO] = "auto",
12617};
12618
12619static struct snd_pci_quirk alc262_cfg_tbl[] = {
12620 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12621 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12622 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12623 ALC262_HP_BPC),
12624 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12625 ALC262_HP_BPC),
5734a07c
TI
12626 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12627 ALC262_HP_BPC),
53eff7e1
TI
12628 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12629 ALC262_HP_BPC),
cd7509a4 12630 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12631 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12632 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12633 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12634 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12635 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12636 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12637 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12638 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12639 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12640 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12641 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12642 ALC262_HP_TC_T5735),
8c427226 12643 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12644 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12645 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12646 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12647 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12648 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12649 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12650 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12651#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12652 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12653 ALC262_SONY_ASSAMD),
c5b5165c 12654#endif
36ca6e13 12655 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12656 ALC262_TOSHIBA_RX1),
80ffe869 12657 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12658 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12659 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12660 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12661 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12662 ALC262_ULTRA),
3e420e78 12663 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12664 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12665 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12666 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12667 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12668 {}
12669};
12670
12671static struct alc_config_preset alc262_presets[] = {
12672 [ALC262_BASIC] = {
12673 .mixers = { alc262_base_mixer },
12674 .init_verbs = { alc262_init_verbs },
12675 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12676 .dac_nids = alc262_dac_nids,
12677 .hp_nid = 0x03,
12678 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12679 .channel_mode = alc262_modes,
a3bcba38 12680 .input_mux = &alc262_capture_source,
df694daa 12681 },
ccc656ce 12682 [ALC262_HIPPO] = {
42171c17 12683 .mixers = { alc262_hippo_mixer },
6732bd0d 12684 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12685 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12686 .dac_nids = alc262_dac_nids,
12687 .hp_nid = 0x03,
12688 .dig_out_nid = ALC262_DIGOUT_NID,
12689 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12690 .channel_mode = alc262_modes,
12691 .input_mux = &alc262_capture_source,
12692 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12693 .setup = alc262_hippo_setup,
12694 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12695 },
12696 [ALC262_HIPPO_1] = {
12697 .mixers = { alc262_hippo1_mixer },
12698 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12699 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12700 .dac_nids = alc262_dac_nids,
12701 .hp_nid = 0x02,
12702 .dig_out_nid = ALC262_DIGOUT_NID,
12703 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12704 .channel_mode = alc262_modes,
12705 .input_mux = &alc262_capture_source,
42171c17 12706 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12707 .setup = alc262_hippo1_setup,
12708 .init_hook = alc262_hippo_automute,
ccc656ce 12709 },
834be88d
TI
12710 [ALC262_FUJITSU] = {
12711 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12712 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12713 alc262_fujitsu_unsol_verbs },
834be88d
TI
12714 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12715 .dac_nids = alc262_dac_nids,
12716 .hp_nid = 0x03,
12717 .dig_out_nid = ALC262_DIGOUT_NID,
12718 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12719 .channel_mode = alc262_modes,
12720 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12721 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12722 .init_hook = alc262_fujitsu_init_hook,
834be88d 12723 },
9c7f852e
TI
12724 [ALC262_HP_BPC] = {
12725 .mixers = { alc262_HP_BPC_mixer },
12726 .init_verbs = { alc262_HP_BPC_init_verbs },
12727 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12728 .dac_nids = alc262_dac_nids,
12729 .hp_nid = 0x03,
12730 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12731 .channel_mode = alc262_modes,
12732 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12733 .unsol_event = alc262_hp_bpc_unsol_event,
12734 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12735 },
cd7509a4
KY
12736 [ALC262_HP_BPC_D7000_WF] = {
12737 .mixers = { alc262_HP_BPC_WildWest_mixer },
12738 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12739 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12740 .dac_nids = alc262_dac_nids,
12741 .hp_nid = 0x03,
12742 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12743 .channel_mode = alc262_modes,
accbe498 12744 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12745 .unsol_event = alc262_hp_wildwest_unsol_event,
12746 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12747 },
cd7509a4
KY
12748 [ALC262_HP_BPC_D7000_WL] = {
12749 .mixers = { alc262_HP_BPC_WildWest_mixer,
12750 alc262_HP_BPC_WildWest_option_mixer },
12751 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12752 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12753 .dac_nids = alc262_dac_nids,
12754 .hp_nid = 0x03,
12755 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12756 .channel_mode = alc262_modes,
accbe498 12757 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12758 .unsol_event = alc262_hp_wildwest_unsol_event,
12759 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12760 },
66d2a9d6
KY
12761 [ALC262_HP_TC_T5735] = {
12762 .mixers = { alc262_hp_t5735_mixer },
12763 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12764 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12765 .dac_nids = alc262_dac_nids,
12766 .hp_nid = 0x03,
12767 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12768 .channel_mode = alc262_modes,
12769 .input_mux = &alc262_capture_source,
dc99be47 12770 .unsol_event = alc_sku_unsol_event,
4f5d1706 12771 .setup = alc262_hp_t5735_setup,
dc99be47 12772 .init_hook = alc_inithook,
8c427226
KY
12773 },
12774 [ALC262_HP_RP5700] = {
12775 .mixers = { alc262_hp_rp5700_mixer },
12776 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12777 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12778 .dac_nids = alc262_dac_nids,
12779 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12780 .channel_mode = alc262_modes,
12781 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12782 },
304dcaac
TI
12783 [ALC262_BENQ_ED8] = {
12784 .mixers = { alc262_base_mixer },
12785 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12786 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12787 .dac_nids = alc262_dac_nids,
12788 .hp_nid = 0x03,
12789 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12790 .channel_mode = alc262_modes,
12791 .input_mux = &alc262_capture_source,
f12ab1e0 12792 },
272a527c
KY
12793 [ALC262_SONY_ASSAMD] = {
12794 .mixers = { alc262_sony_mixer },
12795 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12796 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12797 .dac_nids = alc262_dac_nids,
12798 .hp_nid = 0x02,
12799 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12800 .channel_mode = alc262_modes,
12801 .input_mux = &alc262_capture_source,
12802 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12803 .setup = alc262_hippo_setup,
12804 .init_hook = alc262_hippo_automute,
83c34218
KY
12805 },
12806 [ALC262_BENQ_T31] = {
12807 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12808 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12809 alc_hp15_unsol_verbs },
83c34218
KY
12810 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12811 .dac_nids = alc262_dac_nids,
12812 .hp_nid = 0x03,
12813 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12814 .channel_mode = alc262_modes,
12815 .input_mux = &alc262_capture_source,
12816 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12817 .setup = alc262_hippo_setup,
12818 .init_hook = alc262_hippo_automute,
ea1fb29a 12819 },
f651b50b 12820 [ALC262_ULTRA] = {
f9e336f6
TI
12821 .mixers = { alc262_ultra_mixer },
12822 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12823 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12824 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12825 .dac_nids = alc262_dac_nids,
f651b50b
TD
12826 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12827 .channel_mode = alc262_modes,
12828 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12829 .adc_nids = alc262_adc_nids, /* ADC0 */
12830 .capsrc_nids = alc262_capsrc_nids,
12831 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12832 .unsol_event = alc262_ultra_unsol_event,
12833 .init_hook = alc262_ultra_automute,
12834 },
0e31daf7
J
12835 [ALC262_LENOVO_3000] = {
12836 .mixers = { alc262_lenovo_3000_mixer },
12837 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12838 alc262_lenovo_3000_unsol_verbs,
12839 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12840 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12841 .dac_nids = alc262_dac_nids,
12842 .hp_nid = 0x03,
12843 .dig_out_nid = ALC262_DIGOUT_NID,
12844 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12845 .channel_mode = alc262_modes,
12846 .input_mux = &alc262_fujitsu_capture_source,
12847 .unsol_event = alc262_lenovo_3000_unsol_event,
12848 },
e8f9ae2a
PT
12849 [ALC262_NEC] = {
12850 .mixers = { alc262_nec_mixer },
12851 .init_verbs = { alc262_nec_verbs },
12852 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12853 .dac_nids = alc262_dac_nids,
12854 .hp_nid = 0x03,
12855 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12856 .channel_mode = alc262_modes,
12857 .input_mux = &alc262_capture_source,
12858 },
4e555fe5
KY
12859 [ALC262_TOSHIBA_S06] = {
12860 .mixers = { alc262_toshiba_s06_mixer },
12861 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12862 alc262_eapd_verbs },
12863 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12864 .capsrc_nids = alc262_dmic_capsrc_nids,
12865 .dac_nids = alc262_dac_nids,
12866 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12867 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12868 .dig_out_nid = ALC262_DIGOUT_NID,
12869 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12870 .channel_mode = alc262_modes,
4f5d1706
TI
12871 .unsol_event = alc_sku_unsol_event,
12872 .setup = alc262_toshiba_s06_setup,
12873 .init_hook = alc_inithook,
4e555fe5 12874 },
9f99a638
HM
12875 [ALC262_TOSHIBA_RX1] = {
12876 .mixers = { alc262_toshiba_rx1_mixer },
12877 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12878 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12879 .dac_nids = alc262_dac_nids,
12880 .hp_nid = 0x03,
12881 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12882 .channel_mode = alc262_modes,
12883 .input_mux = &alc262_capture_source,
12884 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12885 .setup = alc262_hippo_setup,
12886 .init_hook = alc262_hippo_automute,
9f99a638 12887 },
ba340e82
TV
12888 [ALC262_TYAN] = {
12889 .mixers = { alc262_tyan_mixer },
12890 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12891 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12892 .dac_nids = alc262_dac_nids,
12893 .hp_nid = 0x02,
12894 .dig_out_nid = ALC262_DIGOUT_NID,
12895 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12896 .channel_mode = alc262_modes,
12897 .input_mux = &alc262_capture_source,
a9fd4f3f 12898 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12899 .setup = alc262_tyan_setup,
12900 .init_hook = alc_automute_amp,
ba340e82 12901 },
df694daa
KY
12902};
12903
12904static int patch_alc262(struct hda_codec *codec)
12905{
12906 struct alc_spec *spec;
12907 int board_config;
12908 int err;
12909
dc041e0b 12910 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12911 if (spec == NULL)
12912 return -ENOMEM;
12913
12914 codec->spec = spec;
12915#if 0
f12ab1e0
TI
12916 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12917 * under-run
12918 */
df694daa
KY
12919 {
12920 int tmp;
12921 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12922 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12923 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12924 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12925 }
12926#endif
da00c244 12927 alc_auto_parse_customize_define(codec);
df694daa 12928
2c3bf9ab
TI
12929 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12930
f5fcc13c
TI
12931 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12932 alc262_models,
12933 alc262_cfg_tbl);
cd7509a4 12934
f5fcc13c 12935 if (board_config < 0) {
9a11f1aa
TI
12936 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12937 codec->chip_name);
df694daa
KY
12938 board_config = ALC262_AUTO;
12939 }
12940
b5bfbc67
TI
12941 if (board_config == ALC262_AUTO) {
12942 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12943 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12944 }
18675e42 12945
df694daa
KY
12946 if (board_config == ALC262_AUTO) {
12947 /* automatic parse from the BIOS config */
12948 err = alc262_parse_auto_config(codec);
12949 if (err < 0) {
12950 alc_free(codec);
12951 return err;
f12ab1e0 12952 } else if (!err) {
9c7f852e
TI
12953 printk(KERN_INFO
12954 "hda_codec: Cannot set up configuration "
12955 "from BIOS. Using base mode...\n");
df694daa
KY
12956 board_config = ALC262_BASIC;
12957 }
12958 }
12959
dc1eae25 12960 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12961 err = snd_hda_attach_beep_device(codec, 0x1);
12962 if (err < 0) {
12963 alc_free(codec);
12964 return err;
12965 }
680cd536
KK
12966 }
12967
df694daa 12968 if (board_config != ALC262_AUTO)
e9c364c0 12969 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12970
df694daa
KY
12971 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12972 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12973
df694daa
KY
12974 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12975 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12976
f12ab1e0 12977 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12978 int i;
12979 /* check whether the digital-mic has to be supported */
12980 for (i = 0; i < spec->input_mux->num_items; i++) {
12981 if (spec->input_mux->items[i].index >= 9)
12982 break;
12983 }
12984 if (i < spec->input_mux->num_items) {
12985 /* use only ADC0 */
12986 spec->adc_nids = alc262_dmic_adc_nids;
12987 spec->num_adc_nids = 1;
12988 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12989 } else {
8c927b4a
TI
12990 /* all analog inputs */
12991 /* check whether NID 0x07 is valid */
12992 unsigned int wcap = get_wcaps(codec, 0x07);
12993
12994 /* get type */
a22d543a 12995 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12996 if (wcap != AC_WID_AUD_IN) {
12997 spec->adc_nids = alc262_adc_nids_alt;
12998 spec->num_adc_nids =
12999 ARRAY_SIZE(alc262_adc_nids_alt);
13000 spec->capsrc_nids = alc262_capsrc_nids_alt;
13001 } else {
13002 spec->adc_nids = alc262_adc_nids;
13003 spec->num_adc_nids =
13004 ARRAY_SIZE(alc262_adc_nids);
13005 spec->capsrc_nids = alc262_capsrc_nids;
13006 }
df694daa
KY
13007 }
13008 }
e64f14f4 13009 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13010 set_capture_mixer(codec);
dc1eae25 13011 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13012 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13013
b5bfbc67 13014 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13015
2134ea4f
TI
13016 spec->vmaster_nid = 0x0c;
13017
df694daa
KY
13018 codec->patch_ops = alc_patch_ops;
13019 if (board_config == ALC262_AUTO)
ae6b813a 13020 spec->init_hook = alc262_auto_init;
bf1b0225
KY
13021
13022 alc_init_jacks(codec);
cb53c626
TI
13023#ifdef CONFIG_SND_HDA_POWER_SAVE
13024 if (!spec->loopback.amplist)
13025 spec->loopback.amplist = alc262_loopbacks;
13026#endif
ea1fb29a 13027
df694daa
KY
13028 return 0;
13029}
13030
a361d84b
KY
13031/*
13032 * ALC268 channel source setting (2 channel)
13033 */
13034#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13035#define alc268_modes alc260_modes
ea1fb29a 13036
a361d84b
KY
13037static hda_nid_t alc268_dac_nids[2] = {
13038 /* front, hp */
13039 0x02, 0x03
13040};
13041
13042static hda_nid_t alc268_adc_nids[2] = {
13043 /* ADC0-1 */
13044 0x08, 0x07
13045};
13046
13047static hda_nid_t alc268_adc_nids_alt[1] = {
13048 /* ADC0 */
13049 0x08
13050};
13051
e1406348
TI
13052static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13053
a361d84b
KY
13054static struct snd_kcontrol_new alc268_base_mixer[] = {
13055 /* output mixer control */
13056 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13057 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13058 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13060 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13061 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13062 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13063 { }
13064};
13065
42171c17
TI
13066static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13067 /* output mixer control */
13068 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13069 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13070 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13071 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13072 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13073 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13074 { }
13075};
13076
aef9d318
TI
13077/* bind Beep switches of both NID 0x0f and 0x10 */
13078static struct hda_bind_ctls alc268_bind_beep_sw = {
13079 .ops = &snd_hda_bind_sw,
13080 .values = {
13081 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13082 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13083 0
13084 },
13085};
13086
13087static struct snd_kcontrol_new alc268_beep_mixer[] = {
13088 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13089 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13090 { }
13091};
13092
d1a991a6
KY
13093static struct hda_verb alc268_eapd_verbs[] = {
13094 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13095 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13096 { }
13097};
13098
d273809e 13099/* Toshiba specific */
d273809e
TI
13100static struct hda_verb alc268_toshiba_verbs[] = {
13101 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13102 { } /* end */
13103};
13104
13105/* Acer specific */
889c4395 13106/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13107static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13108 .ops = &snd_hda_bind_vol,
13109 .values = {
13110 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13111 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13112 0
13113 },
13114};
13115
889c4395
TI
13116/* mute/unmute internal speaker according to the hp jack and mute state */
13117static void alc268_acer_automute(struct hda_codec *codec, int force)
13118{
13119 struct alc_spec *spec = codec->spec;
13120 unsigned int mute;
13121
13122 if (force || !spec->sense_updated) {
864f92be 13123 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
13124 spec->sense_updated = 1;
13125 }
13126 if (spec->jack_present)
13127 mute = HDA_AMP_MUTE; /* mute internal speaker */
13128 else /* unmute internal speaker if necessary */
13129 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13130 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13131 HDA_AMP_MUTE, mute);
13132}
13133
13134
13135/* bind hp and internal speaker mute (with plug check) */
13136static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13137 struct snd_ctl_elem_value *ucontrol)
13138{
13139 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13140 long *valp = ucontrol->value.integer.value;
13141 int change;
13142
8de56b7d 13143 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13144 if (change)
13145 alc268_acer_automute(codec, 0);
13146 return change;
13147}
d273809e 13148
8ef355da
KY
13149static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13150 /* output mixer control */
13151 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13152 {
13153 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13154 .name = "Master Playback Switch",
5e26dfd0 13155 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13156 .info = snd_hda_mixer_amp_switch_info,
13157 .get = snd_hda_mixer_amp_switch_get,
13158 .put = alc268_acer_master_sw_put,
13159 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13160 },
13161 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13162 { }
13163};
13164
d273809e
TI
13165static struct snd_kcontrol_new alc268_acer_mixer[] = {
13166 /* output mixer control */
13167 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13168 {
13169 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13170 .name = "Master Playback Switch",
5e26dfd0 13171 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13172 .info = snd_hda_mixer_amp_switch_info,
13173 .get = snd_hda_mixer_amp_switch_get,
13174 .put = alc268_acer_master_sw_put,
13175 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13176 },
5f99f86a
DH
13177 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13178 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13179 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13180 { }
13181};
13182
c238b4f4
TI
13183static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13184 /* output mixer control */
13185 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13186 {
13187 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13188 .name = "Master Playback Switch",
5e26dfd0 13189 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13190 .info = snd_hda_mixer_amp_switch_info,
13191 .get = snd_hda_mixer_amp_switch_get,
13192 .put = alc268_acer_master_sw_put,
13193 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13194 },
5f99f86a
DH
13195 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13196 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13197 { }
13198};
13199
8ef355da
KY
13200static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13201 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13203 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13204 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13205 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13206 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13207 { }
13208};
13209
d273809e 13210static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13211 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13212 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13213 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13214 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13215 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13216 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13217 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13218 { }
13219};
13220
13221/* unsolicited event for HP jack sensing */
42171c17 13222#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13223#define alc268_toshiba_setup alc262_hippo_setup
13224#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13225
13226static void alc268_acer_unsol_event(struct hda_codec *codec,
13227 unsigned int res)
13228{
889c4395 13229 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13230 return;
13231 alc268_acer_automute(codec, 1);
13232}
13233
889c4395
TI
13234static void alc268_acer_init_hook(struct hda_codec *codec)
13235{
13236 alc268_acer_automute(codec, 1);
13237}
13238
8ef355da
KY
13239/* toggle speaker-output according to the hp-jack state */
13240static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13241{
13242 unsigned int present;
13243 unsigned char bits;
13244
864f92be 13245 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13246 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13247 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13248 HDA_AMP_MUTE, bits);
8ef355da 13249 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13250 HDA_AMP_MUTE, bits);
8ef355da
KY
13251}
13252
8ef355da
KY
13253static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13254 unsigned int res)
13255{
4f5d1706
TI
13256 switch (res >> 26) {
13257 case ALC880_HP_EVENT:
8ef355da 13258 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13259 break;
13260 case ALC880_MIC_EVENT:
13261 alc_mic_automute(codec);
13262 break;
13263 }
13264}
13265
13266static void alc268_acer_lc_setup(struct hda_codec *codec)
13267{
13268 struct alc_spec *spec = codec->spec;
13269 spec->ext_mic.pin = 0x18;
13270 spec->ext_mic.mux_idx = 0;
13271 spec->int_mic.pin = 0x12;
13272 spec->int_mic.mux_idx = 6;
13273 spec->auto_mic = 1;
8ef355da
KY
13274}
13275
13276static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13277{
13278 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13279 alc_mic_automute(codec);
8ef355da
KY
13280}
13281
3866f0b0
TI
13282static struct snd_kcontrol_new alc268_dell_mixer[] = {
13283 /* output mixer control */
13284 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13285 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13286 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13287 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13288 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13289 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13290 { }
13291};
13292
13293static struct hda_verb alc268_dell_verbs[] = {
13294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13296 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13297 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13298 { }
13299};
13300
13301/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13302static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13303{
a9fd4f3f 13304 struct alc_spec *spec = codec->spec;
3866f0b0 13305
a9fd4f3f
TI
13306 spec->autocfg.hp_pins[0] = 0x15;
13307 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13308 spec->ext_mic.pin = 0x18;
13309 spec->ext_mic.mux_idx = 0;
13310 spec->int_mic.pin = 0x19;
13311 spec->int_mic.mux_idx = 1;
13312 spec->auto_mic = 1;
3866f0b0
TI
13313}
13314
eb5a6621
HRK
13315static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13316 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13317 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13318 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13319 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13320 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13321 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13322 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13323 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13324 { }
13325};
13326
13327static struct hda_verb alc267_quanta_il1_verbs[] = {
13328 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13329 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13330 { }
13331};
13332
4f5d1706 13333static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13334{
a9fd4f3f 13335 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13336 spec->autocfg.hp_pins[0] = 0x15;
13337 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13338 spec->ext_mic.pin = 0x18;
13339 spec->ext_mic.mux_idx = 0;
13340 spec->int_mic.pin = 0x19;
13341 spec->int_mic.mux_idx = 1;
13342 spec->auto_mic = 1;
eb5a6621
HRK
13343}
13344
a361d84b
KY
13345/*
13346 * generic initialization of ADC, input mixers and output mixers
13347 */
13348static struct hda_verb alc268_base_init_verbs[] = {
13349 /* Unmute DAC0-1 and set vol = 0 */
13350 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13351 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13352
13353 /*
13354 * Set up output mixers (0x0c - 0x0e)
13355 */
13356 /* set vol=0 to output mixers */
13357 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13358 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13359
13360 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13361 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13362
13363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13365 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13366 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13367 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13368 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13369 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13370 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13371
13372 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13373 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13374 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13375 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13376 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13377
13378 /* set PCBEEP vol = 0, mute connections */
13379 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13381 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13382
a9b3aa8a 13383 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13384
a9b3aa8a
JZ
13385 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13386 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13387 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13388 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13389
a361d84b
KY
13390 { }
13391};
13392
13393/*
13394 * generic initialization of ADC, input mixers and output mixers
13395 */
13396static struct hda_verb alc268_volume_init_verbs[] = {
13397 /* set output DAC */
4cfb91c6
TI
13398 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13399 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13400
13401 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13403 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13404 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13405 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13406
a361d84b 13407 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13408 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13409 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13410
13411 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13412 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13413
aef9d318
TI
13414 /* set PCBEEP vol = 0, mute connections */
13415 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13417 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13418
13419 { }
13420};
13421
fdbc6626
TI
13422static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13423 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13424 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13425 { } /* end */
13426};
13427
a361d84b
KY
13428static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13429 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13430 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13431 _DEFINE_CAPSRC(1),
a361d84b
KY
13432 { } /* end */
13433};
13434
13435static struct snd_kcontrol_new alc268_capture_mixer[] = {
13436 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13437 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13438 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13439 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13440 _DEFINE_CAPSRC(2),
a361d84b
KY
13441 { } /* end */
13442};
13443
13444static struct hda_input_mux alc268_capture_source = {
13445 .num_items = 4,
13446 .items = {
13447 { "Mic", 0x0 },
13448 { "Front Mic", 0x1 },
13449 { "Line", 0x2 },
13450 { "CD", 0x3 },
13451 },
13452};
13453
0ccb541c 13454static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13455 .num_items = 3,
13456 .items = {
13457 { "Mic", 0x0 },
13458 { "Internal Mic", 0x1 },
13459 { "Line", 0x2 },
13460 },
13461};
13462
13463static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13464 .num_items = 3,
13465 .items = {
13466 { "Mic", 0x0 },
13467 { "Internal Mic", 0x6 },
13468 { "Line", 0x2 },
13469 },
13470};
13471
86c53bd2
JW
13472#ifdef CONFIG_SND_DEBUG
13473static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13474 /* Volume widgets */
13475 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13476 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13477 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13478 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13479 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13480 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13481 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13482 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13483 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13484 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13485 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13486 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13487 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13488 /* The below appears problematic on some hardwares */
13489 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13490 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13491 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13492 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13493 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13494
13495 /* Modes for retasking pin widgets */
13496 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13497 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13498 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13499 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13500
13501 /* Controls for GPIO pins, assuming they are configured as outputs */
13502 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13503 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13504 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13505 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13506
13507 /* Switches to allow the digital SPDIF output pin to be enabled.
13508 * The ALC268 does not have an SPDIF input.
13509 */
13510 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13511
13512 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13513 * this output to turn on an external amplifier.
13514 */
13515 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13516 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13517
13518 { } /* end */
13519};
13520#endif
13521
a361d84b
KY
13522/* create input playback/capture controls for the given pin */
13523static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13524 const char *ctlname, int idx)
13525{
3f3b7c1a 13526 hda_nid_t dac;
a361d84b
KY
13527 int err;
13528
3f3b7c1a
TI
13529 switch (nid) {
13530 case 0x14:
13531 case 0x16:
13532 dac = 0x02;
13533 break;
13534 case 0x15:
b08b1637
TI
13535 case 0x1a: /* ALC259/269 only */
13536 case 0x1b: /* ALC259/269 only */
531d8791 13537 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13538 dac = 0x03;
13539 break;
13540 default:
c7a9434d
TI
13541 snd_printd(KERN_WARNING "hda_codec: "
13542 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13543 return 0;
13544 }
13545 if (spec->multiout.dac_nids[0] != dac &&
13546 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13547 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13548 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13549 HDA_OUTPUT));
13550 if (err < 0)
13551 return err;
3f3b7c1a
TI
13552 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13553 }
13554
3f3b7c1a 13555 if (nid != 0x16)
0afe5f89 13556 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13557 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13558 else /* mono */
0afe5f89 13559 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13560 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13561 if (err < 0)
13562 return err;
13563 return 0;
13564}
13565
13566/* add playback controls from the parsed DAC table */
13567static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13568 const struct auto_pin_cfg *cfg)
13569{
13570 hda_nid_t nid;
13571 int err;
13572
a361d84b 13573 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13574
13575 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13576 if (nid) {
13577 const char *name;
13578 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13579 name = "Speaker";
13580 else
13581 name = "Front";
13582 err = alc268_new_analog_output(spec, nid, name, 0);
13583 if (err < 0)
13584 return err;
13585 }
a361d84b
KY
13586
13587 nid = cfg->speaker_pins[0];
13588 if (nid == 0x1d) {
0afe5f89 13589 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13590 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13591 if (err < 0)
13592 return err;
7bfb9c03 13593 } else if (nid) {
3f3b7c1a
TI
13594 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13595 if (err < 0)
13596 return err;
a361d84b
KY
13597 }
13598 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13599 if (nid) {
13600 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13601 if (err < 0)
13602 return err;
13603 }
a361d84b
KY
13604
13605 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13606 if (nid == 0x16) {
0afe5f89 13607 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13608 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13609 if (err < 0)
13610 return err;
13611 }
ea1fb29a 13612 return 0;
a361d84b
KY
13613}
13614
13615/* create playback/capture controls for input pins */
05f5f477 13616static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13617 const struct auto_pin_cfg *cfg)
13618{
05f5f477 13619 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13620}
13621
e9af4f36
TI
13622static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13623 hda_nid_t nid, int pin_type)
13624{
13625 int idx;
13626
13627 alc_set_pin_output(codec, nid, pin_type);
13628 if (nid == 0x14 || nid == 0x16)
13629 idx = 0;
13630 else
13631 idx = 1;
13632 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13633}
13634
13635static void alc268_auto_init_multi_out(struct hda_codec *codec)
13636{
13637 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13638 int i;
13639
13640 for (i = 0; i < spec->autocfg.line_outs; i++) {
13641 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13642 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13643 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13644 }
13645}
13646
13647static void alc268_auto_init_hp_out(struct hda_codec *codec)
13648{
13649 struct alc_spec *spec = codec->spec;
13650 hda_nid_t pin;
e1ca7b4e 13651 int i;
e9af4f36 13652
e1ca7b4e
TI
13653 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13654 pin = spec->autocfg.hp_pins[i];
e9af4f36 13655 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13656 }
13657 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13658 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13659 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13660 }
13661 if (spec->autocfg.mono_out_pin)
13662 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13663 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13664}
13665
a361d84b
KY
13666static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13667{
13668 struct alc_spec *spec = codec->spec;
13669 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13670 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13671 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13672 unsigned int dac_vol1, dac_vol2;
13673
e9af4f36 13674 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13675 snd_hda_codec_write(codec, speaker_nid, 0,
13676 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13677 /* mute mixer inputs from 0x1d */
a361d84b
KY
13678 snd_hda_codec_write(codec, 0x0f, 0,
13679 AC_VERB_SET_AMP_GAIN_MUTE,
13680 AMP_IN_UNMUTE(1));
13681 snd_hda_codec_write(codec, 0x10, 0,
13682 AC_VERB_SET_AMP_GAIN_MUTE,
13683 AMP_IN_UNMUTE(1));
13684 } else {
e9af4f36 13685 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13686 snd_hda_codec_write(codec, 0x0f, 0,
13687 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13688 snd_hda_codec_write(codec, 0x10, 0,
13689 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13690 }
13691
13692 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13693 if (line_nid == 0x14)
a361d84b
KY
13694 dac_vol2 = AMP_OUT_ZERO;
13695 else if (line_nid == 0x15)
13696 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13697 if (hp_nid == 0x14)
a361d84b
KY
13698 dac_vol2 = AMP_OUT_ZERO;
13699 else if (hp_nid == 0x15)
13700 dac_vol1 = AMP_OUT_ZERO;
13701 if (line_nid != 0x16 || hp_nid != 0x16 ||
13702 spec->autocfg.line_out_pins[1] != 0x16 ||
13703 spec->autocfg.line_out_pins[2] != 0x16)
13704 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13705
13706 snd_hda_codec_write(codec, 0x02, 0,
13707 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13708 snd_hda_codec_write(codec, 0x03, 0,
13709 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13710}
13711
def319f9 13712/* pcm configuration: identical with ALC880 */
a361d84b
KY
13713#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13714#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13715#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13716#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13717
13718/*
13719 * BIOS auto configuration
13720 */
13721static int alc268_parse_auto_config(struct hda_codec *codec)
13722{
13723 struct alc_spec *spec = codec->spec;
13724 int err;
13725 static hda_nid_t alc268_ignore[] = { 0 };
13726
13727 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13728 alc268_ignore);
13729 if (err < 0)
13730 return err;
7e0e44d4
TI
13731 if (!spec->autocfg.line_outs) {
13732 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13733 spec->multiout.max_channels = 2;
13734 spec->no_analog = 1;
13735 goto dig_only;
13736 }
a361d84b 13737 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13738 }
a361d84b
KY
13739 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13740 if (err < 0)
13741 return err;
05f5f477 13742 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13743 if (err < 0)
13744 return err;
13745
13746 spec->multiout.max_channels = 2;
13747
7e0e44d4 13748 dig_only:
a361d84b 13749 /* digital only support output */
757899ac 13750 alc_auto_parse_digital(codec);
603c4019 13751 if (spec->kctls.list)
d88897ea 13752 add_mixer(spec, spec->kctls.list);
a361d84b 13753
892981ff 13754 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13755 add_mixer(spec, alc268_beep_mixer);
aef9d318 13756
d88897ea 13757 add_verb(spec, alc268_volume_init_verbs);
5908589f 13758 spec->num_mux_defs = 2;
61b9b9b1 13759 spec->input_mux = &spec->private_imux[0];
a361d84b 13760
776e184e
TI
13761 err = alc_auto_add_mic_boost(codec);
13762 if (err < 0)
13763 return err;
13764
6227cdce 13765 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13766
a361d84b
KY
13767 return 1;
13768}
13769
a361d84b 13770#define alc268_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 13771#define alc268_auto_init_input_src alc882_auto_init_input_src
a361d84b
KY
13772
13773/* init callback for auto-configuration model -- overriding the default init */
13774static void alc268_auto_init(struct hda_codec *codec)
13775{
f6c7e546 13776 struct alc_spec *spec = codec->spec;
a361d84b
KY
13777 alc268_auto_init_multi_out(codec);
13778 alc268_auto_init_hp_out(codec);
13779 alc268_auto_init_mono_speaker_out(codec);
13780 alc268_auto_init_analog_input(codec);
ae0ebbf7 13781 alc268_auto_init_input_src(codec);
757899ac 13782 alc_auto_init_digital(codec);
f6c7e546 13783 if (spec->unsol_event)
7fb0d78f 13784 alc_inithook(codec);
a361d84b
KY
13785}
13786
13787/*
13788 * configuration and preset
13789 */
ea734963 13790static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13791 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13792 [ALC268_3ST] = "3stack",
983f8ae4 13793 [ALC268_TOSHIBA] = "toshiba",
d273809e 13794 [ALC268_ACER] = "acer",
c238b4f4 13795 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13796 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13797 [ALC268_DELL] = "dell",
f12462c5 13798 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13799#ifdef CONFIG_SND_DEBUG
13800 [ALC268_TEST] = "test",
13801#endif
a361d84b
KY
13802 [ALC268_AUTO] = "auto",
13803};
13804
13805static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13806 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13807 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13808 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13809 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13810 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13811 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13812 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13813 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13814 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13815 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13816 /* almost compatible with toshiba but with optional digital outs;
13817 * auto-probing seems working fine
13818 */
8871e5b9 13819 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13820 ALC268_AUTO),
a361d84b 13821 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13822 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13823 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13824 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13825 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13826 {}
13827};
13828
3abf2f36
TI
13829/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13830static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13831 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13832 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13833 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13834 ALC268_TOSHIBA),
13835 {}
13836};
13837
a361d84b 13838static struct alc_config_preset alc268_presets[] = {
eb5a6621 13839 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13840 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13841 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13842 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13843 alc267_quanta_il1_verbs },
13844 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13845 .dac_nids = alc268_dac_nids,
13846 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13847 .adc_nids = alc268_adc_nids_alt,
13848 .hp_nid = 0x03,
13849 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13850 .channel_mode = alc268_modes,
4f5d1706
TI
13851 .unsol_event = alc_sku_unsol_event,
13852 .setup = alc267_quanta_il1_setup,
13853 .init_hook = alc_inithook,
eb5a6621 13854 },
a361d84b 13855 [ALC268_3ST] = {
aef9d318
TI
13856 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13857 alc268_beep_mixer },
a361d84b
KY
13858 .init_verbs = { alc268_base_init_verbs },
13859 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13860 .dac_nids = alc268_dac_nids,
13861 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13862 .adc_nids = alc268_adc_nids_alt,
e1406348 13863 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13864 .hp_nid = 0x03,
13865 .dig_out_nid = ALC268_DIGOUT_NID,
13866 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13867 .channel_mode = alc268_modes,
13868 .input_mux = &alc268_capture_source,
13869 },
d1a991a6 13870 [ALC268_TOSHIBA] = {
42171c17 13871 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13872 alc268_beep_mixer },
d273809e
TI
13873 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13874 alc268_toshiba_verbs },
d1a991a6
KY
13875 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13876 .dac_nids = alc268_dac_nids,
13877 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13878 .adc_nids = alc268_adc_nids_alt,
e1406348 13879 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13880 .hp_nid = 0x03,
13881 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13882 .channel_mode = alc268_modes,
13883 .input_mux = &alc268_capture_source,
d273809e 13884 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13885 .setup = alc268_toshiba_setup,
13886 .init_hook = alc268_toshiba_automute,
d273809e
TI
13887 },
13888 [ALC268_ACER] = {
432fd133 13889 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13890 alc268_beep_mixer },
d273809e
TI
13891 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13892 alc268_acer_verbs },
13893 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13894 .dac_nids = alc268_dac_nids,
13895 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13896 .adc_nids = alc268_adc_nids_alt,
e1406348 13897 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13898 .hp_nid = 0x02,
13899 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13900 .channel_mode = alc268_modes,
0ccb541c 13901 .input_mux = &alc268_acer_capture_source,
d273809e 13902 .unsol_event = alc268_acer_unsol_event,
889c4395 13903 .init_hook = alc268_acer_init_hook,
d1a991a6 13904 },
c238b4f4
TI
13905 [ALC268_ACER_DMIC] = {
13906 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13907 alc268_beep_mixer },
13908 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13909 alc268_acer_verbs },
13910 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13911 .dac_nids = alc268_dac_nids,
13912 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13913 .adc_nids = alc268_adc_nids_alt,
13914 .capsrc_nids = alc268_capsrc_nids,
13915 .hp_nid = 0x02,
13916 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13917 .channel_mode = alc268_modes,
13918 .input_mux = &alc268_acer_dmic_capture_source,
13919 .unsol_event = alc268_acer_unsol_event,
13920 .init_hook = alc268_acer_init_hook,
13921 },
8ef355da
KY
13922 [ALC268_ACER_ASPIRE_ONE] = {
13923 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13924 alc268_beep_mixer,
fdbc6626 13925 alc268_capture_nosrc_mixer },
8ef355da
KY
13926 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13927 alc268_acer_aspire_one_verbs },
13928 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13929 .dac_nids = alc268_dac_nids,
13930 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13931 .adc_nids = alc268_adc_nids_alt,
13932 .capsrc_nids = alc268_capsrc_nids,
13933 .hp_nid = 0x03,
13934 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13935 .channel_mode = alc268_modes,
8ef355da 13936 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13937 .setup = alc268_acer_lc_setup,
8ef355da
KY
13938 .init_hook = alc268_acer_lc_init_hook,
13939 },
3866f0b0 13940 [ALC268_DELL] = {
fdbc6626
TI
13941 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13942 alc268_capture_nosrc_mixer },
3866f0b0
TI
13943 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13944 alc268_dell_verbs },
13945 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13946 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13947 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13948 .adc_nids = alc268_adc_nids_alt,
13949 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13950 .hp_nid = 0x02,
13951 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13952 .channel_mode = alc268_modes,
a9fd4f3f 13953 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13954 .setup = alc268_dell_setup,
13955 .init_hook = alc_inithook,
3866f0b0 13956 },
f12462c5 13957 [ALC268_ZEPTO] = {
aef9d318
TI
13958 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13959 alc268_beep_mixer },
f12462c5
MT
13960 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13961 alc268_toshiba_verbs },
13962 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13963 .dac_nids = alc268_dac_nids,
13964 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13965 .adc_nids = alc268_adc_nids_alt,
e1406348 13966 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13967 .hp_nid = 0x03,
13968 .dig_out_nid = ALC268_DIGOUT_NID,
13969 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13970 .channel_mode = alc268_modes,
13971 .input_mux = &alc268_capture_source,
4f5d1706
TI
13972 .setup = alc268_toshiba_setup,
13973 .init_hook = alc268_toshiba_automute,
f12462c5 13974 },
86c53bd2
JW
13975#ifdef CONFIG_SND_DEBUG
13976 [ALC268_TEST] = {
13977 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13978 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13979 alc268_volume_init_verbs },
13980 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13981 .dac_nids = alc268_dac_nids,
13982 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13983 .adc_nids = alc268_adc_nids_alt,
e1406348 13984 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13985 .hp_nid = 0x03,
13986 .dig_out_nid = ALC268_DIGOUT_NID,
13987 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13988 .channel_mode = alc268_modes,
13989 .input_mux = &alc268_capture_source,
13990 },
13991#endif
a361d84b
KY
13992};
13993
13994static int patch_alc268(struct hda_codec *codec)
13995{
13996 struct alc_spec *spec;
13997 int board_config;
22971e3a 13998 int i, has_beep, err;
a361d84b 13999
ef86f581 14000 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
14001 if (spec == NULL)
14002 return -ENOMEM;
14003
14004 codec->spec = spec;
14005
14006 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14007 alc268_models,
14008 alc268_cfg_tbl);
14009
3abf2f36
TI
14010 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14011 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 14012 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 14013
a361d84b 14014 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
14015 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14016 codec->chip_name);
a361d84b
KY
14017 board_config = ALC268_AUTO;
14018 }
14019
14020 if (board_config == ALC268_AUTO) {
14021 /* automatic parse from the BIOS config */
14022 err = alc268_parse_auto_config(codec);
14023 if (err < 0) {
14024 alc_free(codec);
14025 return err;
14026 } else if (!err) {
14027 printk(KERN_INFO
14028 "hda_codec: Cannot set up configuration "
14029 "from BIOS. Using base mode...\n");
14030 board_config = ALC268_3ST;
14031 }
14032 }
14033
14034 if (board_config != ALC268_AUTO)
e9c364c0 14035 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14036
a361d84b
KY
14037 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14038 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14039 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14040
a361d84b
KY
14041 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14042
22971e3a
TI
14043 has_beep = 0;
14044 for (i = 0; i < spec->num_mixers; i++) {
14045 if (spec->mixers[i] == alc268_beep_mixer) {
14046 has_beep = 1;
14047 break;
14048 }
14049 }
14050
14051 if (has_beep) {
14052 err = snd_hda_attach_beep_device(codec, 0x1);
14053 if (err < 0) {
14054 alc_free(codec);
14055 return err;
14056 }
14057 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14058 /* override the amp caps for beep generator */
14059 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14060 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14061 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14062 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14063 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14064 }
aef9d318 14065
7e0e44d4 14066 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14067 /* check whether NID 0x07 is valid */
14068 unsigned int wcap = get_wcaps(codec, 0x07);
14069
defb5ab2 14070 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14071 /* get type */
a22d543a 14072 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14073 if (spec->auto_mic ||
14074 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14075 spec->adc_nids = alc268_adc_nids_alt;
14076 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14077 if (spec->auto_mic)
14078 fixup_automic_adc(codec);
fdbc6626
TI
14079 if (spec->auto_mic || spec->input_mux->num_items == 1)
14080 add_mixer(spec, alc268_capture_nosrc_mixer);
14081 else
14082 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14083 } else {
14084 spec->adc_nids = alc268_adc_nids;
14085 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14086 add_mixer(spec, alc268_capture_mixer);
a361d84b
KY
14087 }
14088 }
2134ea4f
TI
14089
14090 spec->vmaster_nid = 0x02;
14091
a361d84b
KY
14092 codec->patch_ops = alc_patch_ops;
14093 if (board_config == ALC268_AUTO)
14094 spec->init_hook = alc268_auto_init;
ea1fb29a 14095
bf1b0225
KY
14096 alc_init_jacks(codec);
14097
a361d84b
KY
14098 return 0;
14099}
14100
f6a92248
KY
14101/*
14102 * ALC269 channel source setting (2 channel)
14103 */
14104#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14105
14106#define alc269_dac_nids alc260_dac_nids
14107
14108static hda_nid_t alc269_adc_nids[1] = {
14109 /* ADC1 */
f53281e6
KY
14110 0x08,
14111};
14112
e01bf509
TI
14113static hda_nid_t alc269_capsrc_nids[1] = {
14114 0x23,
14115};
14116
84898e87
KY
14117static hda_nid_t alc269vb_adc_nids[1] = {
14118 /* ADC1 */
14119 0x09,
14120};
14121
14122static hda_nid_t alc269vb_capsrc_nids[1] = {
14123 0x22,
14124};
14125
6694635d
TI
14126static hda_nid_t alc269_adc_candidates[] = {
14127 0x08, 0x09, 0x07,
14128};
e01bf509 14129
f6a92248
KY
14130#define alc269_modes alc260_modes
14131#define alc269_capture_source alc880_lg_lw_capture_source
14132
14133static struct snd_kcontrol_new alc269_base_mixer[] = {
14134 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14135 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14136 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14137 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14138 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14140 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14141 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14142 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14143 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14144 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14145 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14146 { } /* end */
14147};
14148
60db6b53
KY
14149static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14150 /* output mixer control */
14151 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14152 {
14153 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14154 .name = "Master Playback Switch",
5e26dfd0 14155 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14156 .info = snd_hda_mixer_amp_switch_info,
14157 .get = snd_hda_mixer_amp_switch_get,
14158 .put = alc268_acer_master_sw_put,
14159 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14160 },
14161 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14162 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14163 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14164 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14165 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14166 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14167 { }
14168};
14169
64154835
TV
14170static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14171 /* output mixer control */
14172 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14173 {
14174 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14175 .name = "Master Playback Switch",
5e26dfd0 14176 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14177 .info = snd_hda_mixer_amp_switch_info,
14178 .get = snd_hda_mixer_amp_switch_get,
14179 .put = alc268_acer_master_sw_put,
14180 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14181 },
14182 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14183 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14184 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14185 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14186 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14187 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14188 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14189 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14190 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14191 { }
14192};
14193
84898e87 14194static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14195 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14196 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14198 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14199 { } /* end */
14200};
14201
84898e87
KY
14202static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14203 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14204 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14206 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14207 { } /* end */
14208};
14209
fe3eb0a7
KY
14210static struct snd_kcontrol_new alc269_asus_mixer[] = {
14211 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14212 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14213 { } /* end */
14214};
14215
f53281e6 14216/* capture mixer elements */
84898e87
KY
14217static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14218 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14219 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14220 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14221 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14222 { } /* end */
14223};
14224
14225static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14226 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14227 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14228 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14229 { } /* end */
14230};
14231
84898e87
KY
14232static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14233 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14234 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14235 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14236 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14237 { } /* end */
14238};
14239
14240static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14241 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14242 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14243 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14244 { } /* end */
14245};
14246
26f5df26 14247/* FSC amilo */
84898e87 14248#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14249
60db6b53
KY
14250static struct hda_verb alc269_quanta_fl1_verbs[] = {
14251 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14252 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14253 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14254 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14255 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14256 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14257 { }
14258};
f6a92248 14259
64154835
TV
14260static struct hda_verb alc269_lifebook_verbs[] = {
14261 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14262 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14263 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14264 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14265 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14266 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14267 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14268 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14269 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14270 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14271 { }
14272};
14273
60db6b53
KY
14274/* toggle speaker-output according to the hp-jack state */
14275static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14276{
14277 unsigned int present;
14278 unsigned char bits;
f6a92248 14279
864f92be 14280 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14281 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14282 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14283 HDA_AMP_MUTE, bits);
60db6b53 14284 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14285 HDA_AMP_MUTE, bits);
f6a92248 14286
60db6b53
KY
14287 snd_hda_codec_write(codec, 0x20, 0,
14288 AC_VERB_SET_COEF_INDEX, 0x0c);
14289 snd_hda_codec_write(codec, 0x20, 0,
14290 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14291
60db6b53
KY
14292 snd_hda_codec_write(codec, 0x20, 0,
14293 AC_VERB_SET_COEF_INDEX, 0x0c);
14294 snd_hda_codec_write(codec, 0x20, 0,
14295 AC_VERB_SET_PROC_COEF, 0x480);
14296}
f6a92248 14297
64154835
TV
14298/* toggle speaker-output according to the hp-jacks state */
14299static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14300{
14301 unsigned int present;
14302 unsigned char bits;
14303
14304 /* Check laptop headphone socket */
864f92be 14305 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14306
14307 /* Check port replicator headphone socket */
864f92be 14308 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14309
5dbd5ec6 14310 bits = present ? HDA_AMP_MUTE : 0;
64154835 14311 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14312 HDA_AMP_MUTE, bits);
64154835 14313 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14314 HDA_AMP_MUTE, bits);
64154835
TV
14315
14316 snd_hda_codec_write(codec, 0x20, 0,
14317 AC_VERB_SET_COEF_INDEX, 0x0c);
14318 snd_hda_codec_write(codec, 0x20, 0,
14319 AC_VERB_SET_PROC_COEF, 0x680);
14320
14321 snd_hda_codec_write(codec, 0x20, 0,
14322 AC_VERB_SET_COEF_INDEX, 0x0c);
14323 snd_hda_codec_write(codec, 0x20, 0,
14324 AC_VERB_SET_PROC_COEF, 0x480);
14325}
14326
64154835
TV
14327static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14328{
14329 unsigned int present_laptop;
14330 unsigned int present_dock;
14331
864f92be
WF
14332 present_laptop = snd_hda_jack_detect(codec, 0x18);
14333 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14334
14335 /* Laptop mic port overrides dock mic port, design decision */
14336 if (present_dock)
14337 snd_hda_codec_write(codec, 0x23, 0,
14338 AC_VERB_SET_CONNECT_SEL, 0x3);
14339 if (present_laptop)
14340 snd_hda_codec_write(codec, 0x23, 0,
14341 AC_VERB_SET_CONNECT_SEL, 0x0);
14342 if (!present_dock && !present_laptop)
14343 snd_hda_codec_write(codec, 0x23, 0,
14344 AC_VERB_SET_CONNECT_SEL, 0x1);
14345}
14346
60db6b53
KY
14347static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14348 unsigned int res)
14349{
4f5d1706
TI
14350 switch (res >> 26) {
14351 case ALC880_HP_EVENT:
60db6b53 14352 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14353 break;
14354 case ALC880_MIC_EVENT:
14355 alc_mic_automute(codec);
14356 break;
14357 }
60db6b53 14358}
f6a92248 14359
64154835
TV
14360static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14361 unsigned int res)
14362{
14363 if ((res >> 26) == ALC880_HP_EVENT)
14364 alc269_lifebook_speaker_automute(codec);
14365 if ((res >> 26) == ALC880_MIC_EVENT)
14366 alc269_lifebook_mic_autoswitch(codec);
14367}
14368
4f5d1706
TI
14369static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14370{
14371 struct alc_spec *spec = codec->spec;
20645d70
TI
14372 spec->autocfg.hp_pins[0] = 0x15;
14373 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14374 spec->ext_mic.pin = 0x18;
14375 spec->ext_mic.mux_idx = 0;
14376 spec->int_mic.pin = 0x19;
14377 spec->int_mic.mux_idx = 1;
14378 spec->auto_mic = 1;
14379}
14380
60db6b53
KY
14381static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14382{
14383 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14384 alc_mic_automute(codec);
60db6b53 14385}
f6a92248 14386
64154835
TV
14387static void alc269_lifebook_init_hook(struct hda_codec *codec)
14388{
14389 alc269_lifebook_speaker_automute(codec);
14390 alc269_lifebook_mic_autoswitch(codec);
14391}
14392
84898e87 14393static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14394 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14395 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14396 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14397 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14398 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14399 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14400 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14401 {}
14402};
14403
84898e87 14404static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14405 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14406 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14407 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14408 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14409 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14410 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14411 {}
14412};
14413
84898e87
KY
14414static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14415 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14416 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14417 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14418 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14419 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14420 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14421 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14422 {}
14423};
14424
14425static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14426 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14427 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14428 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14429 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14430 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14431 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14432 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14433 {}
14434};
14435
fe3eb0a7
KY
14436static struct hda_verb alc271_acer_dmic_verbs[] = {
14437 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14438 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14439 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14440 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14441 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14442 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14443 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14444 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14445 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14446 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14447 { }
14448};
14449
f53281e6
KY
14450/* toggle speaker-output according to the hp-jack state */
14451static void alc269_speaker_automute(struct hda_codec *codec)
14452{
ebb83eeb
KY
14453 struct alc_spec *spec = codec->spec;
14454 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14455 unsigned int present;
60db6b53 14456 unsigned char bits;
f53281e6 14457
ebb83eeb 14458 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14459 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14460 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14461 HDA_AMP_MUTE, bits);
f53281e6 14462 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14463 HDA_AMP_MUTE, bits);
cd372fb3 14464 snd_hda_input_jack_report(codec, nid);
f53281e6
KY
14465}
14466
f53281e6 14467/* unsolicited event for HP jack sensing */
84898e87 14468static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14469 unsigned int res)
f53281e6 14470{
4f5d1706
TI
14471 switch (res >> 26) {
14472 case ALC880_HP_EVENT:
f53281e6 14473 alc269_speaker_automute(codec);
4f5d1706
TI
14474 break;
14475 case ALC880_MIC_EVENT:
14476 alc_mic_automute(codec);
14477 break;
14478 }
f53281e6
KY
14479}
14480
226b1ec8 14481static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14482{
4f5d1706 14483 struct alc_spec *spec = codec->spec;
20645d70
TI
14484 spec->autocfg.hp_pins[0] = 0x15;
14485 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14486 spec->ext_mic.pin = 0x18;
14487 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14488 spec->int_mic.pin = 0x19;
14489 spec->int_mic.mux_idx = 1;
4f5d1706 14490 spec->auto_mic = 1;
f53281e6
KY
14491}
14492
226b1ec8 14493static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14494{
14495 struct alc_spec *spec = codec->spec;
20645d70
TI
14496 spec->autocfg.hp_pins[0] = 0x15;
14497 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14498 spec->ext_mic.pin = 0x18;
14499 spec->ext_mic.mux_idx = 0;
14500 spec->int_mic.pin = 0x12;
226b1ec8 14501 spec->int_mic.mux_idx = 5;
84898e87
KY
14502 spec->auto_mic = 1;
14503}
14504
226b1ec8 14505static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14506{
4f5d1706 14507 struct alc_spec *spec = codec->spec;
226b1ec8 14508 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14509 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14510 spec->ext_mic.pin = 0x18;
14511 spec->ext_mic.mux_idx = 0;
14512 spec->int_mic.pin = 0x19;
14513 spec->int_mic.mux_idx = 1;
14514 spec->auto_mic = 1;
f53281e6
KY
14515}
14516
226b1ec8
KY
14517static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14518{
14519 struct alc_spec *spec = codec->spec;
14520 spec->autocfg.hp_pins[0] = 0x21;
14521 spec->autocfg.speaker_pins[0] = 0x14;
14522 spec->ext_mic.pin = 0x18;
14523 spec->ext_mic.mux_idx = 0;
14524 spec->int_mic.pin = 0x12;
14525 spec->int_mic.mux_idx = 6;
14526 spec->auto_mic = 1;
14527}
14528
84898e87 14529static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14530{
14531 alc269_speaker_automute(codec);
4f5d1706 14532 alc_mic_automute(codec);
f53281e6
KY
14533}
14534
60db6b53
KY
14535/*
14536 * generic initialization of ADC, input mixers and output mixers
14537 */
14538static struct hda_verb alc269_init_verbs[] = {
14539 /*
14540 * Unmute ADC0 and set the default input to mic-in
14541 */
84898e87 14542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14543
14544 /*
84898e87 14545 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14546 */
14547 /* set vol=0 to output mixers */
14548 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14549 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14550
14551 /* set up input amps for analog loopback */
14552 /* Amp Indices: DAC = 0, mixer = 1 */
14553 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14555 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14556 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14557 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14558 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14559
14560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14561 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14562 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14563 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14564 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14565 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14566 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14567
14568 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14569 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14570
84898e87
KY
14571 /* FIXME: use Mux-type input source selection */
14572 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14573 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14574 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14575
84898e87
KY
14576 /* set EAPD */
14577 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14578 { }
14579};
14580
14581static struct hda_verb alc269vb_init_verbs[] = {
14582 /*
14583 * Unmute ADC0 and set the default input to mic-in
14584 */
14585 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14586
14587 /*
14588 * Set up output mixers (0x02 - 0x03)
14589 */
14590 /* set vol=0 to output mixers */
14591 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14592 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14593
14594 /* set up input amps for analog loopback */
14595 /* Amp Indices: DAC = 0, mixer = 1 */
14596 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14597 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14598 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14599 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14600 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14601 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14602
14603 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14604 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14606 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14607 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14608 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14609 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14610
14611 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14612 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14613
14614 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14615 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14616 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14617 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14618
14619 /* set EAPD */
14620 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14621 { }
14622};
14623
9d0b71b1
TI
14624#define alc269_auto_create_multi_out_ctls \
14625 alc268_auto_create_multi_out_ctls
05f5f477
TI
14626#define alc269_auto_create_input_ctls \
14627 alc268_auto_create_input_ctls
f6a92248
KY
14628
14629#ifdef CONFIG_SND_HDA_POWER_SAVE
14630#define alc269_loopbacks alc880_loopbacks
14631#endif
14632
def319f9 14633/* pcm configuration: identical with ALC880 */
f6a92248
KY
14634#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14635#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14636#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14637#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14638
f03d3115
TI
14639static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14640 .substreams = 1,
14641 .channels_min = 2,
14642 .channels_max = 8,
14643 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14644 /* NID is set in alc_build_pcms */
14645 .ops = {
14646 .open = alc880_playback_pcm_open,
14647 .prepare = alc880_playback_pcm_prepare,
14648 .cleanup = alc880_playback_pcm_cleanup
14649 },
14650};
14651
14652static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14653 .substreams = 1,
14654 .channels_min = 2,
14655 .channels_max = 2,
14656 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14657 /* NID is set in alc_build_pcms */
14658};
14659
ad35879a
TI
14660#ifdef CONFIG_SND_HDA_POWER_SAVE
14661static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14662{
14663 switch (codec->subsystem_id) {
14664 case 0x103c1586:
14665 return 1;
14666 }
14667 return 0;
14668}
14669
14670static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14671{
14672 /* update mute-LED according to the speaker mute state */
14673 if (nid == 0x01 || nid == 0x14) {
14674 int pinval;
14675 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14676 HDA_AMP_MUTE)
14677 pinval = 0x24;
14678 else
14679 pinval = 0x20;
14680 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14681 snd_hda_codec_update_cache(codec, 0x19, 0,
14682 AC_VERB_SET_PIN_WIDGET_CONTROL,
14683 pinval);
ad35879a
TI
14684 }
14685 return alc_check_power_status(codec, nid);
14686}
14687#endif /* CONFIG_SND_HDA_POWER_SAVE */
14688
840b64c0
TI
14689static int alc275_setup_dual_adc(struct hda_codec *codec)
14690{
14691 struct alc_spec *spec = codec->spec;
14692
14693 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14694 return 0;
14695 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14696 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14697 if (spec->ext_mic.pin <= 0x12) {
14698 spec->private_adc_nids[0] = 0x08;
14699 spec->private_adc_nids[1] = 0x11;
14700 spec->private_capsrc_nids[0] = 0x23;
14701 spec->private_capsrc_nids[1] = 0x22;
14702 } else {
14703 spec->private_adc_nids[0] = 0x11;
14704 spec->private_adc_nids[1] = 0x08;
14705 spec->private_capsrc_nids[0] = 0x22;
14706 spec->private_capsrc_nids[1] = 0x23;
14707 }
14708 spec->adc_nids = spec->private_adc_nids;
14709 spec->capsrc_nids = spec->private_capsrc_nids;
14710 spec->num_adc_nids = 2;
14711 spec->dual_adc_switch = 1;
14712 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14713 spec->adc_nids[0], spec->adc_nids[1]);
14714 return 1;
14715 }
14716 return 0;
14717}
14718
d433a678
TI
14719/* different alc269-variants */
14720enum {
14721 ALC269_TYPE_NORMAL,
48c88e82 14722 ALC269_TYPE_ALC258,
d433a678 14723 ALC269_TYPE_ALC259,
48c88e82
KY
14724 ALC269_TYPE_ALC269VB,
14725 ALC269_TYPE_ALC270,
d433a678
TI
14726 ALC269_TYPE_ALC271X,
14727};
14728
f6a92248
KY
14729/*
14730 * BIOS auto configuration
14731 */
14732static int alc269_parse_auto_config(struct hda_codec *codec)
14733{
14734 struct alc_spec *spec = codec->spec;
cfb9fb55 14735 int err;
f6a92248
KY
14736 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14737
14738 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14739 alc269_ignore);
14740 if (err < 0)
14741 return err;
14742
14743 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14744 if (err < 0)
14745 return err;
f3550d1b
TI
14746 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14747 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14748 else
14749 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14750 0x22, 0);
f6a92248
KY
14751 if (err < 0)
14752 return err;
14753
14754 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14755
757899ac 14756 alc_auto_parse_digital(codec);
f6a92248 14757
603c4019 14758 if (spec->kctls.list)
d88897ea 14759 add_mixer(spec, spec->kctls.list);
f6a92248 14760
d433a678 14761 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14762 add_verb(spec, alc269vb_init_verbs);
6227cdce 14763 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14764 } else {
14765 add_verb(spec, alc269_init_verbs);
6227cdce 14766 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14767 }
14768
f6a92248 14769 spec->num_mux_defs = 1;
61b9b9b1 14770 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14771
14772 if (!alc275_setup_dual_adc(codec))
14773 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14774 sizeof(alc269_adc_candidates));
6694635d 14775
f6a92248
KY
14776 err = alc_auto_add_mic_boost(codec);
14777 if (err < 0)
14778 return err;
14779
7e0e44d4 14780 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14781 set_capture_mixer(codec);
f53281e6 14782
f6a92248
KY
14783 return 1;
14784}
14785
e9af4f36
TI
14786#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14787#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248 14788#define alc269_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 14789#define alc269_auto_init_input_src alc882_auto_init_input_src
f6a92248
KY
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);
ae0ebbf7
TI
14799 if (!spec->dual_adc_switch)
14800 alc269_auto_init_input_src(codec);
757899ac 14801 alc_auto_init_digital(codec);
f6c7e546 14802 if (spec->unsol_event)
7fb0d78f 14803 alc_inithook(codec);
f6a92248
KY
14804}
14805
0ec33d1f
TI
14806#ifdef SND_HDA_NEEDS_RESUME
14807static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14808{
14809 int val = alc_read_coef_idx(codec, 0x04);
14810 if (power_up)
14811 val |= 1 << 11;
14812 else
14813 val &= ~(1 << 11);
14814 alc_write_coef_idx(codec, 0x04, val);
14815}
14816
977ddd6b
KY
14817#ifdef CONFIG_SND_HDA_POWER_SAVE
14818static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14819{
14820 struct alc_spec *spec = codec->spec;
977ddd6b 14821
0ec33d1f
TI
14822 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14823 alc269_toggle_power_output(codec, 0);
977ddd6b 14824 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14825 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14826 msleep(150);
14827 }
14828
14829 alc_shutup(codec);
14830 if (spec && spec->power_hook)
14831 spec->power_hook(codec);
14832 return 0;
14833}
0ec33d1f
TI
14834#endif /* CONFIG_SND_HDA_POWER_SAVE */
14835
977ddd6b
KY
14836static int alc269_resume(struct hda_codec *codec)
14837{
977ddd6b 14838 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14839 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14840 msleep(150);
14841 }
14842
14843 codec->patch_ops.init(codec);
14844
14845 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14846 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14847 msleep(200);
14848 }
14849
0ec33d1f
TI
14850 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14851 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14852
14853 snd_hda_codec_resume_amp(codec);
14854 snd_hda_codec_resume_cache(codec);
9e5341b9 14855 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14856 return 0;
14857}
0ec33d1f 14858#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14859
1a99d4a4 14860static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14861 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14862{
14863 int coef;
14864
58701120 14865 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14866 return;
1a99d4a4
KY
14867 coef = alc_read_coef_idx(codec, 0x1e);
14868 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14869}
14870
ff818c24
TI
14871enum {
14872 ALC269_FIXUP_SONY_VAIO,
74dc8909 14873 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14874 ALC269_FIXUP_DELL_M101Z,
022c92be 14875 ALC269_FIXUP_SKU_IGNORE,
ac612407 14876 ALC269_FIXUP_ASUS_G73JW,
357f915e 14877 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14878 ALC275_FIXUP_SONY_HWEQ,
ff818c24
TI
14879};
14880
ff818c24
TI
14881static const struct alc_fixup alc269_fixups[] = {
14882 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14883 .type = ALC_FIXUP_VERBS,
14884 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14885 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14886 {}
14887 }
ff818c24 14888 },
74dc8909 14889 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14890 .type = ALC_FIXUP_VERBS,
14891 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14892 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14893 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14894 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14895 { }
b5bfbc67
TI
14896 },
14897 .chained = true,
14898 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14899 },
145a902b 14900 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14901 .type = ALC_FIXUP_VERBS,
14902 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14903 /* Enables internal speaker */
14904 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14905 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14906 {}
14907 }
14908 },
022c92be 14909 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14910 .type = ALC_FIXUP_SKU,
14911 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14912 },
ac612407 14913 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14914 .type = ALC_FIXUP_PINS,
14915 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14916 { 0x17, 0x99130111 }, /* subwoofer */
14917 { }
14918 }
14919 },
357f915e 14920 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14921 .type = ALC_FIXUP_VERBS,
14922 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14923 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14924 {}
14925 }
14926 },
1a99d4a4 14927 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14928 .type = ALC_FIXUP_FUNC,
14929 .v.func = alc269_fixup_hweq,
14930 .chained = true,
14931 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
1a99d4a4 14932 }
ff818c24
TI
14933};
14934
14935static struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14936 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14937 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14938 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14939 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14940 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
022c92be 14941 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14942 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14943 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14944 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14945 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14946 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14947 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14948 {}
14949};
14950
14951
f6a92248
KY
14952/*
14953 * configuration and preset
14954 */
ea734963 14955static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14956 [ALC269_BASIC] = "basic",
2922c9af 14957 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14958 [ALC269_AMIC] = "laptop-amic",
14959 [ALC269_DMIC] = "laptop-dmic",
64154835 14960 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14961 [ALC269_LIFEBOOK] = "lifebook",
14962 [ALC269_AUTO] = "auto",
f6a92248
KY
14963};
14964
14965static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14966 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14967 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14968 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14969 ALC269_AMIC),
14970 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14971 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14972 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14973 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14974 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14975 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14976 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14977 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14978 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14979 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14980 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14981 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14982 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14983 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14984 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14985 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14986 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14987 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14988 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14989 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14990 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14991 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14992 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14993 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14994 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14995 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14996 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14997 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14998 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14999 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15000 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15001 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15002 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15003 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15004 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15005 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 15006 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 15007 ALC269_DMIC),
60db6b53 15008 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
15009 ALC269_DMIC),
15010 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15011 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 15012 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 15013 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
15014 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15015 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15016 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15017 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15018 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15019 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
15020 {}
15021};
15022
15023static struct alc_config_preset alc269_presets[] = {
15024 [ALC269_BASIC] = {
f9e336f6 15025 .mixers = { alc269_base_mixer },
f6a92248
KY
15026 .init_verbs = { alc269_init_verbs },
15027 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15028 .dac_nids = alc269_dac_nids,
15029 .hp_nid = 0x03,
15030 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15031 .channel_mode = alc269_modes,
15032 .input_mux = &alc269_capture_source,
15033 },
60db6b53
KY
15034 [ALC269_QUANTA_FL1] = {
15035 .mixers = { alc269_quanta_fl1_mixer },
15036 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15037 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15038 .dac_nids = alc269_dac_nids,
15039 .hp_nid = 0x03,
15040 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15041 .channel_mode = alc269_modes,
15042 .input_mux = &alc269_capture_source,
15043 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15044 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15045 .init_hook = alc269_quanta_fl1_init_hook,
15046 },
84898e87
KY
15047 [ALC269_AMIC] = {
15048 .mixers = { alc269_laptop_mixer },
15049 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15050 .init_verbs = { alc269_init_verbs,
84898e87 15051 alc269_laptop_amic_init_verbs },
f53281e6
KY
15052 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15053 .dac_nids = alc269_dac_nids,
15054 .hp_nid = 0x03,
15055 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15056 .channel_mode = alc269_modes,
84898e87
KY
15057 .unsol_event = alc269_laptop_unsol_event,
15058 .setup = alc269_laptop_amic_setup,
15059 .init_hook = alc269_laptop_inithook,
f53281e6 15060 },
84898e87
KY
15061 [ALC269_DMIC] = {
15062 .mixers = { alc269_laptop_mixer },
15063 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15064 .init_verbs = { alc269_init_verbs,
84898e87
KY
15065 alc269_laptop_dmic_init_verbs },
15066 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15067 .dac_nids = alc269_dac_nids,
15068 .hp_nid = 0x03,
15069 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15070 .channel_mode = alc269_modes,
15071 .unsol_event = alc269_laptop_unsol_event,
15072 .setup = alc269_laptop_dmic_setup,
15073 .init_hook = alc269_laptop_inithook,
15074 },
15075 [ALC269VB_AMIC] = {
15076 .mixers = { alc269vb_laptop_mixer },
15077 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15078 .init_verbs = { alc269vb_init_verbs,
15079 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15080 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15081 .dac_nids = alc269_dac_nids,
15082 .hp_nid = 0x03,
15083 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15084 .channel_mode = alc269_modes,
84898e87 15085 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 15086 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
15087 .init_hook = alc269_laptop_inithook,
15088 },
15089 [ALC269VB_DMIC] = {
15090 .mixers = { alc269vb_laptop_mixer },
15091 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15092 .init_verbs = { alc269vb_init_verbs,
15093 alc269vb_laptop_dmic_init_verbs },
15094 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15095 .dac_nids = alc269_dac_nids,
15096 .hp_nid = 0x03,
15097 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15098 .channel_mode = alc269_modes,
15099 .unsol_event = alc269_laptop_unsol_event,
15100 .setup = alc269vb_laptop_dmic_setup,
15101 .init_hook = alc269_laptop_inithook,
f53281e6 15102 },
26f5df26 15103 [ALC269_FUJITSU] = {
45bdd1c1 15104 .mixers = { alc269_fujitsu_mixer },
84898e87 15105 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15106 .init_verbs = { alc269_init_verbs,
84898e87 15107 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15108 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15109 .dac_nids = alc269_dac_nids,
15110 .hp_nid = 0x03,
15111 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15112 .channel_mode = alc269_modes,
84898e87
KY
15113 .unsol_event = alc269_laptop_unsol_event,
15114 .setup = alc269_laptop_dmic_setup,
15115 .init_hook = alc269_laptop_inithook,
26f5df26 15116 },
64154835
TV
15117 [ALC269_LIFEBOOK] = {
15118 .mixers = { alc269_lifebook_mixer },
15119 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15120 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15121 .dac_nids = alc269_dac_nids,
15122 .hp_nid = 0x03,
15123 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15124 .channel_mode = alc269_modes,
15125 .input_mux = &alc269_capture_source,
15126 .unsol_event = alc269_lifebook_unsol_event,
15127 .init_hook = alc269_lifebook_init_hook,
15128 },
fe3eb0a7
KY
15129 [ALC271_ACER] = {
15130 .mixers = { alc269_asus_mixer },
15131 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15132 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15133 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15134 .dac_nids = alc269_dac_nids,
15135 .adc_nids = alc262_dmic_adc_nids,
15136 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15137 .capsrc_nids = alc262_dmic_capsrc_nids,
15138 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15139 .channel_mode = alc269_modes,
15140 .input_mux = &alc269_capture_source,
15141 .dig_out_nid = ALC880_DIGOUT_NID,
15142 .unsol_event = alc_sku_unsol_event,
15143 .setup = alc269vb_laptop_dmic_setup,
15144 .init_hook = alc_inithook,
15145 },
f6a92248
KY
15146};
15147
977ddd6b
KY
15148static int alc269_fill_coef(struct hda_codec *codec)
15149{
15150 int val;
15151
15152 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15153 alc_write_coef_idx(codec, 0xf, 0x960b);
15154 alc_write_coef_idx(codec, 0xe, 0x8817);
15155 }
15156
15157 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15158 alc_write_coef_idx(codec, 0xf, 0x960b);
15159 alc_write_coef_idx(codec, 0xe, 0x8814);
15160 }
15161
15162 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15163 val = alc_read_coef_idx(codec, 0x04);
15164 /* Power up output pin */
15165 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15166 }
15167
15168 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15169 val = alc_read_coef_idx(codec, 0xd);
15170 if ((val & 0x0c00) >> 10 != 0x1) {
15171 /* Capless ramp up clock control */
15172 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15173 }
15174 val = alc_read_coef_idx(codec, 0x17);
15175 if ((val & 0x01c0) >> 6 != 0x4) {
15176 /* Class D power on reset */
15177 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15178 }
15179 }
15180 return 0;
15181}
15182
f6a92248
KY
15183static int patch_alc269(struct hda_codec *codec)
15184{
15185 struct alc_spec *spec;
48c88e82 15186 int board_config, coef;
f6a92248
KY
15187 int err;
15188
15189 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15190 if (spec == NULL)
15191 return -ENOMEM;
15192
15193 codec->spec = spec;
15194
da00c244
KY
15195 alc_auto_parse_customize_define(codec);
15196
c793bec5
KY
15197 if (codec->vendor_id == 0x10ec0269) {
15198 coef = alc_read_coef_idx(codec, 0);
15199 if ((coef & 0x00f0) == 0x0010) {
15200 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15201 spec->cdefine.platform_type == 1) {
15202 alc_codec_rename(codec, "ALC271X");
15203 spec->codec_variant = ALC269_TYPE_ALC271X;
15204 } else if ((coef & 0xf000) == 0x1000) {
15205 spec->codec_variant = ALC269_TYPE_ALC270;
15206 } else if ((coef & 0xf000) == 0x2000) {
15207 alc_codec_rename(codec, "ALC259");
15208 spec->codec_variant = ALC269_TYPE_ALC259;
15209 } else if ((coef & 0xf000) == 0x3000) {
15210 alc_codec_rename(codec, "ALC258");
15211 spec->codec_variant = ALC269_TYPE_ALC258;
15212 } else {
15213 alc_codec_rename(codec, "ALC269VB");
15214 spec->codec_variant = ALC269_TYPE_ALC269VB;
15215 }
15216 } else
15217 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15218 alc269_fill_coef(codec);
15219 }
977ddd6b 15220
f6a92248
KY
15221 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15222 alc269_models,
15223 alc269_cfg_tbl);
15224
15225 if (board_config < 0) {
9a11f1aa
TI
15226 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15227 codec->chip_name);
f6a92248
KY
15228 board_config = ALC269_AUTO;
15229 }
15230
b5bfbc67
TI
15231 if (board_config == ALC269_AUTO) {
15232 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15233 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15234 }
ff818c24 15235
f6a92248
KY
15236 if (board_config == ALC269_AUTO) {
15237 /* automatic parse from the BIOS config */
15238 err = alc269_parse_auto_config(codec);
15239 if (err < 0) {
15240 alc_free(codec);
15241 return err;
15242 } else if (!err) {
15243 printk(KERN_INFO
15244 "hda_codec: Cannot set up configuration "
15245 "from BIOS. Using base mode...\n");
15246 board_config = ALC269_BASIC;
15247 }
15248 }
15249
dc1eae25 15250 if (has_cdefine_beep(codec)) {
8af2591d
TI
15251 err = snd_hda_attach_beep_device(codec, 0x1);
15252 if (err < 0) {
15253 alc_free(codec);
15254 return err;
15255 }
680cd536
KK
15256 }
15257
f6a92248 15258 if (board_config != ALC269_AUTO)
e9c364c0 15259 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15260
84898e87 15261 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15262 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15263 * fix the sample rate of analog I/O to 44.1kHz
15264 */
15265 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15266 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15267 } else if (spec->dual_adc_switch) {
15268 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15269 /* switch ADC dynamically */
15270 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15271 } else {
15272 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15273 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15274 }
f6a92248
KY
15275 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15276 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15277
6694635d 15278 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15279 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15280 spec->adc_nids = alc269_adc_nids;
15281 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15282 spec->capsrc_nids = alc269_capsrc_nids;
15283 } else {
15284 spec->adc_nids = alc269vb_adc_nids;
15285 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15286 spec->capsrc_nids = alc269vb_capsrc_nids;
15287 }
84898e87
KY
15288 }
15289
f9e336f6 15290 if (!spec->cap_mixer)
b59bdf3b 15291 set_capture_mixer(codec);
dc1eae25 15292 if (has_cdefine_beep(codec))
da00c244 15293 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15294
b5bfbc67 15295 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15296
100d5eb3
TI
15297 spec->vmaster_nid = 0x02;
15298
f6a92248 15299 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15300#ifdef CONFIG_SND_HDA_POWER_SAVE
15301 codec->patch_ops.suspend = alc269_suspend;
15302#endif
15303#ifdef SND_HDA_NEEDS_RESUME
15304 codec->patch_ops.resume = alc269_resume;
15305#endif
f6a92248
KY
15306 if (board_config == ALC269_AUTO)
15307 spec->init_hook = alc269_auto_init;
bf1b0225
KY
15308
15309 alc_init_jacks(codec);
f6a92248
KY
15310#ifdef CONFIG_SND_HDA_POWER_SAVE
15311 if (!spec->loopback.amplist)
15312 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15313 if (alc269_mic2_for_mute_led(codec))
15314 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15315#endif
15316
15317 return 0;
15318}
15319
df694daa
KY
15320/*
15321 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15322 */
15323
15324/*
15325 * set the path ways for 2 channel output
15326 * need to set the codec line out and mic 1 pin widgets to inputs
15327 */
15328static struct hda_verb alc861_threestack_ch2_init[] = {
15329 /* set pin widget 1Ah (line in) for input */
15330 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15331 /* set pin widget 18h (mic1/2) for input, for mic also enable
15332 * the vref
15333 */
df694daa
KY
15334 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15335
9c7f852e
TI
15336 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15337#if 0
15338 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15339 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15340#endif
df694daa
KY
15341 { } /* end */
15342};
15343/*
15344 * 6ch mode
15345 * need to set the codec line out and mic 1 pin widgets to outputs
15346 */
15347static struct hda_verb alc861_threestack_ch6_init[] = {
15348 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15349 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15350 /* set pin widget 18h (mic1) for output (CLFE)*/
15351 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15352
15353 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15354 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15355
9c7f852e
TI
15356 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15357#if 0
15358 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15359 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15360#endif
df694daa
KY
15361 { } /* end */
15362};
15363
15364static struct hda_channel_mode alc861_threestack_modes[2] = {
15365 { 2, alc861_threestack_ch2_init },
15366 { 6, alc861_threestack_ch6_init },
15367};
22309c3e
TI
15368/* Set mic1 as input and unmute the mixer */
15369static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15370 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15371 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15372 { } /* end */
15373};
15374/* Set mic1 as output and mute mixer */
15375static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15376 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15377 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15378 { } /* end */
15379};
15380
15381static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15382 { 2, alc861_uniwill_m31_ch2_init },
15383 { 4, alc861_uniwill_m31_ch4_init },
15384};
df694daa 15385
7cdbff94
MD
15386/* Set mic1 and line-in as input and unmute the mixer */
15387static struct hda_verb alc861_asus_ch2_init[] = {
15388 /* set pin widget 1Ah (line in) for input */
15389 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15390 /* set pin widget 18h (mic1/2) for input, for mic also enable
15391 * the vref
15392 */
7cdbff94
MD
15393 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15394
15395 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15396#if 0
15397 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15398 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15399#endif
15400 { } /* end */
15401};
15402/* Set mic1 nad line-in as output and mute mixer */
15403static struct hda_verb alc861_asus_ch6_init[] = {
15404 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15405 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15406 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15407 /* set pin widget 18h (mic1) for output (CLFE)*/
15408 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15409 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15410 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15411 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15412
15413 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15414#if 0
15415 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15416 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15417#endif
15418 { } /* end */
15419};
15420
15421static struct hda_channel_mode alc861_asus_modes[2] = {
15422 { 2, alc861_asus_ch2_init },
15423 { 6, alc861_asus_ch6_init },
15424};
15425
df694daa
KY
15426/* patch-ALC861 */
15427
15428static struct snd_kcontrol_new alc861_base_mixer[] = {
15429 /* output mixer control */
15430 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15431 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15432 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15433 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15434 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15435
15436 /*Input mixer control */
15437 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15438 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15439 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15440 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15441 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15442 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15443 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15444 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15445 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15446 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15447
df694daa
KY
15448 { } /* end */
15449};
15450
15451static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15452 /* output mixer control */
15453 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15454 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15455 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15456 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15457 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15458
15459 /* Input mixer control */
15460 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15462 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15463 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15464 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15465 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15467 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15468 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15469 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15470
df694daa
KY
15471 {
15472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15473 .name = "Channel Mode",
15474 .info = alc_ch_mode_info,
15475 .get = alc_ch_mode_get,
15476 .put = alc_ch_mode_put,
15477 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15478 },
15479 { } /* end */
a53d1aec
TD
15480};
15481
d1d985f0 15482static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15483 /* output mixer control */
15484 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15486 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15487
a53d1aec 15488 { } /* end */
f12ab1e0 15489};
a53d1aec 15490
22309c3e
TI
15491static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15492 /* output mixer control */
15493 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15494 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15495 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15496 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15497 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15498
15499 /* Input mixer control */
15500 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15501 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15502 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15503 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15504 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15505 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15507 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15508 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15509 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15510
22309c3e
TI
15511 {
15512 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15513 .name = "Channel Mode",
15514 .info = alc_ch_mode_info,
15515 .get = alc_ch_mode_get,
15516 .put = alc_ch_mode_put,
15517 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15518 },
15519 { } /* end */
f12ab1e0 15520};
7cdbff94
MD
15521
15522static struct snd_kcontrol_new alc861_asus_mixer[] = {
15523 /* output mixer control */
15524 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15525 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15526 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15527 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15528 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15529
15530 /* Input mixer control */
15531 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15532 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15533 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15534 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15535 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15536 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15538 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15539 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15540 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15541
7cdbff94
MD
15542 {
15543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15544 .name = "Channel Mode",
15545 .info = alc_ch_mode_info,
15546 .get = alc_ch_mode_get,
15547 .put = alc_ch_mode_put,
15548 .private_value = ARRAY_SIZE(alc861_asus_modes),
15549 },
15550 { }
56bb0cab
TI
15551};
15552
15553/* additional mixer */
d1d985f0 15554static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15555 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15556 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15557 { }
15558};
7cdbff94 15559
df694daa
KY
15560/*
15561 * generic initialization of ADC, input mixers and output mixers
15562 */
15563static struct hda_verb alc861_base_init_verbs[] = {
15564 /*
15565 * Unmute ADC0 and set the default input to mic-in
15566 */
15567 /* port-A for surround (rear panel) */
15568 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15569 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15570 /* port-B for mic-in (rear panel) with vref */
15571 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15572 /* port-C for line-in (rear panel) */
15573 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15574 /* port-D for Front */
15575 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15576 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15577 /* port-E for HP out (front panel) */
15578 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15579 /* route front PCM to HP */
9dece1d7 15580 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15581 /* port-F for mic-in (front panel) with vref */
15582 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15583 /* port-G for CLFE (rear panel) */
15584 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15585 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15586 /* port-H for side (rear panel) */
15587 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15588 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15589 /* CD-in */
15590 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15591 /* route front mic to ADC1*/
15592 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15593 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15594
df694daa
KY
15595 /* Unmute DAC0~3 & spdif out*/
15596 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15597 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15598 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15599 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15601
df694daa
KY
15602 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15603 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15604 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15605 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15606 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15607
df694daa
KY
15608 /* Unmute Stereo Mixer 15 */
15609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15611 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15612 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15613
15614 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15615 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15616 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15617 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15618 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15619 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15620 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15621 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15622 /* hp used DAC 3 (Front) */
15623 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15624 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15625
15626 { }
15627};
15628
15629static struct hda_verb alc861_threestack_init_verbs[] = {
15630 /*
15631 * Unmute ADC0 and set the default input to mic-in
15632 */
15633 /* port-A for surround (rear panel) */
15634 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15635 /* port-B for mic-in (rear panel) with vref */
15636 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15637 /* port-C for line-in (rear panel) */
15638 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15639 /* port-D for Front */
15640 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15641 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15642 /* port-E for HP out (front panel) */
15643 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15644 /* route front PCM to HP */
9dece1d7 15645 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15646 /* port-F for mic-in (front panel) with vref */
15647 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15648 /* port-G for CLFE (rear panel) */
15649 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15650 /* port-H for side (rear panel) */
15651 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15652 /* CD-in */
15653 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15654 /* route front mic to ADC1*/
15655 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15657 /* Unmute DAC0~3 & spdif out*/
15658 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15659 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15660 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15661 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15662 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15663
df694daa
KY
15664 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15665 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15666 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15667 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15668 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15669
df694daa
KY
15670 /* Unmute Stereo Mixer 15 */
15671 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15672 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15673 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15674 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15675
15676 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15677 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15678 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15679 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15680 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15681 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15682 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15683 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15684 /* hp used DAC 3 (Front) */
15685 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15686 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15687 { }
15688};
22309c3e
TI
15689
15690static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15691 /*
15692 * Unmute ADC0 and set the default input to mic-in
15693 */
15694 /* port-A for surround (rear panel) */
15695 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15696 /* port-B for mic-in (rear panel) with vref */
15697 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15698 /* port-C for line-in (rear panel) */
15699 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15700 /* port-D for Front */
15701 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15702 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15703 /* port-E for HP out (front panel) */
f12ab1e0
TI
15704 /* this has to be set to VREF80 */
15705 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15706 /* route front PCM to HP */
9dece1d7 15707 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15708 /* port-F for mic-in (front panel) with vref */
15709 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15710 /* port-G for CLFE (rear panel) */
15711 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15712 /* port-H for side (rear panel) */
15713 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15714 /* CD-in */
15715 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15716 /* route front mic to ADC1*/
15717 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15718 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719 /* Unmute DAC0~3 & spdif out*/
15720 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15721 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15722 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15723 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15724 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15725
22309c3e
TI
15726 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15727 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15728 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15729 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15730 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15731
22309c3e
TI
15732 /* Unmute Stereo Mixer 15 */
15733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15737
15738 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15739 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15740 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15741 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15742 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15743 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15744 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15745 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15746 /* hp used DAC 3 (Front) */
15747 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15748 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15749 { }
15750};
15751
7cdbff94
MD
15752static struct hda_verb alc861_asus_init_verbs[] = {
15753 /*
15754 * Unmute ADC0 and set the default input to mic-in
15755 */
f12ab1e0
TI
15756 /* port-A for surround (rear panel)
15757 * according to codec#0 this is the HP jack
15758 */
7cdbff94
MD
15759 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15760 /* route front PCM to HP */
15761 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15762 /* port-B for mic-in (rear panel) with vref */
15763 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15764 /* port-C for line-in (rear panel) */
15765 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15766 /* port-D for Front */
15767 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15768 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15769 /* port-E for HP out (front panel) */
f12ab1e0
TI
15770 /* this has to be set to VREF80 */
15771 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15772 /* route front PCM to HP */
9dece1d7 15773 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15774 /* port-F for mic-in (front panel) with vref */
15775 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15776 /* port-G for CLFE (rear panel) */
15777 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15778 /* port-H for side (rear panel) */
15779 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15780 /* CD-in */
15781 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15782 /* route front mic to ADC1*/
15783 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15784 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15785 /* Unmute DAC0~3 & spdif out*/
15786 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15787 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15788 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15789 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15791 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15792 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15793 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15794 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15795 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15796
7cdbff94
MD
15797 /* Unmute Stereo Mixer 15 */
15798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15799 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15800 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15801 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15802
15803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15804 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15805 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15806 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15807 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15808 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15809 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15810 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15811 /* hp used DAC 3 (Front) */
15812 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15813 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15814 { }
15815};
15816
56bb0cab
TI
15817/* additional init verbs for ASUS laptops */
15818static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15819 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15820 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15821 { }
15822};
7cdbff94 15823
df694daa
KY
15824/*
15825 * generic initialization of ADC, input mixers and output mixers
15826 */
15827static struct hda_verb alc861_auto_init_verbs[] = {
15828 /*
15829 * Unmute ADC0 and set the default input to mic-in
15830 */
f12ab1e0 15831 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15832 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15833
df694daa
KY
15834 /* Unmute DAC0~3 & spdif out*/
15835 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15836 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15837 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15838 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15839 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15840
df694daa
KY
15841 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15842 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15843 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15844 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15845 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15846
df694daa
KY
15847 /* Unmute Stereo Mixer 15 */
15848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15849 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15850 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15852
1c20930a
TI
15853 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15854 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15855 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15856 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15857 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15858 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15859 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15860 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15861
15862 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15863 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15864 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15865 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15866 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15867 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15868 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15869 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15870
f12ab1e0 15871 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15872
15873 { }
15874};
15875
a53d1aec
TD
15876static struct hda_verb alc861_toshiba_init_verbs[] = {
15877 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15878
a53d1aec
TD
15879 { }
15880};
15881
15882/* toggle speaker-output according to the hp-jack state */
15883static void alc861_toshiba_automute(struct hda_codec *codec)
15884{
864f92be 15885 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15886
47fd830a
TI
15887 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15888 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15889 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15890 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15891}
15892
15893static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15894 unsigned int res)
15895{
a53d1aec
TD
15896 if ((res >> 26) == ALC880_HP_EVENT)
15897 alc861_toshiba_automute(codec);
15898}
15899
def319f9 15900/* pcm configuration: identical with ALC880 */
df694daa
KY
15901#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15902#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15903#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15904#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15905
15906
15907#define ALC861_DIGOUT_NID 0x07
15908
15909static struct hda_channel_mode alc861_8ch_modes[1] = {
15910 { 8, NULL }
15911};
15912
15913static hda_nid_t alc861_dac_nids[4] = {
15914 /* front, surround, clfe, side */
15915 0x03, 0x06, 0x05, 0x04
15916};
15917
9c7f852e
TI
15918static hda_nid_t alc660_dac_nids[3] = {
15919 /* front, clfe, surround */
15920 0x03, 0x05, 0x06
15921};
15922
df694daa
KY
15923static hda_nid_t alc861_adc_nids[1] = {
15924 /* ADC0-2 */
15925 0x08,
15926};
15927
15928static struct hda_input_mux alc861_capture_source = {
15929 .num_items = 5,
15930 .items = {
15931 { "Mic", 0x0 },
15932 { "Front Mic", 0x3 },
15933 { "Line", 0x1 },
15934 { "CD", 0x4 },
15935 { "Mixer", 0x5 },
15936 },
15937};
15938
1c20930a
TI
15939static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15940{
15941 struct alc_spec *spec = codec->spec;
15942 hda_nid_t mix, srcs[5];
15943 int i, j, num;
15944
15945 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15946 return 0;
15947 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15948 if (num < 0)
15949 return 0;
15950 for (i = 0; i < num; i++) {
15951 unsigned int type;
a22d543a 15952 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15953 if (type != AC_WID_AUD_OUT)
15954 continue;
15955 for (j = 0; j < spec->multiout.num_dacs; j++)
15956 if (spec->multiout.dac_nids[j] == srcs[i])
15957 break;
15958 if (j >= spec->multiout.num_dacs)
15959 return srcs[i];
15960 }
15961 return 0;
15962}
15963
df694daa 15964/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15965static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15966 const struct auto_pin_cfg *cfg)
df694daa 15967{
1c20930a 15968 struct alc_spec *spec = codec->spec;
df694daa 15969 int i;
1c20930a 15970 hda_nid_t nid, dac;
df694daa
KY
15971
15972 spec->multiout.dac_nids = spec->private_dac_nids;
15973 for (i = 0; i < cfg->line_outs; i++) {
15974 nid = cfg->line_out_pins[i];
1c20930a
TI
15975 dac = alc861_look_for_dac(codec, nid);
15976 if (!dac)
15977 continue;
15978 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15979 }
df694daa
KY
15980 return 0;
15981}
15982
bcb2f0f5
TI
15983static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15984 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15985{
bcb2f0f5 15986 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15987 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15988}
15989
bcb2f0f5
TI
15990#define alc861_create_out_sw(codec, pfx, nid, chs) \
15991 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15992
df694daa 15993/* add playback controls from the parsed DAC table */
1c20930a 15994static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15995 const struct auto_pin_cfg *cfg)
15996{
1c20930a 15997 struct alc_spec *spec = codec->spec;
ea734963 15998 static const char * const chname[4] = {
f12ab1e0
TI
15999 "Front", "Surround", NULL /*CLFE*/, "Side"
16000 };
bcb2f0f5 16001 const char *pfx = alc_get_line_out_pfx(cfg, true);
df694daa 16002 hda_nid_t nid;
1c20930a
TI
16003 int i, err;
16004
df694daa
KY
16005 for (i = 0; i < cfg->line_outs; i++) {
16006 nid = spec->multiout.dac_nids[i];
f12ab1e0 16007 if (!nid)
df694daa 16008 continue;
bcb2f0f5 16009 if (!pfx && i == 2) {
df694daa 16010 /* Center/LFE */
1c20930a 16011 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 16012 if (err < 0)
df694daa 16013 return err;
1c20930a 16014 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 16015 if (err < 0)
df694daa
KY
16016 return err;
16017 } else {
bcb2f0f5 16018 const char *name = pfx;
5a882646
DH
16019 int index = i;
16020 if (!name) {
bcb2f0f5 16021 name = chname[i];
5a882646
DH
16022 index = 0;
16023 }
16024 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 16025 if (err < 0)
df694daa
KY
16026 return err;
16027 }
16028 }
16029 return 0;
16030}
16031
1c20930a 16032static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16033{
1c20930a 16034 struct alc_spec *spec = codec->spec;
df694daa
KY
16035 int err;
16036 hda_nid_t nid;
16037
f12ab1e0 16038 if (!pin)
df694daa
KY
16039 return 0;
16040
16041 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16042 nid = alc861_look_for_dac(codec, pin);
16043 if (nid) {
16044 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16045 if (err < 0)
16046 return err;
16047 spec->multiout.hp_nid = nid;
16048 }
df694daa
KY
16049 }
16050 return 0;
16051}
16052
16053/* create playback/capture controls for input pins */
05f5f477 16054static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16055 const struct auto_pin_cfg *cfg)
df694daa 16056{
05f5f477 16057 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16058}
16059
f12ab1e0
TI
16060static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16061 hda_nid_t nid,
1c20930a 16062 int pin_type, hda_nid_t dac)
df694daa 16063{
1c20930a
TI
16064 hda_nid_t mix, srcs[5];
16065 int i, num;
16066
564c5bea
JL
16067 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16068 pin_type);
1c20930a 16069 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16070 AMP_OUT_UNMUTE);
1c20930a
TI
16071 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16072 return;
16073 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16074 if (num < 0)
16075 return;
16076 for (i = 0; i < num; i++) {
16077 unsigned int mute;
16078 if (srcs[i] == dac || srcs[i] == 0x15)
16079 mute = AMP_IN_UNMUTE(i);
16080 else
16081 mute = AMP_IN_MUTE(i);
16082 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16083 mute);
16084 }
df694daa
KY
16085}
16086
16087static void alc861_auto_init_multi_out(struct hda_codec *codec)
16088{
16089 struct alc_spec *spec = codec->spec;
16090 int i;
16091
16092 for (i = 0; i < spec->autocfg.line_outs; i++) {
16093 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16094 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16095 if (nid)
baba8ee9 16096 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16097 spec->multiout.dac_nids[i]);
df694daa
KY
16098 }
16099}
16100
16101static void alc861_auto_init_hp_out(struct hda_codec *codec)
16102{
16103 struct alc_spec *spec = codec->spec;
df694daa 16104
15870f05
TI
16105 if (spec->autocfg.hp_outs)
16106 alc861_auto_set_output_and_unmute(codec,
16107 spec->autocfg.hp_pins[0],
16108 PIN_HP,
1c20930a 16109 spec->multiout.hp_nid);
15870f05
TI
16110 if (spec->autocfg.speaker_outs)
16111 alc861_auto_set_output_and_unmute(codec,
16112 spec->autocfg.speaker_pins[0],
16113 PIN_OUT,
1c20930a 16114 spec->multiout.dac_nids[0]);
df694daa
KY
16115}
16116
16117static void alc861_auto_init_analog_input(struct hda_codec *codec)
16118{
16119 struct alc_spec *spec = codec->spec;
66ceeb6b 16120 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16121 int i;
16122
66ceeb6b
TI
16123 for (i = 0; i < cfg->num_inputs; i++) {
16124 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16125 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16126 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16127 }
16128}
16129
16130/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16131/* return 1 if successful, 0 if the proper config is not found,
16132 * or a negative error code
16133 */
df694daa
KY
16134static int alc861_parse_auto_config(struct hda_codec *codec)
16135{
16136 struct alc_spec *spec = codec->spec;
16137 int err;
16138 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16139
f12ab1e0
TI
16140 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16141 alc861_ignore);
16142 if (err < 0)
df694daa 16143 return err;
f12ab1e0 16144 if (!spec->autocfg.line_outs)
df694daa
KY
16145 return 0; /* can't find valid BIOS pin config */
16146
1c20930a 16147 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
16148 if (err < 0)
16149 return err;
1c20930a 16150 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16151 if (err < 0)
16152 return err;
1c20930a 16153 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16154 if (err < 0)
16155 return err;
05f5f477 16156 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16157 if (err < 0)
df694daa
KY
16158 return err;
16159
16160 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16161
757899ac 16162 alc_auto_parse_digital(codec);
df694daa 16163
603c4019 16164 if (spec->kctls.list)
d88897ea 16165 add_mixer(spec, spec->kctls.list);
df694daa 16166
d88897ea 16167 add_verb(spec, alc861_auto_init_verbs);
df694daa 16168
a1e8d2da 16169 spec->num_mux_defs = 1;
61b9b9b1 16170 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16171
16172 spec->adc_nids = alc861_adc_nids;
16173 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16174 set_capture_mixer(codec);
df694daa 16175
6227cdce 16176 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16177
df694daa
KY
16178 return 1;
16179}
16180
ae6b813a
TI
16181/* additional initialization for auto-configuration model */
16182static void alc861_auto_init(struct hda_codec *codec)
df694daa 16183{
f6c7e546 16184 struct alc_spec *spec = codec->spec;
df694daa
KY
16185 alc861_auto_init_multi_out(codec);
16186 alc861_auto_init_hp_out(codec);
16187 alc861_auto_init_analog_input(codec);
757899ac 16188 alc_auto_init_digital(codec);
f6c7e546 16189 if (spec->unsol_event)
7fb0d78f 16190 alc_inithook(codec);
df694daa
KY
16191}
16192
cb53c626
TI
16193#ifdef CONFIG_SND_HDA_POWER_SAVE
16194static struct hda_amp_list alc861_loopbacks[] = {
16195 { 0x15, HDA_INPUT, 0 },
16196 { 0x15, HDA_INPUT, 1 },
16197 { 0x15, HDA_INPUT, 2 },
16198 { 0x15, HDA_INPUT, 3 },
16199 { } /* end */
16200};
16201#endif
16202
df694daa
KY
16203
16204/*
16205 * configuration and preset
16206 */
ea734963 16207static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16208 [ALC861_3ST] = "3stack",
16209 [ALC660_3ST] = "3stack-660",
16210 [ALC861_3ST_DIG] = "3stack-dig",
16211 [ALC861_6ST_DIG] = "6stack-dig",
16212 [ALC861_UNIWILL_M31] = "uniwill-m31",
16213 [ALC861_TOSHIBA] = "toshiba",
16214 [ALC861_ASUS] = "asus",
16215 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16216 [ALC861_AUTO] = "auto",
16217};
16218
16219static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16220 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16221 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16222 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16223 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16224 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16225 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16226 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16227 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16228 * Any other models that need this preset?
16229 */
16230 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16231 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16232 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16233 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16234 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16235 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16236 /* FIXME: the below seems conflict */
16237 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16238 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16239 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16240 {}
16241};
16242
16243static struct alc_config_preset alc861_presets[] = {
16244 [ALC861_3ST] = {
16245 .mixers = { alc861_3ST_mixer },
16246 .init_verbs = { alc861_threestack_init_verbs },
16247 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16248 .dac_nids = alc861_dac_nids,
16249 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16250 .channel_mode = alc861_threestack_modes,
4e195a7b 16251 .need_dac_fix = 1,
df694daa
KY
16252 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16253 .adc_nids = alc861_adc_nids,
16254 .input_mux = &alc861_capture_source,
16255 },
16256 [ALC861_3ST_DIG] = {
16257 .mixers = { alc861_base_mixer },
16258 .init_verbs = { alc861_threestack_init_verbs },
16259 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16260 .dac_nids = alc861_dac_nids,
16261 .dig_out_nid = ALC861_DIGOUT_NID,
16262 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16263 .channel_mode = alc861_threestack_modes,
4e195a7b 16264 .need_dac_fix = 1,
df694daa
KY
16265 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16266 .adc_nids = alc861_adc_nids,
16267 .input_mux = &alc861_capture_source,
16268 },
16269 [ALC861_6ST_DIG] = {
16270 .mixers = { alc861_base_mixer },
16271 .init_verbs = { alc861_base_init_verbs },
16272 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16273 .dac_nids = alc861_dac_nids,
16274 .dig_out_nid = ALC861_DIGOUT_NID,
16275 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16276 .channel_mode = alc861_8ch_modes,
16277 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16278 .adc_nids = alc861_adc_nids,
16279 .input_mux = &alc861_capture_source,
16280 },
9c7f852e
TI
16281 [ALC660_3ST] = {
16282 .mixers = { alc861_3ST_mixer },
16283 .init_verbs = { alc861_threestack_init_verbs },
16284 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16285 .dac_nids = alc660_dac_nids,
16286 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16287 .channel_mode = alc861_threestack_modes,
4e195a7b 16288 .need_dac_fix = 1,
9c7f852e
TI
16289 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16290 .adc_nids = alc861_adc_nids,
16291 .input_mux = &alc861_capture_source,
16292 },
22309c3e
TI
16293 [ALC861_UNIWILL_M31] = {
16294 .mixers = { alc861_uniwill_m31_mixer },
16295 .init_verbs = { alc861_uniwill_m31_init_verbs },
16296 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16297 .dac_nids = alc861_dac_nids,
16298 .dig_out_nid = ALC861_DIGOUT_NID,
16299 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16300 .channel_mode = alc861_uniwill_m31_modes,
16301 .need_dac_fix = 1,
16302 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16303 .adc_nids = alc861_adc_nids,
16304 .input_mux = &alc861_capture_source,
16305 },
a53d1aec
TD
16306 [ALC861_TOSHIBA] = {
16307 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16308 .init_verbs = { alc861_base_init_verbs,
16309 alc861_toshiba_init_verbs },
a53d1aec
TD
16310 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16311 .dac_nids = alc861_dac_nids,
16312 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16313 .channel_mode = alc883_3ST_2ch_modes,
16314 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16315 .adc_nids = alc861_adc_nids,
16316 .input_mux = &alc861_capture_source,
16317 .unsol_event = alc861_toshiba_unsol_event,
16318 .init_hook = alc861_toshiba_automute,
16319 },
7cdbff94
MD
16320 [ALC861_ASUS] = {
16321 .mixers = { alc861_asus_mixer },
16322 .init_verbs = { alc861_asus_init_verbs },
16323 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16324 .dac_nids = alc861_dac_nids,
16325 .dig_out_nid = ALC861_DIGOUT_NID,
16326 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16327 .channel_mode = alc861_asus_modes,
16328 .need_dac_fix = 1,
16329 .hp_nid = 0x06,
16330 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16331 .adc_nids = alc861_adc_nids,
16332 .input_mux = &alc861_capture_source,
16333 },
56bb0cab
TI
16334 [ALC861_ASUS_LAPTOP] = {
16335 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16336 .init_verbs = { alc861_asus_init_verbs,
16337 alc861_asus_laptop_init_verbs },
16338 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16339 .dac_nids = alc861_dac_nids,
16340 .dig_out_nid = ALC861_DIGOUT_NID,
16341 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16342 .channel_mode = alc883_3ST_2ch_modes,
16343 .need_dac_fix = 1,
16344 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16345 .adc_nids = alc861_adc_nids,
16346 .input_mux = &alc861_capture_source,
16347 },
16348};
df694daa 16349
cfc9b06f
TI
16350/* Pin config fixes */
16351enum {
16352 PINFIX_FSC_AMILO_PI1505,
16353};
16354
cfc9b06f
TI
16355static const struct alc_fixup alc861_fixups[] = {
16356 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16357 .type = ALC_FIXUP_PINS,
16358 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16359 { 0x0b, 0x0221101f }, /* HP */
16360 { 0x0f, 0x90170310 }, /* speaker */
16361 { }
16362 }
cfc9b06f
TI
16363 },
16364};
16365
16366static struct snd_pci_quirk alc861_fixup_tbl[] = {
16367 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16368 {}
16369};
df694daa
KY
16370
16371static int patch_alc861(struct hda_codec *codec)
16372{
16373 struct alc_spec *spec;
16374 int board_config;
16375 int err;
16376
dc041e0b 16377 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16378 if (spec == NULL)
16379 return -ENOMEM;
16380
f12ab1e0 16381 codec->spec = spec;
df694daa 16382
f5fcc13c
TI
16383 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16384 alc861_models,
16385 alc861_cfg_tbl);
9c7f852e 16386
f5fcc13c 16387 if (board_config < 0) {
9a11f1aa
TI
16388 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16389 codec->chip_name);
df694daa
KY
16390 board_config = ALC861_AUTO;
16391 }
16392
b5bfbc67
TI
16393 if (board_config == ALC861_AUTO) {
16394 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16395 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16396 }
cfc9b06f 16397
df694daa
KY
16398 if (board_config == ALC861_AUTO) {
16399 /* automatic parse from the BIOS config */
16400 err = alc861_parse_auto_config(codec);
16401 if (err < 0) {
16402 alc_free(codec);
16403 return err;
f12ab1e0 16404 } else if (!err) {
9c7f852e
TI
16405 printk(KERN_INFO
16406 "hda_codec: Cannot set up configuration "
16407 "from BIOS. Using base mode...\n");
df694daa
KY
16408 board_config = ALC861_3ST_DIG;
16409 }
16410 }
16411
680cd536
KK
16412 err = snd_hda_attach_beep_device(codec, 0x23);
16413 if (err < 0) {
16414 alc_free(codec);
16415 return err;
16416 }
16417
df694daa 16418 if (board_config != ALC861_AUTO)
e9c364c0 16419 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16420
df694daa
KY
16421 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16422 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16423
df694daa
KY
16424 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16425 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16426
c7a8eb10
TI
16427 if (!spec->cap_mixer)
16428 set_capture_mixer(codec);
45bdd1c1
TI
16429 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16430
2134ea4f
TI
16431 spec->vmaster_nid = 0x03;
16432
b5bfbc67 16433 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16434
df694daa 16435 codec->patch_ops = alc_patch_ops;
c97259df 16436 if (board_config == ALC861_AUTO) {
ae6b813a 16437 spec->init_hook = alc861_auto_init;
c97259df
DC
16438#ifdef CONFIG_SND_HDA_POWER_SAVE
16439 spec->power_hook = alc_power_eapd;
16440#endif
16441 }
cb53c626
TI
16442#ifdef CONFIG_SND_HDA_POWER_SAVE
16443 if (!spec->loopback.amplist)
16444 spec->loopback.amplist = alc861_loopbacks;
16445#endif
ea1fb29a 16446
1da177e4
LT
16447 return 0;
16448}
16449
f32610ed
JS
16450/*
16451 * ALC861-VD support
16452 *
16453 * Based on ALC882
16454 *
16455 * In addition, an independent DAC
16456 */
16457#define ALC861VD_DIGOUT_NID 0x06
16458
16459static hda_nid_t alc861vd_dac_nids[4] = {
16460 /* front, surr, clfe, side surr */
16461 0x02, 0x03, 0x04, 0x05
16462};
16463
16464/* dac_nids for ALC660vd are in a different order - according to
16465 * Realtek's driver.
def319f9 16466 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16467 * of ALC660vd codecs, but for now there is only 3stack mixer
16468 * - and it is the same as in 861vd.
16469 * adc_nids in ALC660vd are (is) the same as in 861vd
16470 */
16471static hda_nid_t alc660vd_dac_nids[3] = {
16472 /* front, rear, clfe, rear_surr */
16473 0x02, 0x04, 0x03
16474};
16475
16476static hda_nid_t alc861vd_adc_nids[1] = {
16477 /* ADC0 */
16478 0x09,
16479};
16480
e1406348
TI
16481static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16482
f32610ed
JS
16483/* input MUX */
16484/* FIXME: should be a matrix-type input source selection */
16485static struct hda_input_mux alc861vd_capture_source = {
16486 .num_items = 4,
16487 .items = {
16488 { "Mic", 0x0 },
16489 { "Front Mic", 0x1 },
16490 { "Line", 0x2 },
16491 { "CD", 0x4 },
16492 },
16493};
16494
272a527c 16495static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16496 .num_items = 2,
272a527c 16497 .items = {
8607f7c4 16498 { "Mic", 0x0 },
28c4edb7 16499 { "Internal Mic", 0x1 },
272a527c
KY
16500 },
16501};
16502
d1a991a6
KY
16503static struct hda_input_mux alc861vd_hp_capture_source = {
16504 .num_items = 2,
16505 .items = {
16506 { "Front Mic", 0x0 },
16507 { "ATAPI Mic", 0x1 },
16508 },
16509};
16510
f32610ed
JS
16511/*
16512 * 2ch mode
16513 */
16514static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16515 { 2, NULL }
16516};
16517
16518/*
16519 * 6ch mode
16520 */
16521static struct hda_verb alc861vd_6stack_ch6_init[] = {
16522 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16523 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16524 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16525 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16526 { } /* end */
16527};
16528
16529/*
16530 * 8ch mode
16531 */
16532static struct hda_verb alc861vd_6stack_ch8_init[] = {
16533 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16534 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16535 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16536 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16537 { } /* end */
16538};
16539
16540static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16541 { 6, alc861vd_6stack_ch6_init },
16542 { 8, alc861vd_6stack_ch8_init },
16543};
16544
16545static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16546 {
16547 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16548 .name = "Channel Mode",
16549 .info = alc_ch_mode_info,
16550 .get = alc_ch_mode_get,
16551 .put = alc_ch_mode_put,
16552 },
16553 { } /* end */
16554};
16555
f32610ed
JS
16556/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16557 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16558 */
16559static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16560 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16561 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16562
16563 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16564 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16565
16566 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16567 HDA_OUTPUT),
16568 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16569 HDA_OUTPUT),
16570 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16571 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16572
16573 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16574 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16575
16576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16577
5f99f86a 16578 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16579 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16580 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16581
5f99f86a 16582 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16583 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16584 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16585
16586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16588
16589 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16590 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16591
f32610ed
JS
16592 { } /* end */
16593};
16594
16595static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16596 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16597 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16598
16599 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16600
5f99f86a 16601 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16602 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16603 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16604
5f99f86a 16605 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16606 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16607 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16608
16609 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16610 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16611
16612 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16613 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16614
f32610ed
JS
16615 { } /* end */
16616};
16617
bdd148a3
KY
16618static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16619 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16620 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16621 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16622
16623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16624
5f99f86a 16625 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16627 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16628
5f99f86a 16629 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16630 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16631 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16632
16633 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16634 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16635
16636 { } /* end */
16637};
16638
b419f346 16639/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16640 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16641 */
16642static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16643 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16644 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16645 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16646 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16647 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16648 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16650 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16651 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16652 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16653 { } /* end */
16654};
16655
d1a991a6
KY
16656/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16657 * Front Mic=0x18, ATAPI Mic = 0x19,
16658 */
16659static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16660 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16661 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16662 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16663 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16664 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16665 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16666 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16667 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16668
d1a991a6
KY
16669 { } /* end */
16670};
16671
f32610ed
JS
16672/*
16673 * generic initialization of ADC, input mixers and output mixers
16674 */
16675static struct hda_verb alc861vd_volume_init_verbs[] = {
16676 /*
16677 * Unmute ADC0 and set the default input to mic-in
16678 */
16679 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16680 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16681
16682 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16683 * the analog-loopback mixer widget
16684 */
16685 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16691
16692 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16693 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16694 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16695 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16696 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16697
16698 /*
16699 * Set up output mixers (0x02 - 0x05)
16700 */
16701 /* set vol=0 to output mixers */
16702 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16703 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16704 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16705 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16706
16707 /* set up input amps for analog loopback */
16708 /* Amp Indices: DAC = 0, mixer = 1 */
16709 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16710 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16711 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16712 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16715 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16716 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16717
16718 { }
16719};
16720
16721/*
16722 * 3-stack pin configuration:
16723 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16724 */
16725static struct hda_verb alc861vd_3stack_init_verbs[] = {
16726 /*
16727 * Set pin mode and muting
16728 */
16729 /* set front pin widgets 0x14 for output */
16730 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16731 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16732 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16733
16734 /* Mic (rear) pin: input vref at 80% */
16735 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16736 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16737 /* Front Mic pin: input vref at 80% */
16738 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16739 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16740 /* Line In pin: input */
16741 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16743 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16744 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16745 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16746 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16747 /* CD pin widget for input */
16748 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16749
16750 { }
16751};
16752
16753/*
16754 * 6-stack pin configuration:
16755 */
16756static struct hda_verb alc861vd_6stack_init_verbs[] = {
16757 /*
16758 * Set pin mode and muting
16759 */
16760 /* set front pin widgets 0x14 for output */
16761 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16762 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16763 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16764
16765 /* Rear Pin: output 1 (0x0d) */
16766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16767 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16768 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16769 /* CLFE Pin: output 2 (0x0e) */
16770 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16771 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16772 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16773 /* Side Pin: output 3 (0x0f) */
16774 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16775 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16776 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16777
16778 /* Mic (rear) pin: input vref at 80% */
16779 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16780 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16781 /* Front Mic pin: input vref at 80% */
16782 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16783 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16784 /* Line In pin: input */
16785 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16786 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16787 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16789 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16790 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16791 /* CD pin widget for input */
16792 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16793
16794 { }
16795};
16796
bdd148a3
KY
16797static struct hda_verb alc861vd_eapd_verbs[] = {
16798 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16799 { }
16800};
16801
f9423e7a
KY
16802static struct hda_verb alc660vd_eapd_verbs[] = {
16803 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16804 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16805 { }
16806};
16807
bdd148a3
KY
16808static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16811 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16812 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16813 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16814 {}
16815};
16816
4f5d1706 16817static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16818{
a9fd4f3f 16819 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16820 spec->autocfg.hp_pins[0] = 0x1b;
16821 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16822}
16823
16824static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16825{
a9fd4f3f 16826 alc_automute_amp(codec);
eeb43387 16827 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16828}
16829
16830static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16831 unsigned int res)
16832{
16833 switch (res >> 26) {
bdd148a3 16834 case ALC880_MIC_EVENT:
eeb43387 16835 alc88x_simple_mic_automute(codec);
bdd148a3 16836 break;
a9fd4f3f
TI
16837 default:
16838 alc_automute_amp_unsol_event(codec, res);
16839 break;
bdd148a3
KY
16840 }
16841}
16842
272a527c
KY
16843static struct hda_verb alc861vd_dallas_verbs[] = {
16844 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16845 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16846 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16847 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16848
16849 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16850 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16851 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16852 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16853 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16854 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16855 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16856 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16857
272a527c
KY
16858 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16859 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16860 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16861 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16862 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16863 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16864 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16865 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16866
16867 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16868 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16869 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16870 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16871 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16872 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16873 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16874 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16875
16876 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16877 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16878 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16879 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16880
16881 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16882 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16883 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16884
16885 { } /* end */
16886};
16887
16888/* toggle speaker-output according to the hp-jack state */
4f5d1706 16889static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16890{
a9fd4f3f 16891 struct alc_spec *spec = codec->spec;
272a527c 16892
a9fd4f3f
TI
16893 spec->autocfg.hp_pins[0] = 0x15;
16894 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16895}
16896
cb53c626
TI
16897#ifdef CONFIG_SND_HDA_POWER_SAVE
16898#define alc861vd_loopbacks alc880_loopbacks
16899#endif
16900
def319f9 16901/* pcm configuration: identical with ALC880 */
f32610ed
JS
16902#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16903#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16904#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16905#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16906
16907/*
16908 * configuration and preset
16909 */
ea734963 16910static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16911 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16912 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16913 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16914 [ALC861VD_3ST] = "3stack",
16915 [ALC861VD_3ST_DIG] = "3stack-digout",
16916 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16917 [ALC861VD_LENOVO] = "lenovo",
272a527c 16918 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16919 [ALC861VD_HP] = "hp",
f32610ed
JS
16920 [ALC861VD_AUTO] = "auto",
16921};
16922
16923static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16924 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16925 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16926 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16927 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16928 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16929 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16930 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16931 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16932 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16933 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16934 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16935 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16936 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16937 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16938 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16939 {}
16940};
16941
16942static struct alc_config_preset alc861vd_presets[] = {
16943 [ALC660VD_3ST] = {
16944 .mixers = { alc861vd_3st_mixer },
16945 .init_verbs = { alc861vd_volume_init_verbs,
16946 alc861vd_3stack_init_verbs },
16947 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16948 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16949 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16950 .channel_mode = alc861vd_3stack_2ch_modes,
16951 .input_mux = &alc861vd_capture_source,
16952 },
6963f84c
MC
16953 [ALC660VD_3ST_DIG] = {
16954 .mixers = { alc861vd_3st_mixer },
16955 .init_verbs = { alc861vd_volume_init_verbs,
16956 alc861vd_3stack_init_verbs },
16957 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16958 .dac_nids = alc660vd_dac_nids,
16959 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16960 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16961 .channel_mode = alc861vd_3stack_2ch_modes,
16962 .input_mux = &alc861vd_capture_source,
16963 },
f32610ed
JS
16964 [ALC861VD_3ST] = {
16965 .mixers = { alc861vd_3st_mixer },
16966 .init_verbs = { alc861vd_volume_init_verbs,
16967 alc861vd_3stack_init_verbs },
16968 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16969 .dac_nids = alc861vd_dac_nids,
16970 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16971 .channel_mode = alc861vd_3stack_2ch_modes,
16972 .input_mux = &alc861vd_capture_source,
16973 },
16974 [ALC861VD_3ST_DIG] = {
16975 .mixers = { alc861vd_3st_mixer },
16976 .init_verbs = { alc861vd_volume_init_verbs,
16977 alc861vd_3stack_init_verbs },
16978 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16979 .dac_nids = alc861vd_dac_nids,
16980 .dig_out_nid = ALC861VD_DIGOUT_NID,
16981 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16982 .channel_mode = alc861vd_3stack_2ch_modes,
16983 .input_mux = &alc861vd_capture_source,
16984 },
16985 [ALC861VD_6ST_DIG] = {
16986 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16987 .init_verbs = { alc861vd_volume_init_verbs,
16988 alc861vd_6stack_init_verbs },
16989 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16990 .dac_nids = alc861vd_dac_nids,
16991 .dig_out_nid = ALC861VD_DIGOUT_NID,
16992 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16993 .channel_mode = alc861vd_6stack_modes,
16994 .input_mux = &alc861vd_capture_source,
16995 },
bdd148a3
KY
16996 [ALC861VD_LENOVO] = {
16997 .mixers = { alc861vd_lenovo_mixer },
16998 .init_verbs = { alc861vd_volume_init_verbs,
16999 alc861vd_3stack_init_verbs,
17000 alc861vd_eapd_verbs,
17001 alc861vd_lenovo_unsol_verbs },
17002 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17003 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
17004 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17005 .channel_mode = alc861vd_3stack_2ch_modes,
17006 .input_mux = &alc861vd_capture_source,
17007 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17008 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17009 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 17010 },
272a527c
KY
17011 [ALC861VD_DALLAS] = {
17012 .mixers = { alc861vd_dallas_mixer },
17013 .init_verbs = { alc861vd_dallas_verbs },
17014 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17015 .dac_nids = alc861vd_dac_nids,
272a527c
KY
17016 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17017 .channel_mode = alc861vd_3stack_2ch_modes,
17018 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 17019 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
17020 .setup = alc861vd_dallas_setup,
17021 .init_hook = alc_automute_amp,
d1a991a6
KY
17022 },
17023 [ALC861VD_HP] = {
17024 .mixers = { alc861vd_hp_mixer },
17025 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17026 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17027 .dac_nids = alc861vd_dac_nids,
d1a991a6 17028 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17029 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17030 .channel_mode = alc861vd_3stack_2ch_modes,
17031 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 17032 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
17033 .setup = alc861vd_dallas_setup,
17034 .init_hook = alc_automute_amp,
ea1fb29a 17035 },
13c94744
TI
17036 [ALC660VD_ASUS_V1S] = {
17037 .mixers = { alc861vd_lenovo_mixer },
17038 .init_verbs = { alc861vd_volume_init_verbs,
17039 alc861vd_3stack_init_verbs,
17040 alc861vd_eapd_verbs,
17041 alc861vd_lenovo_unsol_verbs },
17042 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17043 .dac_nids = alc660vd_dac_nids,
17044 .dig_out_nid = ALC861VD_DIGOUT_NID,
17045 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17046 .channel_mode = alc861vd_3stack_2ch_modes,
17047 .input_mux = &alc861vd_capture_source,
17048 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17049 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17050 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17051 },
f32610ed
JS
17052};
17053
17054/*
17055 * BIOS auto configuration
17056 */
05f5f477
TI
17057static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17058 const struct auto_pin_cfg *cfg)
17059{
7167594a 17060 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17061}
17062
17063
f32610ed
JS
17064static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17065 hda_nid_t nid, int pin_type, int dac_idx)
17066{
f6c7e546 17067 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17068}
17069
17070static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17071{
17072 struct alc_spec *spec = codec->spec;
17073 int i;
17074
17075 for (i = 0; i <= HDA_SIDE; i++) {
17076 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17077 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17078 if (nid)
17079 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17080 pin_type, i);
f32610ed
JS
17081 }
17082}
17083
17084
17085static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17086{
17087 struct alc_spec *spec = codec->spec;
17088 hda_nid_t pin;
17089
17090 pin = spec->autocfg.hp_pins[0];
def319f9 17091 if (pin) /* connect to front and use dac 0 */
f32610ed 17092 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17093 pin = spec->autocfg.speaker_pins[0];
17094 if (pin)
17095 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17096}
17097
f32610ed
JS
17098#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17099
17100static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17101{
17102 struct alc_spec *spec = codec->spec;
66ceeb6b 17103 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17104 int i;
17105
66ceeb6b
TI
17106 for (i = 0; i < cfg->num_inputs; i++) {
17107 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17108 if (alc_is_input_pin(codec, nid)) {
30ea098f 17109 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17110 if (nid != ALC861VD_PIN_CD_NID &&
17111 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17112 snd_hda_codec_write(codec, nid, 0,
17113 AC_VERB_SET_AMP_GAIN_MUTE,
17114 AMP_OUT_MUTE);
17115 }
17116 }
17117}
17118
f511b01c
TI
17119#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17120
f32610ed
JS
17121#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17122#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17123
17124/* add playback controls from the parsed DAC table */
569ed348 17125/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17126 * different NIDs for mute/unmute switch and volume control */
17127static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17128 const struct auto_pin_cfg *cfg)
17129{
ea734963
TI
17130 static const char * const chname[4] = {
17131 "Front", "Surround", "CLFE", "Side"
17132 };
bcb2f0f5 17133 const char *pfx = alc_get_line_out_pfx(cfg, true);
f32610ed
JS
17134 hda_nid_t nid_v, nid_s;
17135 int i, err;
17136
17137 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 17138 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17139 continue;
17140 nid_v = alc861vd_idx_to_mixer_vol(
17141 alc880_dac_to_idx(
17142 spec->multiout.dac_nids[i]));
17143 nid_s = alc861vd_idx_to_mixer_switch(
17144 alc880_dac_to_idx(
17145 spec->multiout.dac_nids[i]));
17146
bcb2f0f5 17147 if (!pfx && i == 2) {
f32610ed 17148 /* Center/LFE */
0afe5f89
TI
17149 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17150 "Center",
f12ab1e0
TI
17151 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17152 HDA_OUTPUT));
17153 if (err < 0)
f32610ed 17154 return err;
0afe5f89
TI
17155 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17156 "LFE",
f12ab1e0
TI
17157 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17158 HDA_OUTPUT));
17159 if (err < 0)
f32610ed 17160 return err;
0afe5f89
TI
17161 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17162 "Center",
f12ab1e0
TI
17163 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17164 HDA_INPUT));
17165 if (err < 0)
f32610ed 17166 return err;
0afe5f89
TI
17167 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17168 "LFE",
f12ab1e0
TI
17169 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17170 HDA_INPUT));
17171 if (err < 0)
f32610ed
JS
17172 return err;
17173 } else {
bcb2f0f5 17174 const char *name = pfx;
5a882646
DH
17175 int index = i;
17176 if (!name) {
bcb2f0f5 17177 name = chname[i];
5a882646
DH
17178 index = 0;
17179 }
bcb2f0f5 17180 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 17181 name, index,
f12ab1e0
TI
17182 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17183 HDA_OUTPUT));
17184 if (err < 0)
f32610ed 17185 return err;
bcb2f0f5 17186 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 17187 name, index,
bdd148a3 17188 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17189 HDA_INPUT));
17190 if (err < 0)
f32610ed
JS
17191 return err;
17192 }
17193 }
17194 return 0;
17195}
17196
17197/* add playback controls for speaker and HP outputs */
17198/* Based on ALC880 version. But ALC861VD has separate,
17199 * different NIDs for mute/unmute switch and volume control */
17200static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17201 hda_nid_t pin, const char *pfx)
17202{
17203 hda_nid_t nid_v, nid_s;
17204 int err;
f32610ed 17205
f12ab1e0 17206 if (!pin)
f32610ed
JS
17207 return 0;
17208
17209 if (alc880_is_fixed_pin(pin)) {
17210 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17211 /* specify the DAC as the extra output */
f12ab1e0 17212 if (!spec->multiout.hp_nid)
f32610ed
JS
17213 spec->multiout.hp_nid = nid_v;
17214 else
17215 spec->multiout.extra_out_nid[0] = nid_v;
17216 /* control HP volume/switch on the output mixer amp */
17217 nid_v = alc861vd_idx_to_mixer_vol(
17218 alc880_fixed_pin_idx(pin));
17219 nid_s = alc861vd_idx_to_mixer_switch(
17220 alc880_fixed_pin_idx(pin));
17221
0afe5f89 17222 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17223 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17224 if (err < 0)
f32610ed 17225 return err;
0afe5f89 17226 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17227 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17228 if (err < 0)
f32610ed
JS
17229 return err;
17230 } else if (alc880_is_multi_pin(pin)) {
17231 /* set manual connection */
17232 /* we have only a switch on HP-out PIN */
0afe5f89 17233 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17234 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17235 if (err < 0)
f32610ed
JS
17236 return err;
17237 }
17238 return 0;
17239}
17240
17241/* parse the BIOS configuration and set up the alc_spec
17242 * return 1 if successful, 0 if the proper config is not found,
17243 * or a negative error code
17244 * Based on ALC880 version - had to change it to override
17245 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17246static int alc861vd_parse_auto_config(struct hda_codec *codec)
17247{
17248 struct alc_spec *spec = codec->spec;
17249 int err;
17250 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17251
f12ab1e0
TI
17252 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17253 alc861vd_ignore);
17254 if (err < 0)
f32610ed 17255 return err;
f12ab1e0 17256 if (!spec->autocfg.line_outs)
f32610ed
JS
17257 return 0; /* can't find valid BIOS pin config */
17258
f12ab1e0
TI
17259 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17260 if (err < 0)
17261 return err;
17262 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17263 if (err < 0)
17264 return err;
17265 err = alc861vd_auto_create_extra_out(spec,
17266 spec->autocfg.speaker_pins[0],
17267 "Speaker");
17268 if (err < 0)
17269 return err;
17270 err = alc861vd_auto_create_extra_out(spec,
17271 spec->autocfg.hp_pins[0],
17272 "Headphone");
17273 if (err < 0)
17274 return err;
05f5f477 17275 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17276 if (err < 0)
f32610ed
JS
17277 return err;
17278
17279 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17280
757899ac 17281 alc_auto_parse_digital(codec);
f32610ed 17282
603c4019 17283 if (spec->kctls.list)
d88897ea 17284 add_mixer(spec, spec->kctls.list);
f32610ed 17285
d88897ea 17286 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17287
17288 spec->num_mux_defs = 1;
61b9b9b1 17289 spec->input_mux = &spec->private_imux[0];
f32610ed 17290
776e184e
TI
17291 err = alc_auto_add_mic_boost(codec);
17292 if (err < 0)
17293 return err;
17294
6227cdce 17295 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17296
f32610ed
JS
17297 return 1;
17298}
17299
17300/* additional initialization for auto-configuration model */
17301static void alc861vd_auto_init(struct hda_codec *codec)
17302{
f6c7e546 17303 struct alc_spec *spec = codec->spec;
f32610ed
JS
17304 alc861vd_auto_init_multi_out(codec);
17305 alc861vd_auto_init_hp_out(codec);
17306 alc861vd_auto_init_analog_input(codec);
f511b01c 17307 alc861vd_auto_init_input_src(codec);
757899ac 17308 alc_auto_init_digital(codec);
f6c7e546 17309 if (spec->unsol_event)
7fb0d78f 17310 alc_inithook(codec);
f32610ed
JS
17311}
17312
f8f25ba3
TI
17313enum {
17314 ALC660VD_FIX_ASUS_GPIO1
17315};
17316
17317/* reset GPIO1 */
f8f25ba3
TI
17318static const struct alc_fixup alc861vd_fixups[] = {
17319 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17320 .type = ALC_FIXUP_VERBS,
17321 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17322 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17323 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17324 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17325 { }
17326 }
f8f25ba3
TI
17327 },
17328};
17329
17330static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17331 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17332 {}
17333};
17334
f32610ed
JS
17335static int patch_alc861vd(struct hda_codec *codec)
17336{
17337 struct alc_spec *spec;
17338 int err, board_config;
17339
17340 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17341 if (spec == NULL)
17342 return -ENOMEM;
17343
17344 codec->spec = spec;
17345
17346 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17347 alc861vd_models,
17348 alc861vd_cfg_tbl);
17349
17350 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17351 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17352 codec->chip_name);
f32610ed
JS
17353 board_config = ALC861VD_AUTO;
17354 }
17355
b5bfbc67
TI
17356 if (board_config == ALC861VD_AUTO) {
17357 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17358 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17359 }
f8f25ba3 17360
f32610ed
JS
17361 if (board_config == ALC861VD_AUTO) {
17362 /* automatic parse from the BIOS config */
17363 err = alc861vd_parse_auto_config(codec);
17364 if (err < 0) {
17365 alc_free(codec);
17366 return err;
f12ab1e0 17367 } else if (!err) {
f32610ed
JS
17368 printk(KERN_INFO
17369 "hda_codec: Cannot set up configuration "
17370 "from BIOS. Using base mode...\n");
17371 board_config = ALC861VD_3ST;
17372 }
17373 }
17374
680cd536
KK
17375 err = snd_hda_attach_beep_device(codec, 0x23);
17376 if (err < 0) {
17377 alc_free(codec);
17378 return err;
17379 }
17380
f32610ed 17381 if (board_config != ALC861VD_AUTO)
e9c364c0 17382 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17383
2f893286 17384 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17385 /* always turn on EAPD */
d88897ea 17386 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17387 }
17388
f32610ed
JS
17389 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17390 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17391
f32610ed
JS
17392 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17393 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17394
dd704698
TI
17395 if (!spec->adc_nids) {
17396 spec->adc_nids = alc861vd_adc_nids;
17397 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17398 }
17399 if (!spec->capsrc_nids)
17400 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17401
b59bdf3b 17402 set_capture_mixer(codec);
45bdd1c1 17403 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17404
2134ea4f
TI
17405 spec->vmaster_nid = 0x02;
17406
b5bfbc67 17407 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17408
f32610ed
JS
17409 codec->patch_ops = alc_patch_ops;
17410
17411 if (board_config == ALC861VD_AUTO)
17412 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17413#ifdef CONFIG_SND_HDA_POWER_SAVE
17414 if (!spec->loopback.amplist)
17415 spec->loopback.amplist = alc861vd_loopbacks;
17416#endif
f32610ed
JS
17417
17418 return 0;
17419}
17420
bc9f98a9
KY
17421/*
17422 * ALC662 support
17423 *
17424 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17425 * configuration. Each pin widget can choose any input DACs and a mixer.
17426 * Each ADC is connected from a mixer of all inputs. This makes possible
17427 * 6-channel independent captures.
17428 *
17429 * In addition, an independent DAC for the multi-playback (not used in this
17430 * driver yet).
17431 */
17432#define ALC662_DIGOUT_NID 0x06
17433#define ALC662_DIGIN_NID 0x0a
17434
4bf4a6c5
RY
17435static hda_nid_t alc662_dac_nids[3] = {
17436 /* front, rear, clfe */
bc9f98a9
KY
17437 0x02, 0x03, 0x04
17438};
17439
622e84cd
KY
17440static hda_nid_t alc272_dac_nids[2] = {
17441 0x02, 0x03
17442};
17443
b59bdf3b 17444static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17445 /* ADC1-2 */
b59bdf3b 17446 0x09, 0x08
bc9f98a9 17447};
e1406348 17448
622e84cd
KY
17449static hda_nid_t alc272_adc_nids[1] = {
17450 /* ADC1-2 */
17451 0x08,
17452};
17453
b59bdf3b 17454static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17455static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17456
e1406348 17457
bc9f98a9
KY
17458/* input MUX */
17459/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17460static struct hda_input_mux alc662_capture_source = {
17461 .num_items = 4,
17462 .items = {
17463 { "Mic", 0x0 },
17464 { "Front Mic", 0x1 },
17465 { "Line", 0x2 },
17466 { "CD", 0x4 },
17467 },
17468};
17469
17470static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17471 .num_items = 2,
17472 .items = {
17473 { "Mic", 0x1 },
17474 { "Line", 0x2 },
17475 },
17476};
291702f0 17477
6dda9f4a
KY
17478static struct hda_input_mux alc663_capture_source = {
17479 .num_items = 3,
17480 .items = {
17481 { "Mic", 0x0 },
17482 { "Front Mic", 0x1 },
17483 { "Line", 0x2 },
17484 },
17485};
17486
4f5d1706 17487#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17488static struct hda_input_mux alc272_nc10_capture_source = {
17489 .num_items = 16,
17490 .items = {
17491 { "Autoselect Mic", 0x0 },
17492 { "Internal Mic", 0x1 },
17493 { "In-0x02", 0x2 },
17494 { "In-0x03", 0x3 },
17495 { "In-0x04", 0x4 },
17496 { "In-0x05", 0x5 },
17497 { "In-0x06", 0x6 },
17498 { "In-0x07", 0x7 },
17499 { "In-0x08", 0x8 },
17500 { "In-0x09", 0x9 },
17501 { "In-0x0a", 0x0a },
17502 { "In-0x0b", 0x0b },
17503 { "In-0x0c", 0x0c },
17504 { "In-0x0d", 0x0d },
17505 { "In-0x0e", 0x0e },
17506 { "In-0x0f", 0x0f },
17507 },
17508};
17509#endif
17510
bc9f98a9
KY
17511/*
17512 * 2ch mode
17513 */
17514static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17515 { 2, NULL }
17516};
17517
17518/*
17519 * 2ch mode
17520 */
17521static struct hda_verb alc662_3ST_ch2_init[] = {
17522 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17523 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17524 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17525 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17526 { } /* end */
17527};
17528
17529/*
17530 * 6ch mode
17531 */
17532static struct hda_verb alc662_3ST_ch6_init[] = {
17533 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17534 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17535 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17536 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17537 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17538 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17539 { } /* end */
17540};
17541
17542static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17543 { 2, alc662_3ST_ch2_init },
17544 { 6, alc662_3ST_ch6_init },
17545};
17546
17547/*
17548 * 2ch mode
17549 */
17550static struct hda_verb alc662_sixstack_ch6_init[] = {
17551 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17552 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17553 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17554 { } /* end */
17555};
17556
17557/*
17558 * 6ch mode
17559 */
17560static struct hda_verb alc662_sixstack_ch8_init[] = {
17561 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17562 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17563 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17564 { } /* end */
17565};
17566
17567static struct hda_channel_mode alc662_5stack_modes[2] = {
17568 { 2, alc662_sixstack_ch6_init },
17569 { 6, alc662_sixstack_ch8_init },
17570};
17571
17572/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17573 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17574 */
17575
17576static struct snd_kcontrol_new alc662_base_mixer[] = {
17577 /* output mixer control */
17578 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17579 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17580 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17581 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17582 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17583 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17584 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17585 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17587
17588 /*Input mixer control */
17589 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17590 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17591 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17592 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17593 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17594 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17595 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17596 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17597 { } /* end */
17598};
17599
17600static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17601 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17602 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17604 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17605 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17606 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17607 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17609 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17610 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17611 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17612 { } /* end */
17613};
17614
17615static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17616 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17617 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17618 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17619 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17620 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17621 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17622 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17623 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17624 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17625 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17626 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17627 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17628 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17631 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17632 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17633 { } /* end */
17634};
17635
17636static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17637 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17638 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17639 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17640 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17642 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17643 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17644 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17645 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17646 { } /* end */
17647};
17648
291702f0 17649static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17650 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17651 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17652
5f99f86a 17653 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17654 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17655 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17656
5f99f86a 17657 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17658 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17659 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17660 { } /* end */
17661};
17662
8c427226 17663static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17664 ALC262_HIPPO_MASTER_SWITCH,
17665 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17666 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17667 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17668 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17669 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17670 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17671 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17672 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17673 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17674 { } /* end */
17675};
17676
f1d4e28b
KY
17677static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17678 .ops = &snd_hda_bind_vol,
17679 .values = {
17680 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17681 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17682 0
17683 },
17684};
17685
17686static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17687 .ops = &snd_hda_bind_sw,
17688 .values = {
17689 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17690 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17691 0
17692 },
17693};
17694
6dda9f4a 17695static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17696 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17697 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17698 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17699 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17700 { } /* end */
17701};
17702
17703static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17704 .ops = &snd_hda_bind_sw,
17705 .values = {
17706 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17707 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17708 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17709 0
17710 },
17711};
17712
17713static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17714 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17715 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17716 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17717 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17718 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17719 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17720
17721 { } /* end */
17722};
17723
17724static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17725 .ops = &snd_hda_bind_sw,
17726 .values = {
17727 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17728 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17729 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17730 0
17731 },
17732};
17733
17734static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17735 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17736 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17737 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17738 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17739 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17740 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17741 { } /* end */
17742};
17743
17744static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17745 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17746 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17747 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17748 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17749 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17750 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17751 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17752 { } /* end */
17753};
17754
17755static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17756 .ops = &snd_hda_bind_vol,
17757 .values = {
17758 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17759 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17760 0
17761 },
17762};
17763
17764static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17765 .ops = &snd_hda_bind_sw,
17766 .values = {
17767 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17768 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17769 0
17770 },
17771};
17772
17773static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17774 HDA_BIND_VOL("Master Playback Volume",
17775 &alc663_asus_two_bind_master_vol),
17776 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17777 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17781 { } /* end */
17782};
17783
17784static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17785 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17786 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17787 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17788 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17790 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17791 { } /* end */
17792};
17793
17794static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17795 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17796 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17797 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17798 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17799 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17800
17801 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17802 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17803 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17804 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17805 { } /* end */
17806};
17807
17808static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17809 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17810 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17812
17813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17815 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17816 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17817 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17818 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17819 { } /* end */
17820};
17821
ebb83eeb
KY
17822static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17823 .ops = &snd_hda_bind_sw,
17824 .values = {
17825 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17826 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17827 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17828 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17829 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17830 0
17831 },
17832};
17833
17834static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17835 .ops = &snd_hda_bind_sw,
17836 .values = {
17837 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17838 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17839 0
17840 },
17841};
17842
17843static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17844 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17845 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17846 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17847 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17848 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17849 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17850 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17852 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17853 { } /* end */
17854};
17855
17856static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17857 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17858 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17859 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17860 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17861 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17862 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17863 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17864 { } /* end */
17865};
17866
17867
bc9f98a9
KY
17868static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17869 {
17870 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17871 .name = "Channel Mode",
17872 .info = alc_ch_mode_info,
17873 .get = alc_ch_mode_get,
17874 .put = alc_ch_mode_put,
17875 },
17876 { } /* end */
17877};
17878
17879static struct hda_verb alc662_init_verbs[] = {
17880 /* ADC: mute amp left and right */
17881 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17882 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17883
b60dd394
KY
17884 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17885 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17886 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17887 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17888 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17889 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17890
17891 /* Front Pin: output 0 (0x0c) */
17892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17893 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17894
17895 /* Rear Pin: output 1 (0x0d) */
17896 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17897 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17898
17899 /* CLFE Pin: output 2 (0x0e) */
17900 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17901 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17902
17903 /* Mic (rear) pin: input vref at 80% */
17904 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17905 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17906 /* Front Mic pin: input vref at 80% */
17907 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17908 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17909 /* Line In pin: input */
17910 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17911 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17912 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17914 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17915 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17916 /* CD pin widget for input */
17917 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17918
17919 /* FIXME: use matrix-type input source selection */
17920 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17921 /* Input mixer */
17922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17924
17925 /* always trun on EAPD */
17926 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17927 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17928
bc9f98a9
KY
17929 { }
17930};
17931
cec27c89
KY
17932static struct hda_verb alc663_init_verbs[] = {
17933 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17934 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17935 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17936 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17937 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17938 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17939 { }
17940};
17941
17942static struct hda_verb alc272_init_verbs[] = {
17943 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17944 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17945 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17946 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17947 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17948 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17949 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17950 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17951 { }
17952};
17953
bc9f98a9
KY
17954static struct hda_verb alc662_sue_init_verbs[] = {
17955 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17956 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17957 {}
17958};
17959
17960static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17961 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17962 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17963 {}
bc9f98a9
KY
17964};
17965
8c427226
KY
17966/* Set Unsolicited Event*/
17967static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17968 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17969 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17970 {}
17971};
17972
6dda9f4a 17973static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17974 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17975 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17976 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17977 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17978 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17980 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17981 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17982 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17983 {}
17984};
17985
17986static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17987 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17988 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17989 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17990 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17991 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17992 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17993 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17994 {}
17995};
17996
17997static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17998 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17999 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18000 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18001 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18002 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18003 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18004 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18005 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18006 {}
18007};
6dda9f4a 18008
f1d4e28b
KY
18009static struct hda_verb alc663_15jd_amic_init_verbs[] = {
18010 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18011 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18012 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18013 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18014 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18015 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18016 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18017 {}
18018};
6dda9f4a 18019
f1d4e28b
KY
18020static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18021 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18022 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18023 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18024 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18025 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18026 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18027 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18028 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18029 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18030 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18031 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18032 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18033 {}
18034};
18035
18036static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18037 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18038 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18039 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18040 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18041 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18042 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18043 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18044 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18046 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18047 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18048 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18049 {}
18050};
18051
18052static struct hda_verb alc663_g71v_init_verbs[] = {
18053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18054 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18055 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18056
18057 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18058 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18059 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18060
18061 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18062 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18063 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18064 {}
18065};
18066
18067static struct hda_verb alc663_g50v_init_verbs[] = {
18068 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18069 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18070 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18071
18072 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18073 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18074 {}
18075};
18076
f1d4e28b
KY
18077static struct hda_verb alc662_ecs_init_verbs[] = {
18078 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18079 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18080 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18081 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18082 {}
18083};
18084
622e84cd
KY
18085static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18086 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18087 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18088 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18089 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18090 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18091 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18092 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18093 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18094 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18095 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18096 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18097 {}
18098};
18099
18100static struct hda_verb alc272_dell_init_verbs[] = {
18101 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18102 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18103 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18104 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18105 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18106 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18107 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18108 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18109 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18110 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18111 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18112 {}
18113};
18114
ebb83eeb
KY
18115static struct hda_verb alc663_mode7_init_verbs[] = {
18116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18117 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18118 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18119 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18120 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18121 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18122 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18123 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18124 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18125 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18128 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18129 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18130 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18131 {}
18132};
18133
18134static struct hda_verb alc663_mode8_init_verbs[] = {
18135 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18136 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18137 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18138 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18139 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18140 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18141 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18142 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18143 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18144 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18145 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18148 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18149 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18150 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18151 {}
18152};
18153
f1d4e28b
KY
18154static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18155 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18156 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18157 { } /* end */
18158};
18159
622e84cd
KY
18160static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18161 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18162 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18163 { } /* end */
18164};
18165
bc9f98a9
KY
18166static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18167{
18168 unsigned int present;
f12ab1e0 18169 unsigned char bits;
bc9f98a9 18170
864f92be 18171 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 18172 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18173
47fd830a
TI
18174 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18175 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18176}
18177
18178static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18179{
18180 unsigned int present;
f12ab1e0 18181 unsigned char bits;
bc9f98a9 18182
864f92be 18183 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 18184 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18185
47fd830a
TI
18186 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18187 HDA_AMP_MUTE, bits);
18188 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18189 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18190}
18191
18192static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18193 unsigned int res)
18194{
18195 if ((res >> 26) == ALC880_HP_EVENT)
18196 alc662_lenovo_101e_all_automute(codec);
18197 if ((res >> 26) == ALC880_FRONT_EVENT)
18198 alc662_lenovo_101e_ispeaker_automute(codec);
18199}
18200
291702f0
KY
18201/* unsolicited event for HP jack sensing */
18202static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18203 unsigned int res)
18204{
291702f0 18205 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18206 alc_mic_automute(codec);
42171c17
TI
18207 else
18208 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18209}
18210
4f5d1706
TI
18211static void alc662_eeepc_setup(struct hda_codec *codec)
18212{
18213 struct alc_spec *spec = codec->spec;
18214
18215 alc262_hippo1_setup(codec);
18216 spec->ext_mic.pin = 0x18;
18217 spec->ext_mic.mux_idx = 0;
18218 spec->int_mic.pin = 0x19;
18219 spec->int_mic.mux_idx = 1;
18220 spec->auto_mic = 1;
18221}
18222
291702f0
KY
18223static void alc662_eeepc_inithook(struct hda_codec *codec)
18224{
4f5d1706
TI
18225 alc262_hippo_automute(codec);
18226 alc_mic_automute(codec);
291702f0
KY
18227}
18228
4f5d1706 18229static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18230{
42171c17
TI
18231 struct alc_spec *spec = codec->spec;
18232
18233 spec->autocfg.hp_pins[0] = 0x14;
18234 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18235}
18236
4f5d1706
TI
18237#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18238
6dda9f4a
KY
18239static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18240{
18241 unsigned int present;
18242 unsigned char bits;
18243
864f92be 18244 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18245 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18246 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18247 HDA_AMP_MUTE, bits);
f1d4e28b 18248 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18249 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18250}
18251
18252static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18253{
18254 unsigned int present;
18255 unsigned char bits;
18256
864f92be 18257 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18258 bits = present ? HDA_AMP_MUTE : 0;
18259 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18260 HDA_AMP_MUTE, bits);
f1d4e28b 18261 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18262 HDA_AMP_MUTE, bits);
f1d4e28b 18263 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18264 HDA_AMP_MUTE, bits);
f1d4e28b 18265 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18266 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18267}
18268
18269static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18270{
18271 unsigned int present;
18272 unsigned char bits;
18273
864f92be 18274 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18275 bits = present ? HDA_AMP_MUTE : 0;
18276 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18277 HDA_AMP_MUTE, bits);
f1d4e28b 18278 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18279 HDA_AMP_MUTE, bits);
f1d4e28b 18280 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18281 HDA_AMP_MUTE, bits);
f1d4e28b 18282 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18283 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18284}
18285
18286static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18287{
18288 unsigned int present;
18289 unsigned char bits;
18290
864f92be 18291 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18292 bits = present ? 0 : PIN_OUT;
18293 snd_hda_codec_write(codec, 0x14, 0,
18294 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18295}
18296
18297static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18298{
18299 unsigned int present1, present2;
18300
864f92be
WF
18301 present1 = snd_hda_jack_detect(codec, 0x21);
18302 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18303
18304 if (present1 || present2) {
18305 snd_hda_codec_write_cache(codec, 0x14, 0,
18306 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18307 } else {
18308 snd_hda_codec_write_cache(codec, 0x14, 0,
18309 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18310 }
18311}
18312
18313static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18314{
18315 unsigned int present1, present2;
18316
864f92be
WF
18317 present1 = snd_hda_jack_detect(codec, 0x1b);
18318 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18319
18320 if (present1 || present2) {
18321 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18322 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18323 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18324 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18325 } else {
18326 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18327 HDA_AMP_MUTE, 0);
f1d4e28b 18328 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18329 HDA_AMP_MUTE, 0);
f1d4e28b 18330 }
6dda9f4a
KY
18331}
18332
ebb83eeb
KY
18333static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18334{
18335 unsigned int present1, present2;
18336
18337 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18338 AC_VERB_GET_PIN_SENSE, 0)
18339 & AC_PINSENSE_PRESENCE;
18340 present2 = snd_hda_codec_read(codec, 0x21, 0,
18341 AC_VERB_GET_PIN_SENSE, 0)
18342 & AC_PINSENSE_PRESENCE;
18343
18344 if (present1 || present2) {
18345 snd_hda_codec_write_cache(codec, 0x14, 0,
18346 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18347 snd_hda_codec_write_cache(codec, 0x17, 0,
18348 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18349 } else {
18350 snd_hda_codec_write_cache(codec, 0x14, 0,
18351 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18352 snd_hda_codec_write_cache(codec, 0x17, 0,
18353 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18354 }
18355}
18356
18357static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18358{
18359 unsigned int present1, present2;
18360
18361 present1 = snd_hda_codec_read(codec, 0x21, 0,
18362 AC_VERB_GET_PIN_SENSE, 0)
18363 & AC_PINSENSE_PRESENCE;
18364 present2 = snd_hda_codec_read(codec, 0x15, 0,
18365 AC_VERB_GET_PIN_SENSE, 0)
18366 & AC_PINSENSE_PRESENCE;
18367
18368 if (present1 || present2) {
18369 snd_hda_codec_write_cache(codec, 0x14, 0,
18370 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18371 snd_hda_codec_write_cache(codec, 0x17, 0,
18372 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18373 } else {
18374 snd_hda_codec_write_cache(codec, 0x14, 0,
18375 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18376 snd_hda_codec_write_cache(codec, 0x17, 0,
18377 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18378 }
18379}
18380
6dda9f4a
KY
18381static void alc663_m51va_unsol_event(struct hda_codec *codec,
18382 unsigned int res)
18383{
18384 switch (res >> 26) {
18385 case ALC880_HP_EVENT:
18386 alc663_m51va_speaker_automute(codec);
18387 break;
18388 case ALC880_MIC_EVENT:
4f5d1706 18389 alc_mic_automute(codec);
6dda9f4a
KY
18390 break;
18391 }
18392}
18393
4f5d1706
TI
18394static void alc663_m51va_setup(struct hda_codec *codec)
18395{
18396 struct alc_spec *spec = codec->spec;
18397 spec->ext_mic.pin = 0x18;
18398 spec->ext_mic.mux_idx = 0;
18399 spec->int_mic.pin = 0x12;
ebb83eeb 18400 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18401 spec->auto_mic = 1;
18402}
18403
6dda9f4a
KY
18404static void alc663_m51va_inithook(struct hda_codec *codec)
18405{
18406 alc663_m51va_speaker_automute(codec);
4f5d1706 18407 alc_mic_automute(codec);
6dda9f4a
KY
18408}
18409
f1d4e28b 18410/* ***************** Mode1 ******************************/
4f5d1706 18411#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18412
18413static void alc663_mode1_setup(struct hda_codec *codec)
18414{
18415 struct alc_spec *spec = codec->spec;
18416 spec->ext_mic.pin = 0x18;
18417 spec->ext_mic.mux_idx = 0;
18418 spec->int_mic.pin = 0x19;
18419 spec->int_mic.mux_idx = 1;
18420 spec->auto_mic = 1;
18421}
18422
4f5d1706 18423#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18424
f1d4e28b
KY
18425/* ***************** Mode2 ******************************/
18426static void alc662_mode2_unsol_event(struct hda_codec *codec,
18427 unsigned int res)
18428{
18429 switch (res >> 26) {
18430 case ALC880_HP_EVENT:
18431 alc662_f5z_speaker_automute(codec);
18432 break;
18433 case ALC880_MIC_EVENT:
4f5d1706 18434 alc_mic_automute(codec);
f1d4e28b
KY
18435 break;
18436 }
18437}
18438
ebb83eeb 18439#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18440
f1d4e28b
KY
18441static void alc662_mode2_inithook(struct hda_codec *codec)
18442{
18443 alc662_f5z_speaker_automute(codec);
4f5d1706 18444 alc_mic_automute(codec);
f1d4e28b
KY
18445}
18446/* ***************** Mode3 ******************************/
18447static void alc663_mode3_unsol_event(struct hda_codec *codec,
18448 unsigned int res)
18449{
18450 switch (res >> 26) {
18451 case ALC880_HP_EVENT:
18452 alc663_two_hp_m1_speaker_automute(codec);
18453 break;
18454 case ALC880_MIC_EVENT:
4f5d1706 18455 alc_mic_automute(codec);
f1d4e28b
KY
18456 break;
18457 }
18458}
18459
ebb83eeb 18460#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18461
f1d4e28b
KY
18462static void alc663_mode3_inithook(struct hda_codec *codec)
18463{
18464 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18465 alc_mic_automute(codec);
f1d4e28b
KY
18466}
18467/* ***************** Mode4 ******************************/
18468static void alc663_mode4_unsol_event(struct hda_codec *codec,
18469 unsigned int res)
18470{
18471 switch (res >> 26) {
18472 case ALC880_HP_EVENT:
18473 alc663_21jd_two_speaker_automute(codec);
18474 break;
18475 case ALC880_MIC_EVENT:
4f5d1706 18476 alc_mic_automute(codec);
f1d4e28b
KY
18477 break;
18478 }
18479}
18480
ebb83eeb 18481#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18482
f1d4e28b
KY
18483static void alc663_mode4_inithook(struct hda_codec *codec)
18484{
18485 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18486 alc_mic_automute(codec);
f1d4e28b
KY
18487}
18488/* ***************** Mode5 ******************************/
18489static void alc663_mode5_unsol_event(struct hda_codec *codec,
18490 unsigned int res)
18491{
18492 switch (res >> 26) {
18493 case ALC880_HP_EVENT:
18494 alc663_15jd_two_speaker_automute(codec);
18495 break;
18496 case ALC880_MIC_EVENT:
4f5d1706 18497 alc_mic_automute(codec);
f1d4e28b
KY
18498 break;
18499 }
18500}
18501
ebb83eeb 18502#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18503
f1d4e28b
KY
18504static void alc663_mode5_inithook(struct hda_codec *codec)
18505{
18506 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18507 alc_mic_automute(codec);
f1d4e28b
KY
18508}
18509/* ***************** Mode6 ******************************/
18510static void alc663_mode6_unsol_event(struct hda_codec *codec,
18511 unsigned int res)
18512{
18513 switch (res >> 26) {
18514 case ALC880_HP_EVENT:
18515 alc663_two_hp_m2_speaker_automute(codec);
18516 break;
18517 case ALC880_MIC_EVENT:
4f5d1706 18518 alc_mic_automute(codec);
f1d4e28b
KY
18519 break;
18520 }
18521}
18522
ebb83eeb 18523#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18524
f1d4e28b
KY
18525static void alc663_mode6_inithook(struct hda_codec *codec)
18526{
18527 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18528 alc_mic_automute(codec);
f1d4e28b
KY
18529}
18530
ebb83eeb
KY
18531/* ***************** Mode7 ******************************/
18532static void alc663_mode7_unsol_event(struct hda_codec *codec,
18533 unsigned int res)
18534{
18535 switch (res >> 26) {
18536 case ALC880_HP_EVENT:
18537 alc663_two_hp_m7_speaker_automute(codec);
18538 break;
18539 case ALC880_MIC_EVENT:
18540 alc_mic_automute(codec);
18541 break;
18542 }
18543}
18544
18545#define alc663_mode7_setup alc663_mode1_setup
18546
18547static void alc663_mode7_inithook(struct hda_codec *codec)
18548{
18549 alc663_two_hp_m7_speaker_automute(codec);
18550 alc_mic_automute(codec);
18551}
18552
18553/* ***************** Mode8 ******************************/
18554static void alc663_mode8_unsol_event(struct hda_codec *codec,
18555 unsigned int res)
18556{
18557 switch (res >> 26) {
18558 case ALC880_HP_EVENT:
18559 alc663_two_hp_m8_speaker_automute(codec);
18560 break;
18561 case ALC880_MIC_EVENT:
18562 alc_mic_automute(codec);
18563 break;
18564 }
18565}
18566
18567#define alc663_mode8_setup alc663_m51va_setup
18568
18569static void alc663_mode8_inithook(struct hda_codec *codec)
18570{
18571 alc663_two_hp_m8_speaker_automute(codec);
18572 alc_mic_automute(codec);
18573}
18574
6dda9f4a
KY
18575static void alc663_g71v_hp_automute(struct hda_codec *codec)
18576{
18577 unsigned int present;
18578 unsigned char bits;
18579
864f92be 18580 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18581 bits = present ? HDA_AMP_MUTE : 0;
18582 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18583 HDA_AMP_MUTE, bits);
18584 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18585 HDA_AMP_MUTE, bits);
18586}
18587
18588static void alc663_g71v_front_automute(struct hda_codec *codec)
18589{
18590 unsigned int present;
18591 unsigned char bits;
18592
864f92be 18593 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18594 bits = present ? HDA_AMP_MUTE : 0;
18595 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18596 HDA_AMP_MUTE, bits);
18597}
18598
18599static void alc663_g71v_unsol_event(struct hda_codec *codec,
18600 unsigned int res)
18601{
18602 switch (res >> 26) {
18603 case ALC880_HP_EVENT:
18604 alc663_g71v_hp_automute(codec);
18605 break;
18606 case ALC880_FRONT_EVENT:
18607 alc663_g71v_front_automute(codec);
18608 break;
18609 case ALC880_MIC_EVENT:
4f5d1706 18610 alc_mic_automute(codec);
6dda9f4a
KY
18611 break;
18612 }
18613}
18614
4f5d1706
TI
18615#define alc663_g71v_setup alc663_m51va_setup
18616
6dda9f4a
KY
18617static void alc663_g71v_inithook(struct hda_codec *codec)
18618{
18619 alc663_g71v_front_automute(codec);
18620 alc663_g71v_hp_automute(codec);
4f5d1706 18621 alc_mic_automute(codec);
6dda9f4a
KY
18622}
18623
18624static void alc663_g50v_unsol_event(struct hda_codec *codec,
18625 unsigned int res)
18626{
18627 switch (res >> 26) {
18628 case ALC880_HP_EVENT:
18629 alc663_m51va_speaker_automute(codec);
18630 break;
18631 case ALC880_MIC_EVENT:
4f5d1706 18632 alc_mic_automute(codec);
6dda9f4a
KY
18633 break;
18634 }
18635}
18636
4f5d1706
TI
18637#define alc663_g50v_setup alc663_m51va_setup
18638
6dda9f4a
KY
18639static void alc663_g50v_inithook(struct hda_codec *codec)
18640{
18641 alc663_m51va_speaker_automute(codec);
4f5d1706 18642 alc_mic_automute(codec);
6dda9f4a
KY
18643}
18644
f1d4e28b
KY
18645static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18646 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18647 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18648
5f99f86a 18649 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18650 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18651 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18652
5f99f86a 18653 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18654 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18655 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18656 { } /* end */
18657};
18658
9541ba1d
CP
18659static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18660 /* Master Playback automatically created from Speaker and Headphone */
18661 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18662 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18663 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18664 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18665
8607f7c4
DH
18666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18668 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18669
28c4edb7
DH
18670 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18671 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18672 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18673 { } /* end */
18674};
18675
cb53c626
TI
18676#ifdef CONFIG_SND_HDA_POWER_SAVE
18677#define alc662_loopbacks alc880_loopbacks
18678#endif
18679
bc9f98a9 18680
def319f9 18681/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18682#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18683#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18684#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18685#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18686
18687/*
18688 * configuration and preset
18689 */
ea734963 18690static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18691 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18692 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18693 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 18694 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 18695 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18696 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18697 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18698 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18699 [ALC663_ASUS_M51VA] = "m51va",
18700 [ALC663_ASUS_G71V] = "g71v",
18701 [ALC663_ASUS_H13] = "h13",
18702 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18703 [ALC663_ASUS_MODE1] = "asus-mode1",
18704 [ALC662_ASUS_MODE2] = "asus-mode2",
18705 [ALC663_ASUS_MODE3] = "asus-mode3",
18706 [ALC663_ASUS_MODE4] = "asus-mode4",
18707 [ALC663_ASUS_MODE5] = "asus-mode5",
18708 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18709 [ALC663_ASUS_MODE7] = "asus-mode7",
18710 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18711 [ALC272_DELL] = "dell",
18712 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18713 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18714 [ALC662_AUTO] = "auto",
18715};
18716
18717static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18718 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18719 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18720 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18721 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18722 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18723 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18724 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18725 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18726 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18727 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18728 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18729 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18730 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18731 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18732 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18733 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18734 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18735 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18736 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18737 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18738 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18739 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18740 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18741 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18742 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18743 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18744 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18745 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18746 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18747 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18748 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18749 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18750 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18751 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18752 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18753 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18754 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18755 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18756 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18757 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18758 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18759 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18760 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18761 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18762 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18763 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18764 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18765 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18766 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18767 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18768 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18769 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18770 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18771 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18772 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18773 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18774 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18775 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18776 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18777 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18778 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18779 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18780 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18781 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18782 ALC662_3ST_6ch_DIG),
4dee8baa 18783 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18784 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
6227cdce 18785 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18786 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18787 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18788 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18789 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18790 ALC662_3ST_6ch_DIG),
dea0a509
TI
18791 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18792 ALC663_ASUS_H13),
965b76d2 18793 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18794 {}
18795};
18796
18797static struct alc_config_preset alc662_presets[] = {
18798 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18799 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18800 .init_verbs = { alc662_init_verbs },
18801 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18802 .dac_nids = alc662_dac_nids,
18803 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18804 .dig_in_nid = ALC662_DIGIN_NID,
18805 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18806 .channel_mode = alc662_3ST_2ch_modes,
18807 .input_mux = &alc662_capture_source,
18808 },
18809 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18810 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18811 .init_verbs = { alc662_init_verbs },
18812 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18813 .dac_nids = alc662_dac_nids,
18814 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18815 .dig_in_nid = ALC662_DIGIN_NID,
18816 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18817 .channel_mode = alc662_3ST_6ch_modes,
18818 .need_dac_fix = 1,
18819 .input_mux = &alc662_capture_source,
f12ab1e0 18820 },
bc9f98a9 18821 [ALC662_3ST_6ch] = {
f9e336f6 18822 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18823 .init_verbs = { alc662_init_verbs },
18824 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18825 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18826 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18827 .channel_mode = alc662_3ST_6ch_modes,
18828 .need_dac_fix = 1,
18829 .input_mux = &alc662_capture_source,
f12ab1e0 18830 },
bc9f98a9 18831 [ALC662_5ST_DIG] = {
f9e336f6 18832 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18833 .init_verbs = { alc662_init_verbs },
18834 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18835 .dac_nids = alc662_dac_nids,
18836 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18837 .dig_in_nid = ALC662_DIGIN_NID,
18838 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18839 .channel_mode = alc662_5stack_modes,
18840 .input_mux = &alc662_capture_source,
18841 },
18842 [ALC662_LENOVO_101E] = {
f9e336f6 18843 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18844 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18845 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18846 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18847 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18848 .channel_mode = alc662_3ST_2ch_modes,
18849 .input_mux = &alc662_lenovo_101e_capture_source,
18850 .unsol_event = alc662_lenovo_101e_unsol_event,
18851 .init_hook = alc662_lenovo_101e_all_automute,
18852 },
291702f0 18853 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18854 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18855 .init_verbs = { alc662_init_verbs,
18856 alc662_eeepc_sue_init_verbs },
18857 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18858 .dac_nids = alc662_dac_nids,
291702f0
KY
18859 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18860 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18861 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18862 .setup = alc662_eeepc_setup,
291702f0
KY
18863 .init_hook = alc662_eeepc_inithook,
18864 },
8c427226 18865 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18866 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18867 alc662_chmode_mixer },
18868 .init_verbs = { alc662_init_verbs,
18869 alc662_eeepc_ep20_sue_init_verbs },
18870 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18871 .dac_nids = alc662_dac_nids,
8c427226
KY
18872 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18873 .channel_mode = alc662_3ST_6ch_modes,
18874 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18875 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18876 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18877 .init_hook = alc662_eeepc_ep20_inithook,
18878 },
f1d4e28b 18879 [ALC662_ECS] = {
f9e336f6 18880 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18881 .init_verbs = { alc662_init_verbs,
18882 alc662_ecs_init_verbs },
18883 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18884 .dac_nids = alc662_dac_nids,
18885 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18886 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18887 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18888 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18889 .init_hook = alc662_eeepc_inithook,
18890 },
6dda9f4a 18891 [ALC663_ASUS_M51VA] = {
f9e336f6 18892 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18893 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18894 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18895 .dac_nids = alc662_dac_nids,
18896 .dig_out_nid = ALC662_DIGOUT_NID,
18897 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18898 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18899 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18900 .setup = alc663_m51va_setup,
6dda9f4a
KY
18901 .init_hook = alc663_m51va_inithook,
18902 },
18903 [ALC663_ASUS_G71V] = {
f9e336f6 18904 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18905 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18906 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18907 .dac_nids = alc662_dac_nids,
18908 .dig_out_nid = ALC662_DIGOUT_NID,
18909 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18910 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18911 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18912 .setup = alc663_g71v_setup,
6dda9f4a
KY
18913 .init_hook = alc663_g71v_inithook,
18914 },
18915 [ALC663_ASUS_H13] = {
f9e336f6 18916 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18917 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18918 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18919 .dac_nids = alc662_dac_nids,
18920 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18921 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18922 .unsol_event = alc663_m51va_unsol_event,
18923 .init_hook = alc663_m51va_inithook,
18924 },
18925 [ALC663_ASUS_G50V] = {
f9e336f6 18926 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18927 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18928 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18929 .dac_nids = alc662_dac_nids,
18930 .dig_out_nid = ALC662_DIGOUT_NID,
18931 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18932 .channel_mode = alc662_3ST_6ch_modes,
18933 .input_mux = &alc663_capture_source,
18934 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18935 .setup = alc663_g50v_setup,
6dda9f4a
KY
18936 .init_hook = alc663_g50v_inithook,
18937 },
f1d4e28b 18938 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18939 .mixers = { alc663_m51va_mixer },
18940 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18941 .init_verbs = { alc662_init_verbs,
18942 alc663_21jd_amic_init_verbs },
18943 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18944 .hp_nid = 0x03,
18945 .dac_nids = alc662_dac_nids,
18946 .dig_out_nid = ALC662_DIGOUT_NID,
18947 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18948 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18949 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18950 .setup = alc663_mode1_setup,
f1d4e28b
KY
18951 .init_hook = alc663_mode1_inithook,
18952 },
18953 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18954 .mixers = { alc662_1bjd_mixer },
18955 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18956 .init_verbs = { alc662_init_verbs,
18957 alc662_1bjd_amic_init_verbs },
18958 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18959 .dac_nids = alc662_dac_nids,
18960 .dig_out_nid = ALC662_DIGOUT_NID,
18961 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18962 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18963 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18964 .setup = alc662_mode2_setup,
f1d4e28b
KY
18965 .init_hook = alc662_mode2_inithook,
18966 },
18967 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18968 .mixers = { alc663_two_hp_m1_mixer },
18969 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18970 .init_verbs = { alc662_init_verbs,
18971 alc663_two_hp_amic_m1_init_verbs },
18972 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18973 .hp_nid = 0x03,
18974 .dac_nids = alc662_dac_nids,
18975 .dig_out_nid = ALC662_DIGOUT_NID,
18976 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18977 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18978 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18979 .setup = alc663_mode3_setup,
f1d4e28b
KY
18980 .init_hook = alc663_mode3_inithook,
18981 },
18982 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18983 .mixers = { alc663_asus_21jd_clfe_mixer },
18984 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18985 .init_verbs = { alc662_init_verbs,
18986 alc663_21jd_amic_init_verbs},
18987 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18988 .hp_nid = 0x03,
18989 .dac_nids = alc662_dac_nids,
18990 .dig_out_nid = ALC662_DIGOUT_NID,
18991 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18992 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18993 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18994 .setup = alc663_mode4_setup,
f1d4e28b
KY
18995 .init_hook = alc663_mode4_inithook,
18996 },
18997 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18998 .mixers = { alc663_asus_15jd_clfe_mixer },
18999 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
19000 .init_verbs = { alc662_init_verbs,
19001 alc663_15jd_amic_init_verbs },
19002 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19003 .hp_nid = 0x03,
19004 .dac_nids = alc662_dac_nids,
19005 .dig_out_nid = ALC662_DIGOUT_NID,
19006 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19007 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 19008 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 19009 .setup = alc663_mode5_setup,
f1d4e28b
KY
19010 .init_hook = alc663_mode5_inithook,
19011 },
19012 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
19013 .mixers = { alc663_two_hp_m2_mixer },
19014 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
19015 .init_verbs = { alc662_init_verbs,
19016 alc663_two_hp_amic_m2_init_verbs },
19017 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19018 .hp_nid = 0x03,
19019 .dac_nids = alc662_dac_nids,
19020 .dig_out_nid = ALC662_DIGOUT_NID,
19021 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19022 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 19023 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 19024 .setup = alc663_mode6_setup,
f1d4e28b
KY
19025 .init_hook = alc663_mode6_inithook,
19026 },
ebb83eeb
KY
19027 [ALC663_ASUS_MODE7] = {
19028 .mixers = { alc663_mode7_mixer },
19029 .cap_mixer = alc662_auto_capture_mixer,
19030 .init_verbs = { alc662_init_verbs,
19031 alc663_mode7_init_verbs },
19032 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19033 .hp_nid = 0x03,
19034 .dac_nids = alc662_dac_nids,
19035 .dig_out_nid = ALC662_DIGOUT_NID,
19036 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19037 .channel_mode = alc662_3ST_2ch_modes,
19038 .unsol_event = alc663_mode7_unsol_event,
19039 .setup = alc663_mode7_setup,
19040 .init_hook = alc663_mode7_inithook,
19041 },
19042 [ALC663_ASUS_MODE8] = {
19043 .mixers = { alc663_mode8_mixer },
19044 .cap_mixer = alc662_auto_capture_mixer,
19045 .init_verbs = { alc662_init_verbs,
19046 alc663_mode8_init_verbs },
19047 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19048 .hp_nid = 0x03,
19049 .dac_nids = alc662_dac_nids,
19050 .dig_out_nid = ALC662_DIGOUT_NID,
19051 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19052 .channel_mode = alc662_3ST_2ch_modes,
19053 .unsol_event = alc663_mode8_unsol_event,
19054 .setup = alc663_mode8_setup,
19055 .init_hook = alc663_mode8_inithook,
19056 },
622e84cd
KY
19057 [ALC272_DELL] = {
19058 .mixers = { alc663_m51va_mixer },
19059 .cap_mixer = alc272_auto_capture_mixer,
19060 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
19061 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 19062 .dac_nids = alc272_dac_nids,
622e84cd
KY
19063 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19064 .adc_nids = alc272_adc_nids,
19065 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19066 .capsrc_nids = alc272_capsrc_nids,
19067 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19068 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19069 .setup = alc663_m51va_setup,
622e84cd
KY
19070 .init_hook = alc663_m51va_inithook,
19071 },
19072 [ALC272_DELL_ZM1] = {
19073 .mixers = { alc663_m51va_mixer },
19074 .cap_mixer = alc662_auto_capture_mixer,
19075 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19076 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 19077 .dac_nids = alc272_dac_nids,
622e84cd
KY
19078 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19079 .adc_nids = alc662_adc_nids,
b59bdf3b 19080 .num_adc_nids = 1,
622e84cd
KY
19081 .capsrc_nids = alc662_capsrc_nids,
19082 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19083 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19084 .setup = alc663_m51va_setup,
622e84cd
KY
19085 .init_hook = alc663_m51va_inithook,
19086 },
9541ba1d
CP
19087 [ALC272_SAMSUNG_NC10] = {
19088 .mixers = { alc272_nc10_mixer },
19089 .init_verbs = { alc662_init_verbs,
19090 alc663_21jd_amic_init_verbs },
19091 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19092 .dac_nids = alc272_dac_nids,
19093 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19094 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 19095 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 19096 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19097 .setup = alc663_mode4_setup,
9541ba1d
CP
19098 .init_hook = alc663_mode4_inithook,
19099 },
bc9f98a9
KY
19100};
19101
19102
19103/*
19104 * BIOS auto configuration
19105 */
19106
7085ec12 19107/* convert from MIX nid to DAC */
1304ac89
TI
19108static hda_nid_t alc662_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
19109{
19110 hda_nid_t list[4];
19111 int i, num;
19112
19113 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
19114 for (i = 0; i < num; i++) {
19115 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
19116 return list[i];
19117 }
19118 return 0;
7085ec12
TI
19119}
19120
19121/* get MIX nid connected to the given pin targeted to DAC */
19122static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19123 hda_nid_t dac)
19124{
cc1c452e 19125 hda_nid_t mix[5];
7085ec12
TI
19126 int i, num;
19127
19128 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19129 for (i = 0; i < num; i++) {
1304ac89 19130 if (alc662_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
19131 return mix[i];
19132 }
19133 return 0;
19134}
19135
19136/* look for an empty DAC slot */
19137static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19138{
19139 struct alc_spec *spec = codec->spec;
19140 hda_nid_t srcs[5];
19141 int i, j, num;
19142
19143 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19144 if (num < 0)
19145 return 0;
19146 for (i = 0; i < num; i++) {
1304ac89 19147 hda_nid_t nid = alc662_mix_to_dac(codec, srcs[i]);
7085ec12
TI
19148 if (!nid)
19149 continue;
19150 for (j = 0; j < spec->multiout.num_dacs; j++)
19151 if (spec->multiout.dac_nids[j] == nid)
19152 break;
19153 if (j >= spec->multiout.num_dacs)
19154 return nid;
19155 }
19156 return 0;
19157}
19158
19159/* fill in the dac_nids table from the parsed pin configuration */
19160static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19161 const struct auto_pin_cfg *cfg)
19162{
19163 struct alc_spec *spec = codec->spec;
19164 int i;
19165 hda_nid_t dac;
19166
19167 spec->multiout.dac_nids = spec->private_dac_nids;
19168 for (i = 0; i < cfg->line_outs; i++) {
19169 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19170 if (!dac)
19171 continue;
19172 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19173 }
19174 return 0;
19175}
19176
bcb2f0f5
TI
19177static inline int __alc662_add_vol_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_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
19181 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19182}
19183
bcb2f0f5
TI
19184static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19185 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19186{
bcb2f0f5 19187 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19188 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19189}
19190
bcb2f0f5
TI
19191#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19192 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19193#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19194 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19195#define alc662_add_stereo_vol(spec, pfx, nid) \
19196 alc662_add_vol_ctl(spec, pfx, nid, 3)
19197#define alc662_add_stereo_sw(spec, pfx, nid) \
19198 alc662_add_sw_ctl(spec, pfx, nid, 3)
19199
bc9f98a9 19200/* add playback controls from the parsed DAC table */
7085ec12 19201static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19202 const struct auto_pin_cfg *cfg)
19203{
7085ec12 19204 struct alc_spec *spec = codec->spec;
ea734963 19205 static const char * const chname[4] = {
bc9f98a9
KY
19206 "Front", "Surround", NULL /*CLFE*/, "Side"
19207 };
bcb2f0f5 19208 const char *pfx = alc_get_line_out_pfx(cfg, true);
7085ec12 19209 hda_nid_t nid, mix;
bc9f98a9
KY
19210 int i, err;
19211
19212 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19213 nid = spec->multiout.dac_nids[i];
19214 if (!nid)
19215 continue;
19216 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19217 if (!mix)
bc9f98a9 19218 continue;
bcb2f0f5 19219 if (!pfx && i == 2) {
bc9f98a9 19220 /* Center/LFE */
7085ec12 19221 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19222 if (err < 0)
19223 return err;
7085ec12 19224 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19225 if (err < 0)
19226 return err;
7085ec12 19227 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19228 if (err < 0)
19229 return err;
7085ec12 19230 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19231 if (err < 0)
19232 return err;
19233 } else {
bcb2f0f5 19234 const char *name = pfx;
5a882646
DH
19235 int index = i;
19236 if (!name) {
bcb2f0f5 19237 name = chname[i];
5a882646
DH
19238 index = 0;
19239 }
19240 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
bc9f98a9
KY
19241 if (err < 0)
19242 return err;
5a882646 19243 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
bc9f98a9
KY
19244 if (err < 0)
19245 return err;
19246 }
19247 }
19248 return 0;
19249}
19250
19251/* add playback controls for speaker and HP outputs */
7085ec12
TI
19252/* return DAC nid if any new DAC is assigned */
19253static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19254 const char *pfx)
19255{
7085ec12
TI
19256 struct alc_spec *spec = codec->spec;
19257 hda_nid_t nid, mix;
bc9f98a9 19258 int err;
bc9f98a9
KY
19259
19260 if (!pin)
19261 return 0;
7085ec12
TI
19262 nid = alc662_look_for_dac(codec, pin);
19263 if (!nid) {
7085ec12
TI
19264 /* the corresponding DAC is already occupied */
19265 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19266 return 0; /* no way */
19267 /* create a switch only */
0afe5f89 19268 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19269 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19270 }
19271
7085ec12
TI
19272 mix = alc662_dac_to_mix(codec, pin, nid);
19273 if (!mix)
19274 return 0;
19275 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19276 if (err < 0)
19277 return err;
19278 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19279 if (err < 0)
19280 return err;
19281 return nid;
bc9f98a9
KY
19282}
19283
19284/* create playback/capture controls for input pins */
05f5f477 19285#define alc662_auto_create_input_ctls \
4b7348a1 19286 alc882_auto_create_input_ctls
bc9f98a9
KY
19287
19288static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19289 hda_nid_t nid, int pin_type,
7085ec12 19290 hda_nid_t dac)
bc9f98a9 19291{
7085ec12 19292 int i, num;
ce503f38 19293 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19294
f6c7e546 19295 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19296 /* need the manual connection? */
7085ec12
TI
19297 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19298 if (num <= 1)
19299 return;
19300 for (i = 0; i < num; i++) {
1304ac89 19301 if (alc662_mix_to_dac(codec, srcs[i]) != dac)
7085ec12
TI
19302 continue;
19303 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19304 return;
bc9f98a9
KY
19305 }
19306}
19307
19308static void alc662_auto_init_multi_out(struct hda_codec *codec)
19309{
19310 struct alc_spec *spec = codec->spec;
7085ec12 19311 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19312 int i;
19313
19314 for (i = 0; i <= HDA_SIDE; i++) {
19315 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19316 if (nid)
baba8ee9 19317 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19318 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19319 }
19320}
19321
19322static void alc662_auto_init_hp_out(struct hda_codec *codec)
19323{
19324 struct alc_spec *spec = codec->spec;
19325 hda_nid_t pin;
19326
19327 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19328 if (pin)
19329 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19330 spec->multiout.hp_nid);
f6c7e546
TI
19331 pin = spec->autocfg.speaker_pins[0];
19332 if (pin)
7085ec12
TI
19333 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19334 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19335}
19336
bc9f98a9
KY
19337#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19338
19339static void alc662_auto_init_analog_input(struct hda_codec *codec)
19340{
19341 struct alc_spec *spec = codec->spec;
66ceeb6b 19342 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19343 int i;
19344
66ceeb6b
TI
19345 for (i = 0; i < cfg->num_inputs; i++) {
19346 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19347 if (alc_is_input_pin(codec, nid)) {
30ea098f 19348 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19349 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19350 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19351 snd_hda_codec_write(codec, nid, 0,
19352 AC_VERB_SET_AMP_GAIN_MUTE,
19353 AMP_OUT_MUTE);
19354 }
19355 }
19356}
19357
f511b01c
TI
19358#define alc662_auto_init_input_src alc882_auto_init_input_src
19359
bc9f98a9
KY
19360static int alc662_parse_auto_config(struct hda_codec *codec)
19361{
19362 struct alc_spec *spec = codec->spec;
19363 int err;
19364 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19365
19366 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19367 alc662_ignore);
19368 if (err < 0)
19369 return err;
19370 if (!spec->autocfg.line_outs)
19371 return 0; /* can't find valid BIOS pin config */
19372
7085ec12 19373 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19374 if (err < 0)
19375 return err;
7085ec12 19376 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19377 if (err < 0)
19378 return err;
7085ec12 19379 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19380 spec->autocfg.speaker_pins[0],
19381 "Speaker");
19382 if (err < 0)
19383 return err;
7085ec12
TI
19384 if (err)
19385 spec->multiout.extra_out_nid[0] = err;
19386 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19387 "Headphone");
19388 if (err < 0)
19389 return err;
7085ec12
TI
19390 if (err)
19391 spec->multiout.hp_nid = err;
05f5f477 19392 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19393 if (err < 0)
bc9f98a9
KY
19394 return err;
19395
19396 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19397
757899ac 19398 alc_auto_parse_digital(codec);
bc9f98a9 19399
603c4019 19400 if (spec->kctls.list)
d88897ea 19401 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19402
19403 spec->num_mux_defs = 1;
61b9b9b1 19404 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19405
cec27c89
KY
19406 add_verb(spec, alc662_init_verbs);
19407 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19408 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19409 add_verb(spec, alc663_init_verbs);
19410
19411 if (codec->vendor_id == 0x10ec0272)
19412 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19413
19414 err = alc_auto_add_mic_boost(codec);
19415 if (err < 0)
19416 return err;
19417
6227cdce
KY
19418 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19419 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19420 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19421 else
19422 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19423
8c87286f 19424 return 1;
bc9f98a9
KY
19425}
19426
19427/* additional initialization for auto-configuration model */
19428static void alc662_auto_init(struct hda_codec *codec)
19429{
f6c7e546 19430 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19431 alc662_auto_init_multi_out(codec);
19432 alc662_auto_init_hp_out(codec);
19433 alc662_auto_init_analog_input(codec);
f511b01c 19434 alc662_auto_init_input_src(codec);
757899ac 19435 alc_auto_init_digital(codec);
f6c7e546 19436 if (spec->unsol_event)
7fb0d78f 19437 alc_inithook(codec);
bc9f98a9
KY
19438}
19439
6be7948f 19440static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19441 const struct alc_fixup *fix, int action)
6fc398cb 19442{
b5bfbc67 19443 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19444 return;
6be7948f
TB
19445 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19446 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19447 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19448 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19449 (0 << AC_AMPCAP_MUTE_SHIFT)))
19450 printk(KERN_WARNING
19451 "hda_codec: failed to override amp caps for NID 0x2\n");
19452}
19453
6cb3b707 19454enum {
2df03514 19455 ALC662_FIXUP_ASPIRE,
6cb3b707 19456 ALC662_FIXUP_IDEAPAD,
6be7948f 19457 ALC272_FIXUP_MARIO,
d2ebd479 19458 ALC662_FIXUP_CZC_P10T,
c6b35874 19459 ALC662_FIXUP_GIGABYTE,
6cb3b707
DH
19460};
19461
19462static const struct alc_fixup alc662_fixups[] = {
2df03514 19463 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19464 .type = ALC_FIXUP_PINS,
19465 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19466 { 0x15, 0x99130112 }, /* subwoofer */
19467 { }
19468 }
19469 },
6cb3b707 19470 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19471 .type = ALC_FIXUP_PINS,
19472 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19473 { 0x17, 0x99130112 }, /* subwoofer */
19474 { }
19475 }
19476 },
6be7948f 19477 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19478 .type = ALC_FIXUP_FUNC,
19479 .v.func = alc272_fixup_mario,
d2ebd479
AA
19480 },
19481 [ALC662_FIXUP_CZC_P10T] = {
19482 .type = ALC_FIXUP_VERBS,
19483 .v.verbs = (const struct hda_verb[]) {
19484 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19485 {}
19486 }
19487 },
c6b35874
TI
19488 [ALC662_FIXUP_GIGABYTE] = {
19489 .type = ALC_FIXUP_PINS,
19490 .v.pins = (const struct alc_pincfg[]) {
19491 { 0x14, 0x1114410 }, /* set as speaker */
19492 { }
19493 }
19494 },
6cb3b707
DH
19495};
19496
19497static struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19498 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
2df03514 19499 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19500 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
c6b35874 19501 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE),
d4118588 19502 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19503 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19504 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19505 {}
19506};
19507
6be7948f
TB
19508static const struct alc_model_fixup alc662_fixup_models[] = {
19509 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19510 {}
19511};
6cb3b707
DH
19512
19513
bc9f98a9
KY
19514static int patch_alc662(struct hda_codec *codec)
19515{
19516 struct alc_spec *spec;
19517 int err, board_config;
693194f3 19518 int coef;
bc9f98a9
KY
19519
19520 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19521 if (!spec)
19522 return -ENOMEM;
19523
19524 codec->spec = spec;
19525
da00c244
KY
19526 alc_auto_parse_customize_define(codec);
19527
2c3bf9ab
TI
19528 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19529
693194f3
KY
19530 coef = alc_read_coef_idx(codec, 0);
19531 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19532 alc_codec_rename(codec, "ALC661");
693194f3
KY
19533 else if (coef & (1 << 14) &&
19534 codec->bus->pci->subsystem_vendor == 0x1025 &&
19535 spec->cdefine.platform_type == 1)
c027ddcd 19536 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19537 else if (coef == 0x4011)
19538 alc_codec_rename(codec, "ALC656");
274693f3 19539
bc9f98a9
KY
19540 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19541 alc662_models,
19542 alc662_cfg_tbl);
19543 if (board_config < 0) {
9a11f1aa
TI
19544 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19545 codec->chip_name);
bc9f98a9
KY
19546 board_config = ALC662_AUTO;
19547 }
19548
19549 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19550 alc_pick_fixup(codec, alc662_fixup_models,
19551 alc662_fixup_tbl, alc662_fixups);
19552 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19553 /* automatic parse from the BIOS config */
19554 err = alc662_parse_auto_config(codec);
19555 if (err < 0) {
19556 alc_free(codec);
19557 return err;
8c87286f 19558 } else if (!err) {
bc9f98a9
KY
19559 printk(KERN_INFO
19560 "hda_codec: Cannot set up configuration "
19561 "from BIOS. Using base mode...\n");
19562 board_config = ALC662_3ST_2ch_DIG;
19563 }
19564 }
19565
dc1eae25 19566 if (has_cdefine_beep(codec)) {
8af2591d
TI
19567 err = snd_hda_attach_beep_device(codec, 0x1);
19568 if (err < 0) {
19569 alc_free(codec);
19570 return err;
19571 }
680cd536
KK
19572 }
19573
bc9f98a9 19574 if (board_config != ALC662_AUTO)
e9c364c0 19575 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19576
bc9f98a9
KY
19577 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19578 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19579
bc9f98a9
KY
19580 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19581 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19582
dd704698
TI
19583 if (!spec->adc_nids) {
19584 spec->adc_nids = alc662_adc_nids;
19585 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19586 }
19587 if (!spec->capsrc_nids)
19588 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19589
f9e336f6 19590 if (!spec->cap_mixer)
b59bdf3b 19591 set_capture_mixer(codec);
cec27c89 19592
dc1eae25 19593 if (has_cdefine_beep(codec)) {
da00c244
KY
19594 switch (codec->vendor_id) {
19595 case 0x10ec0662:
19596 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19597 break;
19598 case 0x10ec0272:
19599 case 0x10ec0663:
19600 case 0x10ec0665:
19601 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19602 break;
19603 case 0x10ec0273:
19604 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19605 break;
19606 }
cec27c89 19607 }
2134ea4f
TI
19608 spec->vmaster_nid = 0x02;
19609
b5bfbc67
TI
19610 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19611
bc9f98a9 19612 codec->patch_ops = alc_patch_ops;
b5bfbc67 19613 if (board_config == ALC662_AUTO)
bc9f98a9 19614 spec->init_hook = alc662_auto_init;
6cb3b707 19615
bf1b0225
KY
19616 alc_init_jacks(codec);
19617
cb53c626
TI
19618#ifdef CONFIG_SND_HDA_POWER_SAVE
19619 if (!spec->loopback.amplist)
19620 spec->loopback.amplist = alc662_loopbacks;
19621#endif
bc9f98a9
KY
19622
19623 return 0;
19624}
19625
274693f3
KY
19626static int patch_alc888(struct hda_codec *codec)
19627{
19628 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19629 kfree(codec->chip_name);
01e0f137
KY
19630 if (codec->vendor_id == 0x10ec0887)
19631 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19632 else
19633 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19634 if (!codec->chip_name) {
19635 alc_free(codec);
274693f3 19636 return -ENOMEM;
ac2c92e0
TI
19637 }
19638 return patch_alc662(codec);
274693f3 19639 }
ac2c92e0 19640 return patch_alc882(codec);
274693f3
KY
19641}
19642
d1eb57f4
KY
19643/*
19644 * ALC680 support
19645 */
c69aefab 19646#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19647#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19648#define alc680_modes alc260_modes
19649
19650static hda_nid_t alc680_dac_nids[3] = {
19651 /* Lout1, Lout2, hp */
19652 0x02, 0x03, 0x04
19653};
19654
19655static hda_nid_t alc680_adc_nids[3] = {
19656 /* ADC0-2 */
19657 /* DMIC, MIC, Line-in*/
19658 0x07, 0x08, 0x09
19659};
19660
c69aefab
KY
19661/*
19662 * Analog capture ADC cgange
19663 */
66ceeb6b
TI
19664static void alc680_rec_autoswitch(struct hda_codec *codec)
19665{
19666 struct alc_spec *spec = codec->spec;
19667 struct auto_pin_cfg *cfg = &spec->autocfg;
19668 int pin_found = 0;
19669 int type_found = AUTO_PIN_LAST;
19670 hda_nid_t nid;
19671 int i;
19672
19673 for (i = 0; i < cfg->num_inputs; i++) {
19674 nid = cfg->inputs[i].pin;
19675 if (!(snd_hda_query_pin_caps(codec, nid) &
19676 AC_PINCAP_PRES_DETECT))
19677 continue;
19678 if (snd_hda_jack_detect(codec, nid)) {
19679 if (cfg->inputs[i].type < type_found) {
19680 type_found = cfg->inputs[i].type;
19681 pin_found = nid;
19682 }
19683 }
19684 }
19685
19686 nid = 0x07;
19687 if (pin_found)
19688 snd_hda_get_connections(codec, pin_found, &nid, 1);
19689
19690 if (nid != spec->cur_adc)
19691 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19692 spec->cur_adc = nid;
19693 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19694 spec->cur_adc_format);
19695}
19696
c69aefab
KY
19697static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19698 struct hda_codec *codec,
19699 unsigned int stream_tag,
19700 unsigned int format,
19701 struct snd_pcm_substream *substream)
19702{
19703 struct alc_spec *spec = codec->spec;
c69aefab 19704
66ceeb6b 19705 spec->cur_adc = 0x07;
c69aefab
KY
19706 spec->cur_adc_stream_tag = stream_tag;
19707 spec->cur_adc_format = format;
19708
66ceeb6b 19709 alc680_rec_autoswitch(codec);
c69aefab
KY
19710 return 0;
19711}
19712
19713static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19714 struct hda_codec *codec,
19715 struct snd_pcm_substream *substream)
19716{
19717 snd_hda_codec_cleanup_stream(codec, 0x07);
19718 snd_hda_codec_cleanup_stream(codec, 0x08);
19719 snd_hda_codec_cleanup_stream(codec, 0x09);
19720 return 0;
19721}
19722
19723static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19724 .substreams = 1, /* can be overridden */
19725 .channels_min = 2,
19726 .channels_max = 2,
19727 /* NID is set in alc_build_pcms */
19728 .ops = {
19729 .prepare = alc680_capture_pcm_prepare,
19730 .cleanup = alc680_capture_pcm_cleanup
19731 },
19732};
19733
d1eb57f4
KY
19734static struct snd_kcontrol_new alc680_base_mixer[] = {
19735 /* output mixer control */
19736 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19737 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19738 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19739 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19740 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19741 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19742 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19743 { }
19744};
19745
c69aefab
KY
19746static struct hda_bind_ctls alc680_bind_cap_vol = {
19747 .ops = &snd_hda_bind_vol,
19748 .values = {
19749 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19750 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19751 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19752 0
19753 },
19754};
19755
19756static struct hda_bind_ctls alc680_bind_cap_switch = {
19757 .ops = &snd_hda_bind_sw,
19758 .values = {
19759 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19760 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19761 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19762 0
19763 },
19764};
19765
19766static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19767 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19768 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19769 { } /* end */
19770};
19771
19772/*
19773 * generic initialization of ADC, input mixers and output mixers
19774 */
19775static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19776 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19777 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19778 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19779
c69aefab
KY
19780 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19781 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19782 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19783 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19784 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19785 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19786
19787 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19788 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19789 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19790 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19791 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19792
19793 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19794 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19795 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19796
d1eb57f4
KY
19797 { }
19798};
19799
c69aefab
KY
19800/* toggle speaker-output according to the hp-jack state */
19801static void alc680_base_setup(struct hda_codec *codec)
19802{
19803 struct alc_spec *spec = codec->spec;
19804
19805 spec->autocfg.hp_pins[0] = 0x16;
19806 spec->autocfg.speaker_pins[0] = 0x14;
19807 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19808 spec->autocfg.num_inputs = 2;
19809 spec->autocfg.inputs[0].pin = 0x18;
19810 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19811 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19812 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19813}
19814
19815static void alc680_unsol_event(struct hda_codec *codec,
19816 unsigned int res)
19817{
19818 if ((res >> 26) == ALC880_HP_EVENT)
19819 alc_automute_amp(codec);
19820 if ((res >> 26) == ALC880_MIC_EVENT)
19821 alc680_rec_autoswitch(codec);
19822}
19823
19824static void alc680_inithook(struct hda_codec *codec)
19825{
19826 alc_automute_amp(codec);
19827 alc680_rec_autoswitch(codec);
19828}
19829
d1eb57f4
KY
19830/* create input playback/capture controls for the given pin */
19831static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19832 const char *ctlname, int idx)
19833{
19834 hda_nid_t dac;
19835 int err;
19836
19837 switch (nid) {
19838 case 0x14:
19839 dac = 0x02;
19840 break;
19841 case 0x15:
19842 dac = 0x03;
19843 break;
19844 case 0x16:
19845 dac = 0x04;
19846 break;
19847 default:
19848 return 0;
19849 }
19850 if (spec->multiout.dac_nids[0] != dac &&
19851 spec->multiout.dac_nids[1] != dac) {
19852 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19853 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19854 HDA_OUTPUT));
19855 if (err < 0)
19856 return err;
19857
19858 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19859 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19860
19861 if (err < 0)
19862 return err;
19863 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19864 }
19865
19866 return 0;
19867}
19868
19869/* add playback controls from the parsed DAC table */
19870static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19871 const struct auto_pin_cfg *cfg)
19872{
19873 hda_nid_t nid;
19874 int err;
19875
19876 spec->multiout.dac_nids = spec->private_dac_nids;
19877
19878 nid = cfg->line_out_pins[0];
19879 if (nid) {
19880 const char *name;
19881 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19882 name = "Speaker";
19883 else
19884 name = "Front";
19885 err = alc680_new_analog_output(spec, nid, name, 0);
19886 if (err < 0)
19887 return err;
19888 }
19889
19890 nid = cfg->speaker_pins[0];
19891 if (nid) {
19892 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19893 if (err < 0)
19894 return err;
19895 }
19896 nid = cfg->hp_pins[0];
19897 if (nid) {
19898 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19899 if (err < 0)
19900 return err;
19901 }
19902
19903 return 0;
19904}
19905
19906static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19907 hda_nid_t nid, int pin_type)
19908{
19909 alc_set_pin_output(codec, nid, pin_type);
19910}
19911
19912static void alc680_auto_init_multi_out(struct hda_codec *codec)
19913{
19914 struct alc_spec *spec = codec->spec;
19915 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19916 if (nid) {
19917 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19918 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19919 }
19920}
19921
19922static void alc680_auto_init_hp_out(struct hda_codec *codec)
19923{
19924 struct alc_spec *spec = codec->spec;
19925 hda_nid_t pin;
19926
19927 pin = spec->autocfg.hp_pins[0];
19928 if (pin)
19929 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19930 pin = spec->autocfg.speaker_pins[0];
19931 if (pin)
19932 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19933}
19934
19935/* pcm configuration: identical with ALC880 */
19936#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19937#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19938#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19939#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19940#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19941
19942/*
19943 * BIOS auto configuration
19944 */
19945static int alc680_parse_auto_config(struct hda_codec *codec)
19946{
19947 struct alc_spec *spec = codec->spec;
19948 int err;
19949 static hda_nid_t alc680_ignore[] = { 0 };
19950
19951 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19952 alc680_ignore);
19953 if (err < 0)
19954 return err;
c69aefab 19955
d1eb57f4
KY
19956 if (!spec->autocfg.line_outs) {
19957 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19958 spec->multiout.max_channels = 2;
19959 spec->no_analog = 1;
19960 goto dig_only;
19961 }
19962 return 0; /* can't find valid BIOS pin config */
19963 }
19964 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19965 if (err < 0)
19966 return err;
19967
19968 spec->multiout.max_channels = 2;
19969
19970 dig_only:
19971 /* digital only support output */
757899ac 19972 alc_auto_parse_digital(codec);
d1eb57f4
KY
19973 if (spec->kctls.list)
19974 add_mixer(spec, spec->kctls.list);
19975
19976 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19977
19978 err = alc_auto_add_mic_boost(codec);
19979 if (err < 0)
19980 return err;
19981
19982 return 1;
19983}
19984
19985#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19986
19987/* init callback for auto-configuration model -- overriding the default init */
19988static void alc680_auto_init(struct hda_codec *codec)
19989{
19990 struct alc_spec *spec = codec->spec;
19991 alc680_auto_init_multi_out(codec);
19992 alc680_auto_init_hp_out(codec);
19993 alc680_auto_init_analog_input(codec);
757899ac 19994 alc_auto_init_digital(codec);
d1eb57f4
KY
19995 if (spec->unsol_event)
19996 alc_inithook(codec);
19997}
19998
19999/*
20000 * configuration and preset
20001 */
ea734963 20002static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
20003 [ALC680_BASE] = "base",
20004 [ALC680_AUTO] = "auto",
d1eb57f4
KY
20005};
20006
20007static struct snd_pci_quirk alc680_cfg_tbl[] = {
20008 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
20009 {}
20010};
20011
20012static struct alc_config_preset alc680_presets[] = {
20013 [ALC680_BASE] = {
20014 .mixers = { alc680_base_mixer },
c69aefab 20015 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
20016 .init_verbs = { alc680_init_verbs },
20017 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20018 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
20019 .dig_out_nid = ALC680_DIGOUT_NID,
20020 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20021 .channel_mode = alc680_modes,
c69aefab
KY
20022 .unsol_event = alc680_unsol_event,
20023 .setup = alc680_base_setup,
20024 .init_hook = alc680_inithook,
20025
d1eb57f4
KY
20026 },
20027};
20028
20029static int patch_alc680(struct hda_codec *codec)
20030{
20031 struct alc_spec *spec;
20032 int board_config;
20033 int err;
20034
20035 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20036 if (spec == NULL)
20037 return -ENOMEM;
20038
20039 codec->spec = spec;
20040
20041 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20042 alc680_models,
20043 alc680_cfg_tbl);
20044
20045 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20046 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20047 codec->chip_name);
20048 board_config = ALC680_AUTO;
20049 }
20050
20051 if (board_config == ALC680_AUTO) {
20052 /* automatic parse from the BIOS config */
20053 err = alc680_parse_auto_config(codec);
20054 if (err < 0) {
20055 alc_free(codec);
20056 return err;
20057 } else if (!err) {
20058 printk(KERN_INFO
20059 "hda_codec: Cannot set up configuration "
20060 "from BIOS. Using base mode...\n");
20061 board_config = ALC680_BASE;
20062 }
20063 }
20064
20065 if (board_config != ALC680_AUTO)
20066 setup_preset(codec, &alc680_presets[board_config]);
20067
20068 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 20069 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 20070 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 20071 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
20072
20073 if (!spec->adc_nids) {
20074 spec->adc_nids = alc680_adc_nids;
20075 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20076 }
20077
20078 if (!spec->cap_mixer)
20079 set_capture_mixer(codec);
20080
20081 spec->vmaster_nid = 0x02;
20082
20083 codec->patch_ops = alc_patch_ops;
20084 if (board_config == ALC680_AUTO)
20085 spec->init_hook = alc680_auto_init;
20086
20087 return 0;
20088}
20089
1da177e4
LT
20090/*
20091 * patch entries
20092 */
1289e9e8 20093static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 20094 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20095 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20096 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20097 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20098 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20099 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20100 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20101 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20102 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20103 .patch = patch_alc861 },
f32610ed
JS
20104 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20105 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20106 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20107 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20108 .patch = patch_alc882 },
bc9f98a9
KY
20109 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20110 .patch = patch_alc662 },
6dda9f4a 20111 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20112 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20113 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20114 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20115 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20116 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20117 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20118 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20119 .patch = patch_alc882 },
cb308f97 20120 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20121 .patch = patch_alc882 },
df694daa 20122 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20123 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20124 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20125 .patch = patch_alc882 },
274693f3 20126 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20127 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20128 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20129 {} /* terminator */
20130};
1289e9e8
TI
20131
20132MODULE_ALIAS("snd-hda-codec-id:10ec*");
20133
20134MODULE_LICENSE("GPL");
20135MODULE_DESCRIPTION("Realtek HD-audio codec");
20136
20137static struct hda_codec_preset_list realtek_list = {
20138 .preset = snd_hda_preset_realtek,
20139 .owner = THIS_MODULE,
20140};
20141
20142static int __init patch_realtek_init(void)
20143{
20144 return snd_hda_add_codec_preset(&realtek_list);
20145}
20146
20147static void __exit patch_realtek_exit(void)
20148{
20149 snd_hda_delete_codec_preset(&realtek_list);
20150}
20151
20152module_init(patch_realtek_init)
20153module_exit(patch_realtek_exit)