]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Optimize the check of ALC269 codec variants
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
ea1fb29a 234 ALC883_MEDION_MD2,
7ad7b218 235 ALC883_MEDION_WIM2160,
b373bdeb 236 ALC883_LAPTOP_EAPD,
bc9f98a9 237 ALC883_LENOVO_101E_2ch,
272a527c 238 ALC883_LENOVO_NB0763,
189609ae 239 ALC888_LENOVO_MS7195_DIG,
e2757d5e 240 ALC888_LENOVO_SKY,
ea1fb29a 241 ALC883_HAIER_W66,
4723c022 242 ALC888_3ST_HP,
5795b9e6 243 ALC888_6ST_DELL,
a8848bd6 244 ALC883_MITAC,
a65cc60f 245 ALC883_CLEVO_M540R,
0c4cc443 246 ALC883_CLEVO_M720,
fb97dc67 247 ALC883_FUJITSU_PI2515,
ef8ef5fb 248 ALC888_FUJITSU_XA3530,
17bba1b7 249 ALC883_3ST_6ch_INTEL,
87a8c370
JK
250 ALC889A_INTEL,
251 ALC889_INTEL,
e2757d5e
KY
252 ALC888_ASUS_M90V,
253 ALC888_ASUS_EEE1601,
eb4c41d3 254 ALC889A_MB31,
3ab90935 255 ALC1200_ASUS_P5Q,
3e1647c5 256 ALC883_SONY_VAIO_TT,
4953550a
TI
257 ALC882_AUTO,
258 ALC882_MODEL_LAST,
9c7f852e
TI
259};
260
d4a86d81
TI
261/* ALC680 models */
262enum {
263 ALC680_BASE,
264 ALC680_AUTO,
265 ALC680_MODEL_LAST,
266};
267
df694daa
KY
268/* for GPIO Poll */
269#define GPIO_MASK 0x03
270
4a79ba34
TI
271/* extra amp-initialization sequence types */
272enum {
273 ALC_INIT_NONE,
274 ALC_INIT_DEFAULT,
275 ALC_INIT_GPIO1,
276 ALC_INIT_GPIO2,
277 ALC_INIT_GPIO3,
278};
279
6c819492
TI
280struct alc_mic_route {
281 hda_nid_t pin;
282 unsigned char mux_idx;
283 unsigned char amix_idx;
284};
285
9ad0e496
KY
286struct alc_jack {
287 hda_nid_t nid;
288 int type;
289 struct snd_jack *jack;
290};
291
6c819492
TI
292#define MUX_IDX_UNDEF ((unsigned char)-1)
293
da00c244
KY
294struct alc_customize_define {
295 unsigned int sku_cfg;
296 unsigned char port_connectivity;
297 unsigned char check_sum;
298 unsigned char customization;
299 unsigned char external_amp;
300 unsigned int enable_pcbeep:1;
301 unsigned int platform_type:1;
302 unsigned int swap:1;
303 unsigned int override:1;
304};
305
1da177e4
LT
306struct alc_spec {
307 /* codec parameterization */
df694daa 308 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 309 unsigned int num_mixers;
f9e336f6 310 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 311 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 312
2d9c6482 313 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
314 * don't forget NULL
315 * termination!
e9edcee0
TI
316 */
317 unsigned int num_init_verbs;
1da177e4 318
aa563af7 319 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
320 struct hda_pcm_stream *stream_analog_playback;
321 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
322 struct hda_pcm_stream *stream_analog_alt_playback;
323 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 324
aa563af7 325 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
326 struct hda_pcm_stream *stream_digital_playback;
327 struct hda_pcm_stream *stream_digital_capture;
328
329 /* playback */
16ded525
TI
330 struct hda_multi_out multiout; /* playback set-up
331 * max_channels, dacs must be set
332 * dig_out_nid and hp_nid are optional
333 */
6330079f 334 hda_nid_t alt_dac_nid;
6a05ac4a 335 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 336 int dig_out_type;
1da177e4
LT
337
338 /* capture */
339 unsigned int num_adc_nids;
340 hda_nid_t *adc_nids;
e1406348 341 hda_nid_t *capsrc_nids;
16ded525 342 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 343
840b64c0
TI
344 /* capture setup for dynamic dual-adc switch */
345 unsigned int cur_adc_idx;
346 hda_nid_t cur_adc;
347 unsigned int cur_adc_stream_tag;
348 unsigned int cur_adc_format;
349
1da177e4 350 /* capture source */
a1e8d2da 351 unsigned int num_mux_defs;
1da177e4
LT
352 const struct hda_input_mux *input_mux;
353 unsigned int cur_mux[3];
6c819492
TI
354 struct alc_mic_route ext_mic;
355 struct alc_mic_route int_mic;
1da177e4
LT
356
357 /* channel model */
d2a6d7dc 358 const struct hda_channel_mode *channel_mode;
1da177e4 359 int num_channel_mode;
4e195a7b 360 int need_dac_fix;
3b315d70
HM
361 int const_channel_count;
362 int ext_channel_count;
1da177e4
LT
363
364 /* PCM information */
4c5186ed 365 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 366
9ad0e496
KY
367 /* jack detection */
368 struct snd_array jacks;
369
e9edcee0
TI
370 /* dynamic controls, init_verbs and input_mux */
371 struct auto_pin_cfg autocfg;
da00c244 372 struct alc_customize_define cdefine;
603c4019 373 struct snd_array kctls;
61b9b9b1 374 struct hda_input_mux private_imux[3];
41923e44 375 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
376 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
377 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 378
ae6b813a
TI
379 /* hooks */
380 void (*init_hook)(struct hda_codec *codec);
381 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 382#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 383 void (*power_hook)(struct hda_codec *codec);
f5de24b0 384#endif
ae6b813a 385
834be88d
TI
386 /* for pin sensing */
387 unsigned int sense_updated: 1;
388 unsigned int jack_present: 1;
bec15c3a 389 unsigned int master_sw: 1;
6c819492 390 unsigned int auto_mic:1;
cb53c626 391
e64f14f4
TI
392 /* other flags */
393 unsigned int no_analog :1; /* digital I/O only */
840b64c0 394 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
4a79ba34 395 int init_amp;
d433a678 396 int codec_variant; /* flag for other variants */
e64f14f4 397
2134ea4f
TI
398 /* for virtual master */
399 hda_nid_t vmaster_nid;
cb53c626
TI
400#ifdef CONFIG_SND_HDA_POWER_SAVE
401 struct hda_loopback_check loopback;
402#endif
2c3bf9ab
TI
403
404 /* for PLL fix */
405 hda_nid_t pll_nid;
406 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
407};
408
409/*
410 * configuration template - to be copied to the spec instance
411 */
412struct alc_config_preset {
9c7f852e
TI
413 struct snd_kcontrol_new *mixers[5]; /* should be identical size
414 * with spec
415 */
f9e336f6 416 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
417 const struct hda_verb *init_verbs[5];
418 unsigned int num_dacs;
419 hda_nid_t *dac_nids;
420 hda_nid_t dig_out_nid; /* optional */
421 hda_nid_t hp_nid; /* optional */
b25c9da1 422 hda_nid_t *slave_dig_outs;
df694daa
KY
423 unsigned int num_adc_nids;
424 hda_nid_t *adc_nids;
e1406348 425 hda_nid_t *capsrc_nids;
df694daa
KY
426 hda_nid_t dig_in_nid;
427 unsigned int num_channel_mode;
428 const struct hda_channel_mode *channel_mode;
4e195a7b 429 int need_dac_fix;
3b315d70 430 int const_channel_count;
a1e8d2da 431 unsigned int num_mux_defs;
df694daa 432 const struct hda_input_mux *input_mux;
ae6b813a 433 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 434 void (*setup)(struct hda_codec *);
ae6b813a 435 void (*init_hook)(struct hda_codec *);
cb53c626
TI
436#ifdef CONFIG_SND_HDA_POWER_SAVE
437 struct hda_amp_list *loopbacks;
c97259df 438 void (*power_hook)(struct hda_codec *codec);
cb53c626 439#endif
1da177e4
LT
440};
441
1da177e4
LT
442
443/*
444 * input MUX handling
445 */
9c7f852e
TI
446static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
447 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
448{
449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
450 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
451 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
452 if (mux_idx >= spec->num_mux_defs)
453 mux_idx = 0;
5311114d
TI
454 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
455 mux_idx = 0;
a1e8d2da 456 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
457}
458
9c7f852e
TI
459static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
461{
462 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
463 struct alc_spec *spec = codec->spec;
464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
465
466 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
467 return 0;
468}
469
9c7f852e
TI
470static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
471 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
472{
473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
474 struct alc_spec *spec = codec->spec;
cd896c33 475 const struct hda_input_mux *imux;
1da177e4 476 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 477 unsigned int mux_idx;
e1406348
TI
478 hda_nid_t nid = spec->capsrc_nids ?
479 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 480 unsigned int type;
1da177e4 481
cd896c33
TI
482 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
483 imux = &spec->input_mux[mux_idx];
5311114d
TI
484 if (!imux->num_items && mux_idx > 0)
485 imux = &spec->input_mux[0];
cd896c33 486
a22d543a 487 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 488 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
489 /* Matrix-mixer style (e.g. ALC882) */
490 unsigned int *cur_val = &spec->cur_mux[adc_idx];
491 unsigned int i, idx;
492
493 idx = ucontrol->value.enumerated.item[0];
494 if (idx >= imux->num_items)
495 idx = imux->num_items - 1;
496 if (*cur_val == idx)
497 return 0;
498 for (i = 0; i < imux->num_items; i++) {
499 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
500 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
501 imux->items[i].index,
502 HDA_AMP_MUTE, v);
503 }
504 *cur_val = idx;
505 return 1;
506 } else {
507 /* MUX style (e.g. ALC880) */
cd896c33 508 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
509 &spec->cur_mux[adc_idx]);
510 }
511}
e9edcee0 512
1da177e4
LT
513/*
514 * channel mode setting
515 */
9c7f852e
TI
516static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
518{
519 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
520 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
521 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
522 spec->num_channel_mode);
1da177e4
LT
523}
524
9c7f852e
TI
525static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
526 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
527{
528 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
529 struct alc_spec *spec = codec->spec;
d2a6d7dc 530 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 531 spec->num_channel_mode,
3b315d70 532 spec->ext_channel_count);
1da177e4
LT
533}
534
9c7f852e
TI
535static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
536 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
537{
538 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
539 struct alc_spec *spec = codec->spec;
4e195a7b
TI
540 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
541 spec->num_channel_mode,
3b315d70
HM
542 &spec->ext_channel_count);
543 if (err >= 0 && !spec->const_channel_count) {
544 spec->multiout.max_channels = spec->ext_channel_count;
545 if (spec->need_dac_fix)
546 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
547 }
4e195a7b 548 return err;
1da177e4
LT
549}
550
a9430dd8 551/*
4c5186ed 552 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 553 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
554 * being part of a format specifier. Maximum allowed length of a value is
555 * 63 characters plus NULL terminator.
7cf51e48
JW
556 *
557 * Note: some retasking pin complexes seem to ignore requests for input
558 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
559 * are requested. Therefore order this list so that this behaviour will not
560 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
561 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
562 * March 2006.
4c5186ed
JW
563 */
564static char *alc_pin_mode_names[] = {
7cf51e48
JW
565 "Mic 50pc bias", "Mic 80pc bias",
566 "Line in", "Line out", "Headphone out",
4c5186ed
JW
567};
568static unsigned char alc_pin_mode_values[] = {
7cf51e48 569 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
570};
571/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
572 * in the pin being assumed to be exclusively an input or an output pin. In
573 * addition, "input" pins may or may not process the mic bias option
574 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
575 * accept requests for bias as of chip versions up to March 2006) and/or
576 * wiring in the computer.
a9430dd8 577 */
a1e8d2da
JW
578#define ALC_PIN_DIR_IN 0x00
579#define ALC_PIN_DIR_OUT 0x01
580#define ALC_PIN_DIR_INOUT 0x02
581#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
582#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 583
ea1fb29a 584/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
585 * For each direction the minimum and maximum values are given.
586 */
a1e8d2da 587static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
588 { 0, 2 }, /* ALC_PIN_DIR_IN */
589 { 3, 4 }, /* ALC_PIN_DIR_OUT */
590 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
591 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
592 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
593};
594#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
595#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
596#define alc_pin_mode_n_items(_dir) \
597 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
598
9c7f852e
TI
599static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
600 struct snd_ctl_elem_info *uinfo)
a9430dd8 601{
4c5186ed
JW
602 unsigned int item_num = uinfo->value.enumerated.item;
603 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
604
605 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 606 uinfo->count = 1;
4c5186ed
JW
607 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
608
609 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
610 item_num = alc_pin_mode_min(dir);
611 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
612 return 0;
613}
614
9c7f852e
TI
615static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
616 struct snd_ctl_elem_value *ucontrol)
a9430dd8 617{
4c5186ed 618 unsigned int i;
a9430dd8
JW
619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
620 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 621 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 622 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
623 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
624 AC_VERB_GET_PIN_WIDGET_CONTROL,
625 0x00);
a9430dd8 626
4c5186ed
JW
627 /* Find enumerated value for current pinctl setting */
628 i = alc_pin_mode_min(dir);
4b35d2ca 629 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 630 i++;
9c7f852e 631 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
632 return 0;
633}
634
9c7f852e
TI
635static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
636 struct snd_ctl_elem_value *ucontrol)
a9430dd8 637{
4c5186ed 638 signed int change;
a9430dd8
JW
639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
640 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
641 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
642 long val = *ucontrol->value.integer.value;
9c7f852e
TI
643 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
644 AC_VERB_GET_PIN_WIDGET_CONTROL,
645 0x00);
a9430dd8 646
f12ab1e0 647 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
648 val = alc_pin_mode_min(dir);
649
650 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
651 if (change) {
652 /* Set pin mode to that requested */
82beb8fd
TI
653 snd_hda_codec_write_cache(codec, nid, 0,
654 AC_VERB_SET_PIN_WIDGET_CONTROL,
655 alc_pin_mode_values[val]);
cdcd9268 656
ea1fb29a 657 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
658 * for the requested pin mode. Enum values of 2 or less are
659 * input modes.
660 *
661 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
662 * reduces noise slightly (particularly on input) so we'll
663 * do it. However, having both input and output buffers
664 * enabled simultaneously doesn't seem to be problematic if
665 * this turns out to be necessary in the future.
cdcd9268
JW
666 */
667 if (val <= 2) {
47fd830a
TI
668 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
669 HDA_AMP_MUTE, HDA_AMP_MUTE);
670 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
671 HDA_AMP_MUTE, 0);
cdcd9268 672 } else {
47fd830a
TI
673 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
674 HDA_AMP_MUTE, HDA_AMP_MUTE);
675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
676 HDA_AMP_MUTE, 0);
cdcd9268
JW
677 }
678 }
a9430dd8
JW
679 return change;
680}
681
4c5186ed 682#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 683 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 684 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
685 .info = alc_pin_mode_info, \
686 .get = alc_pin_mode_get, \
687 .put = alc_pin_mode_put, \
688 .private_value = nid | (dir<<16) }
df694daa 689
5c8f858d
JW
690/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
691 * together using a mask with more than one bit set. This control is
692 * currently used only by the ALC260 test model. At this stage they are not
693 * needed for any "production" models.
694 */
695#ifdef CONFIG_SND_DEBUG
a5ce8890 696#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 697
9c7f852e
TI
698static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
699 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
700{
701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
702 hda_nid_t nid = kcontrol->private_value & 0xffff;
703 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
704 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
705 unsigned int val = snd_hda_codec_read(codec, nid, 0,
706 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
707
708 *valp = (val & mask) != 0;
709 return 0;
710}
9c7f852e
TI
711static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
713{
714 signed int change;
715 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
716 hda_nid_t nid = kcontrol->private_value & 0xffff;
717 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
718 long val = *ucontrol->value.integer.value;
9c7f852e
TI
719 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
720 AC_VERB_GET_GPIO_DATA,
721 0x00);
5c8f858d
JW
722
723 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
724 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
725 if (val == 0)
5c8f858d
JW
726 gpio_data &= ~mask;
727 else
728 gpio_data |= mask;
82beb8fd
TI
729 snd_hda_codec_write_cache(codec, nid, 0,
730 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
731
732 return change;
733}
734#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
735 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
737 .info = alc_gpio_data_info, \
738 .get = alc_gpio_data_get, \
739 .put = alc_gpio_data_put, \
740 .private_value = nid | (mask<<16) }
741#endif /* CONFIG_SND_DEBUG */
742
92621f13
JW
743/* A switch control to allow the enabling of the digital IO pins on the
744 * ALC260. This is incredibly simplistic; the intention of this control is
745 * to provide something in the test model allowing digital outputs to be
746 * identified if present. If models are found which can utilise these
747 * outputs a more complete mixer control can be devised for those models if
748 * necessary.
749 */
750#ifdef CONFIG_SND_DEBUG
a5ce8890 751#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 752
9c7f852e
TI
753static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
754 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
755{
756 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
757 hda_nid_t nid = kcontrol->private_value & 0xffff;
758 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
759 long *valp = ucontrol->value.integer.value;
9c7f852e 760 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 761 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
762
763 *valp = (val & mask) != 0;
764 return 0;
765}
9c7f852e
TI
766static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
767 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
768{
769 signed int change;
770 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
771 hda_nid_t nid = kcontrol->private_value & 0xffff;
772 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
773 long val = *ucontrol->value.integer.value;
9c7f852e 774 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 775 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 776 0x00);
92621f13
JW
777
778 /* Set/unset the masked control bit(s) as needed */
9c7f852e 779 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
780 if (val==0)
781 ctrl_data &= ~mask;
782 else
783 ctrl_data |= mask;
82beb8fd
TI
784 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
785 ctrl_data);
92621f13
JW
786
787 return change;
788}
789#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
790 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 791 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
792 .info = alc_spdif_ctrl_info, \
793 .get = alc_spdif_ctrl_get, \
794 .put = alc_spdif_ctrl_put, \
795 .private_value = nid | (mask<<16) }
796#endif /* CONFIG_SND_DEBUG */
797
f8225f6d
JW
798/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
799 * Again, this is only used in the ALC26x test models to help identify when
800 * the EAPD line must be asserted for features to work.
801 */
802#ifdef CONFIG_SND_DEBUG
803#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
804
805static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
806 struct snd_ctl_elem_value *ucontrol)
807{
808 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
809 hda_nid_t nid = kcontrol->private_value & 0xffff;
810 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
811 long *valp = ucontrol->value.integer.value;
812 unsigned int val = snd_hda_codec_read(codec, nid, 0,
813 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
814
815 *valp = (val & mask) != 0;
816 return 0;
817}
818
819static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
820 struct snd_ctl_elem_value *ucontrol)
821{
822 int change;
823 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
824 hda_nid_t nid = kcontrol->private_value & 0xffff;
825 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
826 long val = *ucontrol->value.integer.value;
827 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
828 AC_VERB_GET_EAPD_BTLENABLE,
829 0x00);
830
831 /* Set/unset the masked control bit(s) as needed */
832 change = (!val ? 0 : mask) != (ctrl_data & mask);
833 if (!val)
834 ctrl_data &= ~mask;
835 else
836 ctrl_data |= mask;
837 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
838 ctrl_data);
839
840 return change;
841}
842
843#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
844 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 845 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
846 .info = alc_eapd_ctrl_info, \
847 .get = alc_eapd_ctrl_get, \
848 .put = alc_eapd_ctrl_put, \
849 .private_value = nid | (mask<<16) }
850#endif /* CONFIG_SND_DEBUG */
851
23f0c048
TI
852/*
853 * set up the input pin config (depending on the given auto-pin type)
854 */
855static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
856 int auto_pin_type)
857{
858 unsigned int val = PIN_IN;
859
86e2959a 860 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 861 unsigned int pincap;
954a29c8
TI
862 unsigned int oldval;
863 oldval = snd_hda_codec_read(codec, nid, 0,
864 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 865 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 866 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
867 /* if the default pin setup is vref50, we give it priority */
868 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 869 val = PIN_VREF80;
461c6c3a
TI
870 else if (pincap & AC_PINCAP_VREF_50)
871 val = PIN_VREF50;
872 else if (pincap & AC_PINCAP_VREF_100)
873 val = PIN_VREF100;
874 else if (pincap & AC_PINCAP_VREF_GRD)
875 val = PIN_VREFGRD;
23f0c048
TI
876 }
877 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
878}
879
f6837bbd
TI
880static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
881{
882 struct alc_spec *spec = codec->spec;
883 struct auto_pin_cfg *cfg = &spec->autocfg;
884
885 if (!cfg->line_outs) {
886 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
887 cfg->line_out_pins[cfg->line_outs])
888 cfg->line_outs++;
889 }
890 if (!cfg->speaker_outs) {
891 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
892 cfg->speaker_pins[cfg->speaker_outs])
893 cfg->speaker_outs++;
894 }
895 if (!cfg->hp_outs) {
896 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
897 cfg->hp_pins[cfg->hp_outs])
898 cfg->hp_outs++;
899 }
900}
901
d88897ea
TI
902/*
903 */
904static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
905{
906 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
907 return;
908 spec->mixers[spec->num_mixers++] = mix;
909}
910
911static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
912{
913 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
914 return;
915 spec->init_verbs[spec->num_init_verbs++] = verb;
916}
917
df694daa
KY
918/*
919 * set up from the preset table
920 */
e9c364c0 921static void setup_preset(struct hda_codec *codec,
9c7f852e 922 const struct alc_config_preset *preset)
df694daa 923{
e9c364c0 924 struct alc_spec *spec = codec->spec;
df694daa
KY
925 int i;
926
927 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 928 add_mixer(spec, preset->mixers[i]);
f9e336f6 929 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
930 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
931 i++)
d88897ea 932 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 933
df694daa
KY
934 spec->channel_mode = preset->channel_mode;
935 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 936 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 937 spec->const_channel_count = preset->const_channel_count;
df694daa 938
3b315d70
HM
939 if (preset->const_channel_count)
940 spec->multiout.max_channels = preset->const_channel_count;
941 else
942 spec->multiout.max_channels = spec->channel_mode[0].channels;
943 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
944
945 spec->multiout.num_dacs = preset->num_dacs;
946 spec->multiout.dac_nids = preset->dac_nids;
947 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 948 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 949 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 950
a1e8d2da 951 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 952 if (!spec->num_mux_defs)
a1e8d2da 953 spec->num_mux_defs = 1;
df694daa
KY
954 spec->input_mux = preset->input_mux;
955
956 spec->num_adc_nids = preset->num_adc_nids;
957 spec->adc_nids = preset->adc_nids;
e1406348 958 spec->capsrc_nids = preset->capsrc_nids;
df694daa 959 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
960
961 spec->unsol_event = preset->unsol_event;
962 spec->init_hook = preset->init_hook;
cb53c626 963#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 964 spec->power_hook = preset->power_hook;
cb53c626
TI
965 spec->loopback.amplist = preset->loopbacks;
966#endif
e9c364c0
TI
967
968 if (preset->setup)
969 preset->setup(codec);
f6837bbd
TI
970
971 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
972}
973
bc9f98a9
KY
974/* Enable GPIO mask and set output */
975static struct hda_verb alc_gpio1_init_verbs[] = {
976 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
977 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
978 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
979 { }
980};
981
982static struct hda_verb alc_gpio2_init_verbs[] = {
983 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
985 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
986 { }
987};
988
bdd148a3
KY
989static struct hda_verb alc_gpio3_init_verbs[] = {
990 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
992 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
993 { }
994};
995
2c3bf9ab
TI
996/*
997 * Fix hardware PLL issue
998 * On some codecs, the analog PLL gating control must be off while
999 * the default value is 1.
1000 */
1001static void alc_fix_pll(struct hda_codec *codec)
1002{
1003 struct alc_spec *spec = codec->spec;
1004 unsigned int val;
1005
1006 if (!spec->pll_nid)
1007 return;
1008 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1009 spec->pll_coef_idx);
1010 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1011 AC_VERB_GET_PROC_COEF, 0);
1012 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1013 spec->pll_coef_idx);
1014 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1015 val & ~(1 << spec->pll_coef_bit));
1016}
1017
1018static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1019 unsigned int coef_idx, unsigned int coef_bit)
1020{
1021 struct alc_spec *spec = codec->spec;
1022 spec->pll_nid = nid;
1023 spec->pll_coef_idx = coef_idx;
1024 spec->pll_coef_bit = coef_bit;
1025 alc_fix_pll(codec);
1026}
1027
9ad0e496
KY
1028#ifdef CONFIG_SND_HDA_INPUT_JACK
1029static void alc_free_jack_priv(struct snd_jack *jack)
1030{
1031 struct alc_jack *jacks = jack->private_data;
1032 jacks->nid = 0;
1033 jacks->jack = NULL;
1034}
1035
1036static int alc_add_jack(struct hda_codec *codec,
1037 hda_nid_t nid, int type)
1038{
1039 struct alc_spec *spec;
1040 struct alc_jack *jack;
1041 const char *name;
1042 int err;
1043
1044 spec = codec->spec;
1045 snd_array_init(&spec->jacks, sizeof(*jack), 32);
1046 jack = snd_array_new(&spec->jacks);
1047 if (!jack)
1048 return -ENOMEM;
1049
1050 jack->nid = nid;
1051 jack->type = type;
1052 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
1053
1054 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
1055 if (err < 0)
1056 return err;
1057 jack->jack->private_data = jack;
1058 jack->jack->private_free = alc_free_jack_priv;
1059 return 0;
1060}
1061
1062static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1063{
1064 struct alc_spec *spec = codec->spec;
1065 struct alc_jack *jacks = spec->jacks.list;
1066
1067 if (jacks) {
1068 int i;
1069 for (i = 0; i < spec->jacks.used; i++) {
1070 if (jacks->nid == nid) {
1071 unsigned int present;
1072 present = snd_hda_jack_detect(codec, nid);
1073
1074 present = (present) ? jacks->type : 0;
1075
1076 snd_jack_report(jacks->jack, present);
1077 }
1078 jacks++;
1079 }
1080 }
1081}
1082
1083static int alc_init_jacks(struct hda_codec *codec)
1084{
1085 struct alc_spec *spec = codec->spec;
1086 int err;
1087 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1088 unsigned int mic_nid = spec->ext_mic.pin;
1089
1090 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE);
1091 if (err < 0)
1092 return err;
1093 alc_report_jack(codec, hp_nid);
1094
1095 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE);
1096 if (err < 0)
1097 return err;
1098 alc_report_jack(codec, mic_nid);
1099
1100 return 0;
1101}
1102#else
1103static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1104{
1105}
1106
1107static inline int alc_init_jacks(struct hda_codec *codec)
1108{
1109 return 0;
1110}
1111#endif
1112
bb35febd 1113static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
c9b58006
KY
1114{
1115 struct alc_spec *spec = codec->spec;
bb35febd
TI
1116 unsigned int mute;
1117 hda_nid_t nid;
a9fd4f3f 1118 int i;
c9b58006 1119
bb35febd
TI
1120 spec->jack_present = 0;
1121 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1122 nid = spec->autocfg.hp_pins[i];
1123 if (!nid)
1124 break;
1125 if (snd_hda_jack_detect(codec, nid)) {
1126 spec->jack_present = 1;
1127 break;
1128 }
9ad0e496 1129 alc_report_jack(codec, spec->autocfg.hp_pins[i]);
bb35febd
TI
1130 }
1131
1132 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1133 /* Toggle internal speakers muting */
a9fd4f3f
TI
1134 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1135 nid = spec->autocfg.speaker_pins[i];
1136 if (!nid)
1137 break;
bb35febd
TI
1138 if (pinctl) {
1139 snd_hda_codec_write(codec, nid, 0,
a9fd4f3f
TI
1140 AC_VERB_SET_PIN_WIDGET_CONTROL,
1141 spec->jack_present ? 0 : PIN_OUT);
bb35febd
TI
1142 } else {
1143 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1144 HDA_AMP_MUTE, mute);
1145 }
a9fd4f3f 1146 }
c9b58006
KY
1147}
1148
bb35febd
TI
1149static void alc_automute_pin(struct hda_codec *codec)
1150{
1151 alc_automute_speaker(codec, 1);
1152}
1153
6c819492
TI
1154static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1155 hda_nid_t nid)
1156{
1157 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1158 int i, nums;
1159
1160 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1161 for (i = 0; i < nums; i++)
1162 if (conn[i] == nid)
1163 return i;
1164 return -1;
1165}
1166
840b64c0
TI
1167/* switch the current ADC according to the jack state */
1168static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1169{
1170 struct alc_spec *spec = codec->spec;
1171 unsigned int present;
1172 hda_nid_t new_adc;
1173
1174 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1175 if (present)
1176 spec->cur_adc_idx = 1;
1177 else
1178 spec->cur_adc_idx = 0;
1179 new_adc = spec->adc_nids[spec->cur_adc_idx];
1180 if (spec->cur_adc && spec->cur_adc != new_adc) {
1181 /* stream is running, let's swap the current ADC */
f0cea797 1182 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1183 spec->cur_adc = new_adc;
1184 snd_hda_codec_setup_stream(codec, new_adc,
1185 spec->cur_adc_stream_tag, 0,
1186 spec->cur_adc_format);
1187 }
1188}
1189
7fb0d78f
KY
1190static void alc_mic_automute(struct hda_codec *codec)
1191{
1192 struct alc_spec *spec = codec->spec;
6c819492
TI
1193 struct alc_mic_route *dead, *alive;
1194 unsigned int present, type;
1195 hda_nid_t cap_nid;
1196
b59bdf3b
TI
1197 if (!spec->auto_mic)
1198 return;
6c819492
TI
1199 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1200 return;
1201 if (snd_BUG_ON(!spec->adc_nids))
1202 return;
1203
840b64c0
TI
1204 if (spec->dual_adc_switch) {
1205 alc_dual_mic_adc_auto_switch(codec);
1206 return;
1207 }
1208
6c819492
TI
1209 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1210
864f92be 1211 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1212 if (present) {
1213 alive = &spec->ext_mic;
1214 dead = &spec->int_mic;
1215 } else {
1216 alive = &spec->int_mic;
1217 dead = &spec->ext_mic;
1218 }
1219
6c819492
TI
1220 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1221 if (type == AC_WID_AUD_MIX) {
1222 /* Matrix-mixer style (e.g. ALC882) */
1223 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1224 alive->mux_idx,
1225 HDA_AMP_MUTE, 0);
1226 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1227 dead->mux_idx,
1228 HDA_AMP_MUTE, HDA_AMP_MUTE);
1229 } else {
1230 /* MUX style (e.g. ALC880) */
1231 snd_hda_codec_write_cache(codec, cap_nid, 0,
1232 AC_VERB_SET_CONNECT_SEL,
1233 alive->mux_idx);
1234 }
9ad0e496 1235 alc_report_jack(codec, spec->ext_mic.pin);
6c819492
TI
1236
1237 /* FIXME: analog mixer */
7fb0d78f
KY
1238}
1239
c9b58006
KY
1240/* unsolicited event for HP jack sensing */
1241static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1242{
1243 if (codec->vendor_id == 0x10ec0880)
1244 res >>= 28;
1245 else
1246 res >>= 26;
a9fd4f3f
TI
1247 switch (res) {
1248 case ALC880_HP_EVENT:
1249 alc_automute_pin(codec);
1250 break;
1251 case ALC880_MIC_EVENT:
7fb0d78f 1252 alc_mic_automute(codec);
a9fd4f3f
TI
1253 break;
1254 }
7fb0d78f
KY
1255}
1256
1257static void alc_inithook(struct hda_codec *codec)
1258{
a9fd4f3f 1259 alc_automute_pin(codec);
7fb0d78f 1260 alc_mic_automute(codec);
c9b58006
KY
1261}
1262
f9423e7a
KY
1263/* additional initialization for ALC888 variants */
1264static void alc888_coef_init(struct hda_codec *codec)
1265{
1266 unsigned int tmp;
1267
1268 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1269 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1270 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1271 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1272 /* alc888S-VC */
1273 snd_hda_codec_read(codec, 0x20, 0,
1274 AC_VERB_SET_PROC_COEF, 0x830);
1275 else
1276 /* alc888-VB */
1277 snd_hda_codec_read(codec, 0x20, 0,
1278 AC_VERB_SET_PROC_COEF, 0x3030);
1279}
1280
87a8c370
JK
1281static void alc889_coef_init(struct hda_codec *codec)
1282{
1283 unsigned int tmp;
1284
1285 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1286 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1287 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1288 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1289}
1290
3fb4a508
TI
1291/* turn on/off EAPD control (only if available) */
1292static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1293{
1294 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1295 return;
1296 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1297 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1298 on ? 2 : 0);
1299}
1300
4a79ba34 1301static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1302{
4a79ba34 1303 unsigned int tmp;
bc9f98a9 1304
4a79ba34
TI
1305 switch (type) {
1306 case ALC_INIT_GPIO1:
bc9f98a9
KY
1307 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1308 break;
4a79ba34 1309 case ALC_INIT_GPIO2:
bc9f98a9
KY
1310 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1311 break;
4a79ba34 1312 case ALC_INIT_GPIO3:
bdd148a3
KY
1313 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1314 break;
4a79ba34 1315 case ALC_INIT_DEFAULT:
bdd148a3 1316 switch (codec->vendor_id) {
c9b58006 1317 case 0x10ec0260:
3fb4a508
TI
1318 set_eapd(codec, 0x0f, 1);
1319 set_eapd(codec, 0x10, 1);
c9b58006
KY
1320 break;
1321 case 0x10ec0262:
bdd148a3
KY
1322 case 0x10ec0267:
1323 case 0x10ec0268:
c9b58006 1324 case 0x10ec0269:
3fb4a508 1325 case 0x10ec0270:
c6e8f2da 1326 case 0x10ec0272:
f9423e7a
KY
1327 case 0x10ec0660:
1328 case 0x10ec0662:
1329 case 0x10ec0663:
c9b58006 1330 case 0x10ec0862:
20a3a05d 1331 case 0x10ec0889:
3fb4a508
TI
1332 set_eapd(codec, 0x14, 1);
1333 set_eapd(codec, 0x15, 1);
c9b58006 1334 break;
bdd148a3 1335 }
c9b58006
KY
1336 switch (codec->vendor_id) {
1337 case 0x10ec0260:
1338 snd_hda_codec_write(codec, 0x1a, 0,
1339 AC_VERB_SET_COEF_INDEX, 7);
1340 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1341 AC_VERB_GET_PROC_COEF, 0);
1342 snd_hda_codec_write(codec, 0x1a, 0,
1343 AC_VERB_SET_COEF_INDEX, 7);
1344 snd_hda_codec_write(codec, 0x1a, 0,
1345 AC_VERB_SET_PROC_COEF,
1346 tmp | 0x2010);
1347 break;
1348 case 0x10ec0262:
1349 case 0x10ec0880:
1350 case 0x10ec0882:
1351 case 0x10ec0883:
1352 case 0x10ec0885:
4a5a4c56 1353 case 0x10ec0887:
20a3a05d 1354 case 0x10ec0889:
87a8c370 1355 alc889_coef_init(codec);
c9b58006 1356 break;
f9423e7a 1357 case 0x10ec0888:
4a79ba34 1358 alc888_coef_init(codec);
f9423e7a 1359 break;
0aea778e 1360#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1361 case 0x10ec0267:
1362 case 0x10ec0268:
1363 snd_hda_codec_write(codec, 0x20, 0,
1364 AC_VERB_SET_COEF_INDEX, 7);
1365 tmp = snd_hda_codec_read(codec, 0x20, 0,
1366 AC_VERB_GET_PROC_COEF, 0);
1367 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1368 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1369 snd_hda_codec_write(codec, 0x20, 0,
1370 AC_VERB_SET_PROC_COEF,
1371 tmp | 0x3000);
1372 break;
0aea778e 1373#endif /* XXX */
bc9f98a9 1374 }
4a79ba34
TI
1375 break;
1376 }
1377}
1378
1379static void alc_init_auto_hp(struct hda_codec *codec)
1380{
1381 struct alc_spec *spec = codec->spec;
bb35febd
TI
1382 struct auto_pin_cfg *cfg = &spec->autocfg;
1383 int i;
4a79ba34 1384
bb35febd
TI
1385 if (!cfg->hp_pins[0]) {
1386 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1387 return;
1388 }
4a79ba34 1389
bb35febd
TI
1390 if (!cfg->speaker_pins[0]) {
1391 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4a79ba34 1392 return;
bb35febd
TI
1393 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1394 sizeof(cfg->speaker_pins));
1395 cfg->speaker_outs = cfg->line_outs;
1396 }
1397
1398 if (!cfg->hp_pins[0]) {
1399 memcpy(cfg->hp_pins, cfg->line_out_pins,
1400 sizeof(cfg->hp_pins));
1401 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1402 }
1403
bb35febd
TI
1404 for (i = 0; i < cfg->hp_outs; i++) {
1405 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1406 cfg->hp_pins[i]);
1407 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
4a79ba34
TI
1408 AC_VERB_SET_UNSOLICITED_ENABLE,
1409 AC_USRSP_EN | ALC880_HP_EVENT);
bb35febd 1410 }
4a79ba34
TI
1411 spec->unsol_event = alc_sku_unsol_event;
1412}
1413
6c819492
TI
1414static void alc_init_auto_mic(struct hda_codec *codec)
1415{
1416 struct alc_spec *spec = codec->spec;
1417 struct auto_pin_cfg *cfg = &spec->autocfg;
1418 hda_nid_t fixed, ext;
1419 int i;
1420
1421 /* there must be only two mic inputs exclusively */
66ceeb6b 1422 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1423 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1424 return;
1425
1426 fixed = ext = 0;
66ceeb6b
TI
1427 for (i = 0; i < cfg->num_inputs; i++) {
1428 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1429 unsigned int defcfg;
6c819492 1430 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1431 switch (snd_hda_get_input_pin_attr(defcfg)) {
1432 case INPUT_PIN_ATTR_INT:
6c819492
TI
1433 if (fixed)
1434 return; /* already occupied */
1435 fixed = nid;
1436 break;
99ae28be
TI
1437 case INPUT_PIN_ATTR_UNUSED:
1438 return; /* invalid entry */
1439 default:
6c819492
TI
1440 if (ext)
1441 return; /* already occupied */
1442 ext = nid;
1443 break;
6c819492
TI
1444 }
1445 }
eaa9b3a7
TI
1446 if (!ext || !fixed)
1447 return;
6c819492
TI
1448 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1449 return; /* no unsol support */
1450 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1451 ext, fixed);
1452 spec->ext_mic.pin = ext;
1453 spec->int_mic.pin = fixed;
1454 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1455 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1456 spec->auto_mic = 1;
1457 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1458 AC_VERB_SET_UNSOLICITED_ENABLE,
1459 AC_USRSP_EN | ALC880_MIC_EVENT);
1460 spec->unsol_event = alc_sku_unsol_event;
1461}
1462
da00c244
KY
1463static int alc_auto_parse_customize_define(struct hda_codec *codec)
1464{
1465 unsigned int ass, tmp, i;
7fb56223 1466 unsigned nid = 0;
da00c244
KY
1467 struct alc_spec *spec = codec->spec;
1468
b6cbe517
TI
1469 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1470
da00c244 1471 ass = codec->subsystem_id & 0xffff;
b6cbe517 1472 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1473 goto do_sku;
1474
1475 nid = 0x1d;
1476 if (codec->vendor_id == 0x10ec0260)
1477 nid = 0x17;
1478 ass = snd_hda_codec_get_pincfg(codec, nid);
1479
1480 if (!(ass & 1)) {
1481 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1482 codec->chip_name, ass);
1483 return -1;
1484 }
1485
1486 /* check sum */
1487 tmp = 0;
1488 for (i = 1; i < 16; i++) {
1489 if ((ass >> i) & 1)
1490 tmp++;
1491 }
1492 if (((ass >> 16) & 0xf) != tmp)
1493 return -1;
1494
1495 spec->cdefine.port_connectivity = ass >> 30;
1496 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1497 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1498 spec->cdefine.customization = ass >> 8;
1499do_sku:
1500 spec->cdefine.sku_cfg = ass;
1501 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1502 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1503 spec->cdefine.swap = (ass & 0x2) >> 1;
1504 spec->cdefine.override = ass & 0x1;
1505
1506 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1507 nid, spec->cdefine.sku_cfg);
1508 snd_printd("SKU: port_connectivity=0x%x\n",
1509 spec->cdefine.port_connectivity);
1510 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1511 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1512 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1513 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1514 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1515 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1516 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1517
1518 return 0;
1519}
1520
4a79ba34
TI
1521/* check subsystem ID and set up device-specific initialization;
1522 * return 1 if initialized, 0 if invalid SSID
1523 */
1524/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1525 * 31 ~ 16 : Manufacture ID
1526 * 15 ~ 8 : SKU ID
1527 * 7 ~ 0 : Assembly ID
1528 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1529 */
1530static int alc_subsystem_id(struct hda_codec *codec,
1531 hda_nid_t porta, hda_nid_t porte,
6227cdce 1532 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1533{
1534 unsigned int ass, tmp, i;
1535 unsigned nid;
1536 struct alc_spec *spec = codec->spec;
1537
1538 ass = codec->subsystem_id & 0xffff;
1539 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1540 goto do_sku;
1541
1542 /* invalid SSID, check the special NID pin defcfg instead */
1543 /*
def319f9 1544 * 31~30 : port connectivity
4a79ba34
TI
1545 * 29~21 : reserve
1546 * 20 : PCBEEP input
1547 * 19~16 : Check sum (15:1)
1548 * 15~1 : Custom
1549 * 0 : override
1550 */
1551 nid = 0x1d;
1552 if (codec->vendor_id == 0x10ec0260)
1553 nid = 0x17;
1554 ass = snd_hda_codec_get_pincfg(codec, nid);
1555 snd_printd("realtek: No valid SSID, "
1556 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1557 ass, nid);
6227cdce 1558 if (!(ass & 1))
4a79ba34
TI
1559 return 0;
1560 if ((ass >> 30) != 1) /* no physical connection */
1561 return 0;
1562
1563 /* check sum */
1564 tmp = 0;
1565 for (i = 1; i < 16; i++) {
1566 if ((ass >> i) & 1)
1567 tmp++;
1568 }
1569 if (((ass >> 16) & 0xf) != tmp)
1570 return 0;
1571do_sku:
1572 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1573 ass & 0xffff, codec->vendor_id);
1574 /*
1575 * 0 : override
1576 * 1 : Swap Jack
1577 * 2 : 0 --> Desktop, 1 --> Laptop
1578 * 3~5 : External Amplifier control
1579 * 7~6 : Reserved
1580 */
1581 tmp = (ass & 0x38) >> 3; /* external Amp control */
1582 switch (tmp) {
1583 case 1:
1584 spec->init_amp = ALC_INIT_GPIO1;
1585 break;
1586 case 3:
1587 spec->init_amp = ALC_INIT_GPIO2;
1588 break;
1589 case 7:
1590 spec->init_amp = ALC_INIT_GPIO3;
1591 break;
1592 case 5:
1593 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1594 break;
1595 }
ea1fb29a 1596
8c427226 1597 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1598 * when the external headphone out jack is plugged"
1599 */
8c427226 1600 if (!(ass & 0x8000))
4a79ba34 1601 return 1;
c9b58006
KY
1602 /*
1603 * 10~8 : Jack location
1604 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1605 * 14~13: Resvered
1606 * 15 : 1 --> enable the function "Mute internal speaker
1607 * when the external headphone out jack is plugged"
1608 */
c9b58006 1609 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1610 hda_nid_t nid;
c9b58006
KY
1611 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1612 if (tmp == 0)
01d4825d 1613 nid = porta;
c9b58006 1614 else if (tmp == 1)
01d4825d 1615 nid = porte;
c9b58006 1616 else if (tmp == 2)
01d4825d 1617 nid = portd;
6227cdce
KY
1618 else if (tmp == 3)
1619 nid = porti;
c9b58006 1620 else
4a79ba34 1621 return 1;
01d4825d
TI
1622 for (i = 0; i < spec->autocfg.line_outs; i++)
1623 if (spec->autocfg.line_out_pins[i] == nid)
1624 return 1;
1625 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1626 }
1627
4a79ba34 1628 alc_init_auto_hp(codec);
6c819492 1629 alc_init_auto_mic(codec);
4a79ba34
TI
1630 return 1;
1631}
ea1fb29a 1632
4a79ba34 1633static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1634 hda_nid_t porta, hda_nid_t porte,
1635 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1636{
6227cdce 1637 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1638 struct alc_spec *spec = codec->spec;
1639 snd_printd("realtek: "
1640 "Enable default setup for auto mode as fallback\n");
1641 spec->init_amp = ALC_INIT_DEFAULT;
1642 alc_init_auto_hp(codec);
6c819492 1643 alc_init_auto_mic(codec);
4a79ba34 1644 }
bc9f98a9
KY
1645}
1646
f95474ec 1647/*
f8f25ba3 1648 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1649 */
1650
1651struct alc_pincfg {
1652 hda_nid_t nid;
1653 u32 val;
1654};
1655
f8f25ba3
TI
1656struct alc_fixup {
1657 const struct alc_pincfg *pins;
1658 const struct hda_verb *verbs;
1659};
1660
1661static void alc_pick_fixup(struct hda_codec *codec,
f95474ec 1662 const struct snd_pci_quirk *quirk,
7fa90e87
TI
1663 const struct alc_fixup *fix,
1664 int pre_init)
f95474ec
TI
1665{
1666 const struct alc_pincfg *cfg;
1667
1668 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1669 if (!quirk)
1670 return;
f8f25ba3
TI
1671 fix += quirk->value;
1672 cfg = fix->pins;
7fa90e87
TI
1673 if (pre_init && cfg) {
1674#ifdef CONFIG_SND_DEBUG_VERBOSE
1675 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1676 codec->chip_name, quirk->name);
1677#endif
f8f25ba3
TI
1678 for (; cfg->nid; cfg++)
1679 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1680 }
7fa90e87
TI
1681 if (!pre_init && fix->verbs) {
1682#ifdef CONFIG_SND_DEBUG_VERBOSE
1683 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1684 codec->chip_name, quirk->name);
1685#endif
f8f25ba3 1686 add_verb(codec->spec, fix->verbs);
7fa90e87 1687 }
f95474ec
TI
1688}
1689
274693f3
KY
1690static int alc_read_coef_idx(struct hda_codec *codec,
1691 unsigned int coef_idx)
1692{
1693 unsigned int val;
1694 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1695 coef_idx);
1696 val = snd_hda_codec_read(codec, 0x20, 0,
1697 AC_VERB_GET_PROC_COEF, 0);
1698 return val;
1699}
1700
977ddd6b
KY
1701static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1702 unsigned int coef_val)
1703{
1704 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1705 coef_idx);
1706 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1707 coef_val);
1708}
1709
757899ac
TI
1710/* set right pin controls for digital I/O */
1711static void alc_auto_init_digital(struct hda_codec *codec)
1712{
1713 struct alc_spec *spec = codec->spec;
1714 int i;
1715 hda_nid_t pin;
1716
1717 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1718 pin = spec->autocfg.dig_out_pins[i];
1719 if (pin) {
1720 snd_hda_codec_write(codec, pin, 0,
1721 AC_VERB_SET_PIN_WIDGET_CONTROL,
1722 PIN_OUT);
1723 }
1724 }
1725 pin = spec->autocfg.dig_in_pin;
1726 if (pin)
1727 snd_hda_codec_write(codec, pin, 0,
1728 AC_VERB_SET_PIN_WIDGET_CONTROL,
1729 PIN_IN);
1730}
1731
1732/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1733static void alc_auto_parse_digital(struct hda_codec *codec)
1734{
1735 struct alc_spec *spec = codec->spec;
1736 int i, err;
1737 hda_nid_t dig_nid;
1738
1739 /* support multiple SPDIFs; the secondary is set up as a slave */
1740 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1741 err = snd_hda_get_connections(codec,
1742 spec->autocfg.dig_out_pins[i],
1743 &dig_nid, 1);
1744 if (err < 0)
1745 continue;
1746 if (!i) {
1747 spec->multiout.dig_out_nid = dig_nid;
1748 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1749 } else {
1750 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1751 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1752 break;
1753 spec->slave_dig_outs[i - 1] = dig_nid;
1754 }
1755 }
1756
1757 if (spec->autocfg.dig_in_pin) {
1758 hda_nid_t dig_nid;
1759 err = snd_hda_get_connections(codec,
1760 spec->autocfg.dig_in_pin,
1761 &dig_nid, 1);
1762 if (err > 0)
1763 spec->dig_in_nid = dig_nid;
1764 }
1765}
1766
ef8ef5fb
VP
1767/*
1768 * ALC888
1769 */
1770
1771/*
1772 * 2ch mode
1773 */
1774static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1775/* Mic-in jack as mic in */
1776 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1777 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1778/* Line-in jack as Line in */
1779 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1780 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1781/* Line-Out as Front */
1782 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1783 { } /* end */
1784};
1785
1786/*
1787 * 4ch mode
1788 */
1789static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1790/* Mic-in jack as mic in */
1791 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1792 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1793/* Line-in jack as Surround */
1794 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1795 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1796/* Line-Out as Front */
1797 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1798 { } /* end */
1799};
1800
1801/*
1802 * 6ch mode
1803 */
1804static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1805/* Mic-in jack as CLFE */
1806 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1807 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1808/* Line-in jack as Surround */
1809 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1810 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1811/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1812 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1813 { } /* end */
1814};
1815
1816/*
1817 * 8ch mode
1818 */
1819static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1820/* Mic-in jack as CLFE */
1821 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1822 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1823/* Line-in jack as Surround */
1824 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1825 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1826/* Line-Out as Side */
1827 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1828 { } /* end */
1829};
1830
1831static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1832 { 2, alc888_4ST_ch2_intel_init },
1833 { 4, alc888_4ST_ch4_intel_init },
1834 { 6, alc888_4ST_ch6_intel_init },
1835 { 8, alc888_4ST_ch8_intel_init },
1836};
1837
1838/*
1839 * ALC888 Fujitsu Siemens Amillo xa3530
1840 */
1841
1842static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1843/* Front Mic: set to PIN_IN (empty by default) */
1844 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1845/* Connect Internal HP to Front */
1846 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1847 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1848 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1849/* Connect Bass HP to Front */
1850 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1852 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1853/* Connect Line-Out side jack (SPDIF) to Side */
1854 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1855 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1856 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1857/* Connect Mic jack to CLFE */
1858 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1859 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1860 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1861/* Connect Line-in jack to Surround */
1862 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1863 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1864 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1865/* Connect HP out jack to Front */
1866 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1867 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1868 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1869/* Enable unsolicited event for HP jack and Line-out jack */
1870 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1871 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1872 {}
1873};
1874
a9fd4f3f 1875static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1876{
bb35febd 1877 alc_automute_speaker(codec, 0);
ef8ef5fb
VP
1878}
1879
a9fd4f3f
TI
1880static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1881 unsigned int res)
ef8ef5fb 1882{
a9fd4f3f
TI
1883 if (codec->vendor_id == 0x10ec0880)
1884 res >>= 28;
1885 else
1886 res >>= 26;
1887 if (res == ALC880_HP_EVENT)
1888 alc_automute_amp(codec);
ef8ef5fb
VP
1889}
1890
4f5d1706 1891static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1892{
1893 struct alc_spec *spec = codec->spec;
1894
1895 spec->autocfg.hp_pins[0] = 0x15;
1896 spec->autocfg.speaker_pins[0] = 0x14;
1897 spec->autocfg.speaker_pins[1] = 0x16;
1898 spec->autocfg.speaker_pins[2] = 0x17;
1899 spec->autocfg.speaker_pins[3] = 0x19;
1900 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1901}
1902
1903static void alc889_intel_init_hook(struct hda_codec *codec)
1904{
1905 alc889_coef_init(codec);
4f5d1706 1906 alc_automute_amp(codec);
6732bd0d
WF
1907}
1908
4f5d1706 1909static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1910{
1911 struct alc_spec *spec = codec->spec;
1912
1913 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1914 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1915 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1916 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1917}
ef8ef5fb 1918
5b2d1eca
VP
1919/*
1920 * ALC888 Acer Aspire 4930G model
1921 */
1922
1923static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1924/* Front Mic: set to PIN_IN (empty by default) */
1925 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1926/* Unselect Front Mic by default in input mixer 3 */
1927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1928/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1929 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1930/* Connect Internal HP to front */
1931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1932 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1933 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1934/* Connect HP out to front */
1935 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1936 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1937 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1938 { }
1939};
1940
d2fd4b09
TV
1941/*
1942 * ALC888 Acer Aspire 6530G model
1943 */
1944
1945static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
1946/* Route to built-in subwoofer as well as speakers */
1947 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1948 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1949 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1950 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
1951/* Bias voltage on for external mic port */
1952 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1953/* Front Mic: set to PIN_IN (empty by default) */
1954 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1955/* Unselect Front Mic by default in input mixer 3 */
1956 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1957/* Enable unsolicited event for HP jack */
1958 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1959/* Enable speaker output */
1960 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1961 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 1962 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1963/* Enable headphone output */
1964 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1965 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1966 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 1967 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1968 { }
1969};
1970
3b315d70 1971/*
018df418 1972 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1973 */
1974
018df418 1975static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1976/* Front Mic: set to PIN_IN (empty by default) */
1977 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1978/* Unselect Front Mic by default in input mixer 3 */
1979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1980/* Enable unsolicited event for HP jack */
1981 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1982/* Connect Internal Front to Front */
1983 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1985 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1986/* Connect Internal Rear to Rear */
1987 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1988 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1989 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1990/* Connect Internal CLFE to CLFE */
1991 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1992 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1993 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1994/* Connect HP out to Front */
018df418 1995 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1996 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1997 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1998/* Enable all DACs */
1999/* DAC DISABLE/MUTE 1? */
2000/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2001 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2002 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2003/* DAC DISABLE/MUTE 2? */
2004/* some bit here disables the other DACs. Init=0x4900 */
2005 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2006 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2007/* DMIC fix
2008 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2009 * which makes the stereo useless. However, either the mic or the ALC889
2010 * makes the signal become a difference/sum signal instead of standard
2011 * stereo, which is annoying. So instead we flip this bit which makes the
2012 * codec replicate the sum signal to both channels, turning it into a
2013 * normal mono mic.
2014 */
2015/* DMIC_CONTROL? Init value = 0x0001 */
2016 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2017 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2018 { }
2019};
2020
ef8ef5fb 2021static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2022 /* Front mic only available on one ADC */
2023 {
2024 .num_items = 4,
2025 .items = {
2026 { "Mic", 0x0 },
2027 { "Line", 0x2 },
2028 { "CD", 0x4 },
2029 { "Front Mic", 0xb },
2030 },
2031 },
2032 {
2033 .num_items = 3,
2034 .items = {
2035 { "Mic", 0x0 },
2036 { "Line", 0x2 },
2037 { "CD", 0x4 },
2038 },
2039 }
2040};
2041
d2fd4b09
TV
2042static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2043 /* Interal mic only available on one ADC */
2044 {
684a8842 2045 .num_items = 5,
d2fd4b09
TV
2046 .items = {
2047 { "Ext Mic", 0x0 },
684a8842 2048 { "Line In", 0x2 },
d2fd4b09 2049 { "CD", 0x4 },
684a8842 2050 { "Input Mix", 0xa },
d2fd4b09
TV
2051 { "Int Mic", 0xb },
2052 },
2053 },
2054 {
684a8842 2055 .num_items = 4,
d2fd4b09
TV
2056 .items = {
2057 { "Ext Mic", 0x0 },
684a8842 2058 { "Line In", 0x2 },
d2fd4b09 2059 { "CD", 0x4 },
684a8842 2060 { "Input Mix", 0xa },
d2fd4b09
TV
2061 },
2062 }
2063};
2064
018df418
HM
2065static struct hda_input_mux alc889_capture_sources[3] = {
2066 /* Digital mic only available on first "ADC" */
2067 {
2068 .num_items = 5,
2069 .items = {
2070 { "Mic", 0x0 },
2071 { "Line", 0x2 },
2072 { "CD", 0x4 },
2073 { "Front Mic", 0xb },
2074 { "Input Mix", 0xa },
2075 },
2076 },
2077 {
2078 .num_items = 4,
2079 .items = {
2080 { "Mic", 0x0 },
2081 { "Line", 0x2 },
2082 { "CD", 0x4 },
2083 { "Input Mix", 0xa },
2084 },
2085 },
2086 {
2087 .num_items = 4,
2088 .items = {
2089 { "Mic", 0x0 },
2090 { "Line", 0x2 },
2091 { "CD", 0x4 },
2092 { "Input Mix", 0xa },
2093 },
2094 }
2095};
2096
ef8ef5fb 2097static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2098 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2099 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2100 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2101 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2102 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2103 HDA_OUTPUT),
2104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2107 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2108 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2109 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2110 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2111 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2112 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2114 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
2115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2116 { } /* end */
2117};
2118
556eea9a
HM
2119static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2120 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2121 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2122 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2123 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2124 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2125 HDA_OUTPUT),
2126 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2127 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2128 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2130 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2132 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
2133 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2134 { } /* end */
2135};
2136
2137
4f5d1706 2138static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2139{
a9fd4f3f 2140 struct alc_spec *spec = codec->spec;
5b2d1eca 2141
a9fd4f3f
TI
2142 spec->autocfg.hp_pins[0] = 0x15;
2143 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2144 spec->autocfg.speaker_pins[1] = 0x16;
2145 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2146}
2147
4f5d1706 2148static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2149{
2150 struct alc_spec *spec = codec->spec;
2151
2152 spec->autocfg.hp_pins[0] = 0x15;
2153 spec->autocfg.speaker_pins[0] = 0x14;
2154 spec->autocfg.speaker_pins[1] = 0x16;
2155 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2156}
2157
4f5d1706 2158static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2159{
2160 struct alc_spec *spec = codec->spec;
2161
2162 spec->autocfg.hp_pins[0] = 0x15;
2163 spec->autocfg.speaker_pins[0] = 0x14;
2164 spec->autocfg.speaker_pins[1] = 0x16;
2165 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2166}
2167
1da177e4 2168/*
e9edcee0
TI
2169 * ALC880 3-stack model
2170 *
2171 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2172 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2173 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2174 */
2175
e9edcee0
TI
2176static hda_nid_t alc880_dac_nids[4] = {
2177 /* front, rear, clfe, rear_surr */
2178 0x02, 0x05, 0x04, 0x03
2179};
2180
2181static hda_nid_t alc880_adc_nids[3] = {
2182 /* ADC0-2 */
2183 0x07, 0x08, 0x09,
2184};
2185
2186/* The datasheet says the node 0x07 is connected from inputs,
2187 * but it shows zero connection in the real implementation on some devices.
df694daa 2188 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2189 */
e9edcee0
TI
2190static hda_nid_t alc880_adc_nids_alt[2] = {
2191 /* ADC1-2 */
2192 0x08, 0x09,
2193};
2194
2195#define ALC880_DIGOUT_NID 0x06
2196#define ALC880_DIGIN_NID 0x0a
2197
2198static struct hda_input_mux alc880_capture_source = {
2199 .num_items = 4,
2200 .items = {
2201 { "Mic", 0x0 },
2202 { "Front Mic", 0x3 },
2203 { "Line", 0x2 },
2204 { "CD", 0x4 },
2205 },
2206};
2207
2208/* channel source setting (2/6 channel selection for 3-stack) */
2209/* 2ch mode */
2210static struct hda_verb alc880_threestack_ch2_init[] = {
2211 /* set line-in to input, mute it */
2212 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2213 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2214 /* set mic-in to input vref 80%, mute it */
2215 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2216 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2217 { } /* end */
2218};
2219
2220/* 6ch mode */
2221static struct hda_verb alc880_threestack_ch6_init[] = {
2222 /* set line-in to output, unmute it */
2223 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2224 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2225 /* set mic-in to output, unmute it */
2226 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2227 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2228 { } /* end */
2229};
2230
d2a6d7dc 2231static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2232 { 2, alc880_threestack_ch2_init },
2233 { 6, alc880_threestack_ch6_init },
2234};
2235
c8b6bf9b 2236static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2237 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2238 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2239 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2240 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2241 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2242 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2243 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2244 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2245 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2246 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2247 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2248 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2251 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2252 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2253 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2254 {
2255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2256 .name = "Channel Mode",
df694daa
KY
2257 .info = alc_ch_mode_info,
2258 .get = alc_ch_mode_get,
2259 .put = alc_ch_mode_put,
e9edcee0
TI
2260 },
2261 { } /* end */
2262};
2263
2264/* capture mixer elements */
f9e336f6
TI
2265static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2266 struct snd_ctl_elem_info *uinfo)
2267{
2268 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2269 struct alc_spec *spec = codec->spec;
2270 int err;
1da177e4 2271
5a9e02e9 2272 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2273 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2274 HDA_INPUT);
2275 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2276 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2277 return err;
2278}
2279
2280static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2281 unsigned int size, unsigned int __user *tlv)
2282{
2283 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2284 struct alc_spec *spec = codec->spec;
2285 int err;
1da177e4 2286
5a9e02e9 2287 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2288 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2289 HDA_INPUT);
2290 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2291 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2292 return err;
2293}
2294
2295typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2296 struct snd_ctl_elem_value *ucontrol);
2297
2298static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2299 struct snd_ctl_elem_value *ucontrol,
2300 getput_call_t func)
2301{
2302 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2303 struct alc_spec *spec = codec->spec;
2304 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2305 int err;
2306
5a9e02e9 2307 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2308 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2309 3, 0, HDA_INPUT);
2310 err = func(kcontrol, ucontrol);
5a9e02e9 2311 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2312 return err;
2313}
2314
2315static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2316 struct snd_ctl_elem_value *ucontrol)
2317{
2318 return alc_cap_getput_caller(kcontrol, ucontrol,
2319 snd_hda_mixer_amp_volume_get);
2320}
2321
2322static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2323 struct snd_ctl_elem_value *ucontrol)
2324{
2325 return alc_cap_getput_caller(kcontrol, ucontrol,
2326 snd_hda_mixer_amp_volume_put);
2327}
2328
2329/* capture mixer elements */
2330#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2331
2332static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2333 struct snd_ctl_elem_value *ucontrol)
2334{
2335 return alc_cap_getput_caller(kcontrol, ucontrol,
2336 snd_hda_mixer_amp_switch_get);
2337}
2338
2339static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2340 struct snd_ctl_elem_value *ucontrol)
2341{
2342 return alc_cap_getput_caller(kcontrol, ucontrol,
2343 snd_hda_mixer_amp_switch_put);
2344}
2345
a23b688f 2346#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2347 { \
2348 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2349 .name = "Capture Switch", \
2350 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2351 .count = num, \
2352 .info = alc_cap_sw_info, \
2353 .get = alc_cap_sw_get, \
2354 .put = alc_cap_sw_put, \
2355 }, \
2356 { \
2357 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2358 .name = "Capture Volume", \
2359 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2360 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2361 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2362 .count = num, \
2363 .info = alc_cap_vol_info, \
2364 .get = alc_cap_vol_get, \
2365 .put = alc_cap_vol_put, \
2366 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2367 }
2368
2369#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2370 { \
2371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2372 /* .name = "Capture Source", */ \
2373 .name = "Input Source", \
2374 .count = num, \
2375 .info = alc_mux_enum_info, \
2376 .get = alc_mux_enum_get, \
2377 .put = alc_mux_enum_put, \
a23b688f
TI
2378 }
2379
2380#define DEFINE_CAPMIX(num) \
2381static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2382 _DEFINE_CAPMIX(num), \
2383 _DEFINE_CAPSRC(num), \
2384 { } /* end */ \
2385}
2386
2387#define DEFINE_CAPMIX_NOSRC(num) \
2388static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2389 _DEFINE_CAPMIX(num), \
2390 { } /* end */ \
f9e336f6
TI
2391}
2392
2393/* up to three ADCs */
2394DEFINE_CAPMIX(1);
2395DEFINE_CAPMIX(2);
2396DEFINE_CAPMIX(3);
a23b688f
TI
2397DEFINE_CAPMIX_NOSRC(1);
2398DEFINE_CAPMIX_NOSRC(2);
2399DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2400
2401/*
2402 * ALC880 5-stack model
2403 *
9c7f852e
TI
2404 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2405 * Side = 0x02 (0xd)
e9edcee0
TI
2406 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2407 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2408 */
2409
2410/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2411static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2412 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2413 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2414 { } /* end */
2415};
2416
e9edcee0
TI
2417/* channel source setting (6/8 channel selection for 5-stack) */
2418/* 6ch mode */
2419static struct hda_verb alc880_fivestack_ch6_init[] = {
2420 /* set line-in to input, mute it */
2421 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2422 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2423 { } /* end */
2424};
2425
e9edcee0
TI
2426/* 8ch mode */
2427static struct hda_verb alc880_fivestack_ch8_init[] = {
2428 /* set line-in to output, unmute it */
2429 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2430 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2431 { } /* end */
2432};
2433
d2a6d7dc 2434static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2435 { 6, alc880_fivestack_ch6_init },
2436 { 8, alc880_fivestack_ch8_init },
2437};
2438
2439
2440/*
2441 * ALC880 6-stack model
2442 *
9c7f852e
TI
2443 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2444 * Side = 0x05 (0x0f)
e9edcee0
TI
2445 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2446 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2447 */
2448
2449static hda_nid_t alc880_6st_dac_nids[4] = {
2450 /* front, rear, clfe, rear_surr */
2451 0x02, 0x03, 0x04, 0x05
f12ab1e0 2452};
e9edcee0
TI
2453
2454static struct hda_input_mux alc880_6stack_capture_source = {
2455 .num_items = 4,
2456 .items = {
2457 { "Mic", 0x0 },
2458 { "Front Mic", 0x1 },
2459 { "Line", 0x2 },
2460 { "CD", 0x4 },
2461 },
2462};
2463
2464/* fixed 8-channels */
d2a6d7dc 2465static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2466 { 8, NULL },
2467};
2468
c8b6bf9b 2469static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2470 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2471 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2472 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2473 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2474 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2475 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2476 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2477 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2478 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2479 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2480 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2481 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2482 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2483 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2485 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2486 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2487 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2488 {
2489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2490 .name = "Channel Mode",
df694daa
KY
2491 .info = alc_ch_mode_info,
2492 .get = alc_ch_mode_get,
2493 .put = alc_ch_mode_put,
16ded525
TI
2494 },
2495 { } /* end */
2496};
2497
e9edcee0
TI
2498
2499/*
2500 * ALC880 W810 model
2501 *
2502 * W810 has rear IO for:
2503 * Front (DAC 02)
2504 * Surround (DAC 03)
2505 * Center/LFE (DAC 04)
2506 * Digital out (06)
2507 *
2508 * The system also has a pair of internal speakers, and a headphone jack.
2509 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2510 *
e9edcee0
TI
2511 * There is a variable resistor to control the speaker or headphone
2512 * volume. This is a hardware-only device without a software API.
2513 *
2514 * Plugging headphones in will disable the internal speakers. This is
2515 * implemented in hardware, not via the driver using jack sense. In
2516 * a similar fashion, plugging into the rear socket marked "front" will
2517 * disable both the speakers and headphones.
2518 *
2519 * For input, there's a microphone jack, and an "audio in" jack.
2520 * These may not do anything useful with this driver yet, because I
2521 * haven't setup any initialization verbs for these yet...
2522 */
2523
2524static hda_nid_t alc880_w810_dac_nids[3] = {
2525 /* front, rear/surround, clfe */
2526 0x02, 0x03, 0x04
16ded525
TI
2527};
2528
e9edcee0 2529/* fixed 6 channels */
d2a6d7dc 2530static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2531 { 6, NULL }
2532};
2533
2534/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2535static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2536 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2537 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2538 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2539 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2540 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2541 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2542 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2543 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2544 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2545 { } /* end */
2546};
2547
2548
2549/*
2550 * Z710V model
2551 *
2552 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2553 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2554 * Line = 0x1a
e9edcee0
TI
2555 */
2556
2557static hda_nid_t alc880_z71v_dac_nids[1] = {
2558 0x02
2559};
2560#define ALC880_Z71V_HP_DAC 0x03
2561
2562/* fixed 2 channels */
d2a6d7dc 2563static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2564 { 2, NULL }
2565};
2566
c8b6bf9b 2567static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2568 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2569 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2570 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2571 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2572 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2573 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2575 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2576 { } /* end */
2577};
2578
e9edcee0 2579
e9edcee0
TI
2580/*
2581 * ALC880 F1734 model
2582 *
2583 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2584 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2585 */
2586
2587static hda_nid_t alc880_f1734_dac_nids[1] = {
2588 0x03
2589};
2590#define ALC880_F1734_HP_DAC 0x02
2591
c8b6bf9b 2592static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2593 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2594 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2595 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2596 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2597 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2598 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2599 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2600 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2601 { } /* end */
2602};
2603
937b4160
TI
2604static struct hda_input_mux alc880_f1734_capture_source = {
2605 .num_items = 2,
2606 .items = {
2607 { "Mic", 0x1 },
2608 { "CD", 0x4 },
2609 },
2610};
2611
e9edcee0 2612
e9edcee0
TI
2613/*
2614 * ALC880 ASUS model
2615 *
2616 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2617 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2618 * Mic = 0x18, Line = 0x1a
2619 */
2620
2621#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2622#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2623
c8b6bf9b 2624static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2625 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2626 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2627 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2628 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2629 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2630 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2631 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2632 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2633 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2634 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2635 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2636 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2639 {
2640 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2641 .name = "Channel Mode",
df694daa
KY
2642 .info = alc_ch_mode_info,
2643 .get = alc_ch_mode_get,
2644 .put = alc_ch_mode_put,
16ded525
TI
2645 },
2646 { } /* end */
2647};
e9edcee0 2648
e9edcee0
TI
2649/*
2650 * ALC880 ASUS W1V model
2651 *
2652 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2653 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2654 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2655 */
2656
2657/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2658static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2659 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2660 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2661 { } /* end */
2662};
2663
df694daa
KY
2664/* TCL S700 */
2665static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2666 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2667 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2668 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2669 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2670 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2673 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2674 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2675 { } /* end */
2676};
2677
ccc656ce
KY
2678/* Uniwill */
2679static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2680 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2681 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2682 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2683 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2684 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2685 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2686 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2687 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2688 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2689 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2690 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2691 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2693 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2694 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2695 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2696 {
2697 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2698 .name = "Channel Mode",
2699 .info = alc_ch_mode_info,
2700 .get = alc_ch_mode_get,
2701 .put = alc_ch_mode_put,
2702 },
2703 { } /* end */
2704};
2705
2cf9f0fc
TD
2706static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2707 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2708 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2709 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2710 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2711 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2712 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2713 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2714 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2715 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2716 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2717 { } /* end */
2718};
2719
ccc656ce 2720static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2721 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2722 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2723 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2724 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2725 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2726 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2727 { } /* end */
2728};
2729
2134ea4f
TI
2730/*
2731 * virtual master controls
2732 */
2733
2734/*
2735 * slave controls for virtual master
2736 */
2737static const char *alc_slave_vols[] = {
2738 "Front Playback Volume",
2739 "Surround Playback Volume",
2740 "Center Playback Volume",
2741 "LFE Playback Volume",
2742 "Side Playback Volume",
2743 "Headphone Playback Volume",
2744 "Speaker Playback Volume",
2745 "Mono Playback Volume",
2134ea4f 2746 "Line-Out Playback Volume",
26f5df26 2747 "PCM Playback Volume",
2134ea4f
TI
2748 NULL,
2749};
2750
2751static const char *alc_slave_sws[] = {
2752 "Front Playback Switch",
2753 "Surround Playback Switch",
2754 "Center Playback Switch",
2755 "LFE Playback Switch",
2756 "Side Playback Switch",
2757 "Headphone Playback Switch",
2758 "Speaker Playback Switch",
2759 "Mono Playback Switch",
edb54a55 2760 "IEC958 Playback Switch",
23033b2b
TI
2761 "Line-Out Playback Switch",
2762 "PCM Playback Switch",
2134ea4f
TI
2763 NULL,
2764};
2765
1da177e4 2766/*
e9edcee0 2767 * build control elements
1da177e4 2768 */
603c4019 2769
5b0cb1d8
JK
2770#define NID_MAPPING (-1)
2771
2772#define SUBDEV_SPEAKER_ (0 << 6)
2773#define SUBDEV_HP_ (1 << 6)
2774#define SUBDEV_LINE_ (2 << 6)
2775#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2776#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2777#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2778
603c4019
TI
2779static void alc_free_kctls(struct hda_codec *codec);
2780
67d634c0 2781#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2782/* additional beep mixers; the actual parameters are overwritten at build */
2783static struct snd_kcontrol_new alc_beep_mixer[] = {
2784 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2785 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2786 { } /* end */
2787};
67d634c0 2788#endif
45bdd1c1 2789
1da177e4
LT
2790static int alc_build_controls(struct hda_codec *codec)
2791{
2792 struct alc_spec *spec = codec->spec;
2f44f847 2793 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2794 struct snd_kcontrol_new *knew;
2795 int i, j, err;
2796 unsigned int u;
2797 hda_nid_t nid;
1da177e4
LT
2798
2799 for (i = 0; i < spec->num_mixers; i++) {
2800 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2801 if (err < 0)
2802 return err;
2803 }
f9e336f6
TI
2804 if (spec->cap_mixer) {
2805 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2806 if (err < 0)
2807 return err;
2808 }
1da177e4 2809 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2810 err = snd_hda_create_spdif_out_ctls(codec,
2811 spec->multiout.dig_out_nid);
1da177e4
LT
2812 if (err < 0)
2813 return err;
e64f14f4
TI
2814 if (!spec->no_analog) {
2815 err = snd_hda_create_spdif_share_sw(codec,
2816 &spec->multiout);
2817 if (err < 0)
2818 return err;
2819 spec->multiout.share_spdif = 1;
2820 }
1da177e4
LT
2821 }
2822 if (spec->dig_in_nid) {
2823 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2824 if (err < 0)
2825 return err;
2826 }
2134ea4f 2827
67d634c0 2828#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2829 /* create beep controls if needed */
2830 if (spec->beep_amp) {
2831 struct snd_kcontrol_new *knew;
2832 for (knew = alc_beep_mixer; knew->name; knew++) {
2833 struct snd_kcontrol *kctl;
2834 kctl = snd_ctl_new1(knew, codec);
2835 if (!kctl)
2836 return -ENOMEM;
2837 kctl->private_value = spec->beep_amp;
5e26dfd0 2838 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2839 if (err < 0)
2840 return err;
2841 }
2842 }
67d634c0 2843#endif
45bdd1c1 2844
2134ea4f 2845 /* if we have no master control, let's create it */
e64f14f4
TI
2846 if (!spec->no_analog &&
2847 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2848 unsigned int vmaster_tlv[4];
2134ea4f 2849 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2850 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2851 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2852 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2853 if (err < 0)
2854 return err;
2855 }
e64f14f4
TI
2856 if (!spec->no_analog &&
2857 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2858 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2859 NULL, alc_slave_sws);
2860 if (err < 0)
2861 return err;
2862 }
2863
5b0cb1d8 2864 /* assign Capture Source enums to NID */
fbe618f2
TI
2865 if (spec->capsrc_nids || spec->adc_nids) {
2866 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2867 if (!kctl)
2868 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2869 for (i = 0; kctl && i < kctl->count; i++) {
2870 hda_nid_t *nids = spec->capsrc_nids;
2871 if (!nids)
2872 nids = spec->adc_nids;
2873 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2874 if (err < 0)
2875 return err;
2876 }
5b0cb1d8
JK
2877 }
2878 if (spec->cap_mixer) {
2879 const char *kname = kctl ? kctl->id.name : NULL;
2880 for (knew = spec->cap_mixer; knew->name; knew++) {
2881 if (kname && strcmp(knew->name, kname) == 0)
2882 continue;
2883 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2884 for (i = 0; kctl && i < kctl->count; i++) {
2885 err = snd_hda_add_nid(codec, kctl, i,
2886 spec->adc_nids[i]);
2887 if (err < 0)
2888 return err;
2889 }
2890 }
2891 }
2892
2893 /* other nid->control mapping */
2894 for (i = 0; i < spec->num_mixers; i++) {
2895 for (knew = spec->mixers[i]; knew->name; knew++) {
2896 if (knew->iface != NID_MAPPING)
2897 continue;
2898 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2899 if (kctl == NULL)
2900 continue;
2901 u = knew->subdevice;
2902 for (j = 0; j < 4; j++, u >>= 8) {
2903 nid = u & 0x3f;
2904 if (nid == 0)
2905 continue;
2906 switch (u & 0xc0) {
2907 case SUBDEV_SPEAKER_:
2908 nid = spec->autocfg.speaker_pins[nid];
2909 break;
2910 case SUBDEV_LINE_:
2911 nid = spec->autocfg.line_out_pins[nid];
2912 break;
2913 case SUBDEV_HP_:
2914 nid = spec->autocfg.hp_pins[nid];
2915 break;
2916 default:
2917 continue;
2918 }
2919 err = snd_hda_add_nid(codec, kctl, 0, nid);
2920 if (err < 0)
2921 return err;
2922 }
2923 u = knew->private_value;
2924 for (j = 0; j < 4; j++, u >>= 8) {
2925 nid = u & 0xff;
2926 if (nid == 0)
2927 continue;
2928 err = snd_hda_add_nid(codec, kctl, 0, nid);
2929 if (err < 0)
2930 return err;
2931 }
2932 }
2933 }
bae84e70
TI
2934
2935 alc_free_kctls(codec); /* no longer needed */
2936
1da177e4
LT
2937 return 0;
2938}
2939
e9edcee0 2940
1da177e4
LT
2941/*
2942 * initialize the codec volumes, etc
2943 */
2944
e9edcee0
TI
2945/*
2946 * generic initialization of ADC, input mixers and output mixers
2947 */
2948static struct hda_verb alc880_volume_init_verbs[] = {
2949 /*
2950 * Unmute ADC0-2 and set the default input to mic-in
2951 */
71fe7b82 2952 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2953 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2954 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2956 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2958
e9edcee0
TI
2959 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2960 * mixer widget
9c7f852e
TI
2961 * Note: PASD motherboards uses the Line In 2 as the input for front
2962 * panel mic (mic 2)
1da177e4 2963 */
e9edcee0 2964 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2965 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2966 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2967 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2968 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2969 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2970 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2971 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2972
e9edcee0
TI
2973 /*
2974 * Set up output mixers (0x0c - 0x0f)
1da177e4 2975 */
e9edcee0
TI
2976 /* set vol=0 to output mixers */
2977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2978 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2979 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2980 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2981 /* set up input amps for analog loopback */
2982 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2983 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2984 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2985 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2986 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2987 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2988 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2989 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2990 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2991
2992 { }
2993};
2994
e9edcee0
TI
2995/*
2996 * 3-stack pin configuration:
2997 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2998 */
2999static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3000 /*
3001 * preset connection lists of input pins
3002 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3003 */
3004 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3005 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3006 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3007
3008 /*
3009 * Set pin mode and muting
3010 */
3011 /* set front pin widgets 0x14 for output */
05acb863 3012 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3013 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3014 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3015 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3016 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3017 /* Mic2 (as headphone out) for HP output */
3018 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3019 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3020 /* Line In pin widget for input */
05acb863 3021 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3022 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3023 /* Line2 (as front mic) pin widget for input and vref at 80% */
3024 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3025 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3026 /* CD pin widget for input */
05acb863 3027 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3028
e9edcee0
TI
3029 { }
3030};
1da177e4 3031
e9edcee0
TI
3032/*
3033 * 5-stack pin configuration:
3034 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3035 * line-in/side = 0x1a, f-mic = 0x1b
3036 */
3037static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3038 /*
3039 * preset connection lists of input pins
3040 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3041 */
e9edcee0
TI
3042 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3043 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3044
e9edcee0
TI
3045 /*
3046 * Set pin mode and muting
1da177e4 3047 */
e9edcee0
TI
3048 /* set pin widgets 0x14-0x17 for output */
3049 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3050 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3051 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3052 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3053 /* unmute pins for output (no gain on this amp) */
3054 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3056 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3057 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3058
3059 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3060 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3061 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3062 /* Mic2 (as headphone out) for HP output */
3063 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3064 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3065 /* Line In pin widget for input */
3066 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3067 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3068 /* Line2 (as front mic) pin widget for input and vref at 80% */
3069 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3070 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3071 /* CD pin widget for input */
3072 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3073
3074 { }
3075};
3076
e9edcee0
TI
3077/*
3078 * W810 pin configuration:
3079 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3080 */
3081static struct hda_verb alc880_pin_w810_init_verbs[] = {
3082 /* hphone/speaker input selector: front DAC */
3083 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3084
05acb863 3085 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3086 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3089 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3090 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3091
e9edcee0 3092 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3093 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3094
1da177e4
LT
3095 { }
3096};
3097
e9edcee0
TI
3098/*
3099 * Z71V pin configuration:
3100 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3101 */
3102static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3103 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3104 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3105 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3106 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3107
16ded525 3108 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3109 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3110 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3111 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3112
3113 { }
3114};
3115
e9edcee0
TI
3116/*
3117 * 6-stack pin configuration:
9c7f852e
TI
3118 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3119 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3120 */
3121static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3122 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3123
16ded525 3124 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3125 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3126 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3128 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3129 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3130 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3131 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3132
16ded525 3133 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3135 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3137 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3138 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3139 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3140 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3141 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3142
e9edcee0
TI
3143 { }
3144};
3145
ccc656ce
KY
3146/*
3147 * Uniwill pin configuration:
3148 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3149 * line = 0x1a
3150 */
3151static struct hda_verb alc880_uniwill_init_verbs[] = {
3152 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3153
3154 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3155 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3157 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3158 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3159 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3160 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3161 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3162 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3164 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3165 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3166 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3167 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3168
3169 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3171 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3172 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3173 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3174 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3175 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3176 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3177 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3178
3179 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3180 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3181
3182 { }
3183};
3184
3185/*
3186* Uniwill P53
ea1fb29a 3187* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3188 */
3189static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3190 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3191
3192 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3193 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3194 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3195 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3196 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3197 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3198 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3200 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3201 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3202 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3203 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3204
3205 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3206 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3207 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3208 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3209 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3210 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3211
3212 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3213 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3214
3215 { }
3216};
3217
2cf9f0fc
TD
3218static struct hda_verb alc880_beep_init_verbs[] = {
3219 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3220 { }
3221};
3222
458a4fab
TI
3223/* auto-toggle front mic */
3224static void alc880_uniwill_mic_automute(struct hda_codec *codec)
3225{
3226 unsigned int present;
3227 unsigned char bits;
ccc656ce 3228
864f92be 3229 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3230 bits = present ? HDA_AMP_MUTE : 0;
3231 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3232}
3233
4f5d1706 3234static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3235{
a9fd4f3f
TI
3236 struct alc_spec *spec = codec->spec;
3237
3238 spec->autocfg.hp_pins[0] = 0x14;
3239 spec->autocfg.speaker_pins[0] = 0x15;
3240 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3241}
3242
3243static void alc880_uniwill_init_hook(struct hda_codec *codec)
3244{
a9fd4f3f 3245 alc_automute_amp(codec);
458a4fab 3246 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
3247}
3248
3249static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3250 unsigned int res)
3251{
3252 /* Looks like the unsol event is incompatible with the standard
3253 * definition. 4bit tag is placed at 28 bit!
3254 */
458a4fab 3255 switch (res >> 28) {
458a4fab
TI
3256 case ALC880_MIC_EVENT:
3257 alc880_uniwill_mic_automute(codec);
3258 break;
a9fd4f3f
TI
3259 default:
3260 alc_automute_amp_unsol_event(codec, res);
3261 break;
458a4fab 3262 }
ccc656ce
KY
3263}
3264
4f5d1706 3265static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3266{
a9fd4f3f 3267 struct alc_spec *spec = codec->spec;
ccc656ce 3268
a9fd4f3f
TI
3269 spec->autocfg.hp_pins[0] = 0x14;
3270 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3271}
3272
3273static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3274{
3275 unsigned int present;
ea1fb29a 3276
ccc656ce 3277 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3278 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3279 present &= HDA_AMP_VOLMASK;
3280 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3281 HDA_AMP_VOLMASK, present);
3282 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3283 HDA_AMP_VOLMASK, present);
ccc656ce 3284}
47fd830a 3285
ccc656ce
KY
3286static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3287 unsigned int res)
3288{
3289 /* Looks like the unsol event is incompatible with the standard
3290 * definition. 4bit tag is placed at 28 bit!
3291 */
f12ab1e0 3292 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3293 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3294 else
3295 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3296}
3297
e9edcee0
TI
3298/*
3299 * F1734 pin configuration:
3300 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3301 */
3302static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3303 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3304 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3305 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3306 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3307 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3308
e9edcee0 3309 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3310 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3311 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3312 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3313
e9edcee0
TI
3314 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3315 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3316 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3317 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3318 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3319 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3320 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3321 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3322 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3323
937b4160
TI
3324 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3325 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3326
dfc0ff62
TI
3327 { }
3328};
3329
e9edcee0
TI
3330/*
3331 * ASUS pin configuration:
3332 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3333 */
3334static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3335 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3336 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3337 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3338 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3339
3340 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3343 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3344 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3345 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3346 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3347 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3348
3349 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3350 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3351 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3352 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3353 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3354 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3356 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3357 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3358
e9edcee0
TI
3359 { }
3360};
16ded525 3361
e9edcee0 3362/* Enable GPIO mask and set output */
bc9f98a9
KY
3363#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3364#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3365#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3366
3367/* Clevo m520g init */
3368static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3369 /* headphone output */
3370 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3371 /* line-out */
3372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3373 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3374 /* Line-in */
3375 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3376 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3377 /* CD */
3378 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3379 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3380 /* Mic1 (rear panel) */
3381 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3382 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3383 /* Mic2 (front panel) */
3384 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3385 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3386 /* headphone */
3387 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3388 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3389 /* change to EAPD mode */
3390 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3391 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3392
3393 { }
16ded525
TI
3394};
3395
df694daa 3396static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3397 /* change to EAPD mode */
3398 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3399 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3400
df694daa
KY
3401 /* Headphone output */
3402 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3403 /* Front output*/
3404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3405 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3406
3407 /* Line In pin widget for input */
3408 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3409 /* CD pin widget for input */
3410 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3411 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3412 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3413
3414 /* change to EAPD mode */
3415 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3416 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3417
3418 { }
3419};
16ded525 3420
e9edcee0 3421/*
ae6b813a
TI
3422 * LG m1 express dual
3423 *
3424 * Pin assignment:
3425 * Rear Line-In/Out (blue): 0x14
3426 * Build-in Mic-In: 0x15
3427 * Speaker-out: 0x17
3428 * HP-Out (green): 0x1b
3429 * Mic-In/Out (red): 0x19
3430 * SPDIF-Out: 0x1e
3431 */
3432
3433/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3434static hda_nid_t alc880_lg_dac_nids[3] = {
3435 0x05, 0x02, 0x03
3436};
3437
3438/* seems analog CD is not working */
3439static struct hda_input_mux alc880_lg_capture_source = {
3440 .num_items = 3,
3441 .items = {
3442 { "Mic", 0x1 },
3443 { "Line", 0x5 },
3444 { "Internal Mic", 0x6 },
3445 },
3446};
3447
3448/* 2,4,6 channel modes */
3449static struct hda_verb alc880_lg_ch2_init[] = {
3450 /* set line-in and mic-in to input */
3451 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3452 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3453 { }
3454};
3455
3456static struct hda_verb alc880_lg_ch4_init[] = {
3457 /* set line-in to out and mic-in to input */
3458 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3459 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3460 { }
3461};
3462
3463static struct hda_verb alc880_lg_ch6_init[] = {
3464 /* set line-in and mic-in to output */
3465 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3466 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3467 { }
3468};
3469
3470static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3471 { 2, alc880_lg_ch2_init },
3472 { 4, alc880_lg_ch4_init },
3473 { 6, alc880_lg_ch6_init },
3474};
3475
3476static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3477 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3478 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3479 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3480 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3481 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3482 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3483 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3484 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3487 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3488 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3489 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3490 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3491 {
3492 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3493 .name = "Channel Mode",
3494 .info = alc_ch_mode_info,
3495 .get = alc_ch_mode_get,
3496 .put = alc_ch_mode_put,
3497 },
3498 { } /* end */
3499};
3500
3501static struct hda_verb alc880_lg_init_verbs[] = {
3502 /* set capture source to mic-in */
3503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3504 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3505 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3506 /* mute all amp mixer inputs */
3507 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3508 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3509 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3510 /* line-in to input */
3511 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3512 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3513 /* built-in mic */
3514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3516 /* speaker-out */
3517 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3518 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3519 /* mic-in to input */
3520 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3521 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3522 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3523 /* HP-out */
3524 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3525 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3526 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3527 /* jack sense */
a9fd4f3f 3528 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3529 { }
3530};
3531
3532/* toggle speaker-output according to the hp-jack state */
4f5d1706 3533static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3534{
a9fd4f3f 3535 struct alc_spec *spec = codec->spec;
ae6b813a 3536
a9fd4f3f
TI
3537 spec->autocfg.hp_pins[0] = 0x1b;
3538 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3539}
3540
d681518a
TI
3541/*
3542 * LG LW20
3543 *
3544 * Pin assignment:
3545 * Speaker-out: 0x14
3546 * Mic-In: 0x18
e4f41da9
CM
3547 * Built-in Mic-In: 0x19
3548 * Line-In: 0x1b
3549 * HP-Out: 0x1a
d681518a
TI
3550 * SPDIF-Out: 0x1e
3551 */
3552
d681518a 3553static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3554 .num_items = 3,
d681518a
TI
3555 .items = {
3556 { "Mic", 0x0 },
3557 { "Internal Mic", 0x1 },
e4f41da9 3558 { "Line In", 0x2 },
d681518a
TI
3559 },
3560};
3561
0a8c5da3
CM
3562#define alc880_lg_lw_modes alc880_threestack_modes
3563
d681518a 3564static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3565 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3566 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3567 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3568 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3569 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3570 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3571 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3572 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3573 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3574 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3577 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3578 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3579 {
3580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3581 .name = "Channel Mode",
3582 .info = alc_ch_mode_info,
3583 .get = alc_ch_mode_get,
3584 .put = alc_ch_mode_put,
3585 },
d681518a
TI
3586 { } /* end */
3587};
3588
3589static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3590 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3591 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3592 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3593
d681518a
TI
3594 /* set capture source to mic-in */
3595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3596 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3597 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3598 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3599 /* speaker-out */
3600 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3601 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3602 /* HP-out */
d681518a
TI
3603 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3604 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3605 /* mic-in to input */
3606 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3607 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3608 /* built-in mic */
3609 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3610 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3611 /* jack sense */
a9fd4f3f 3612 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3613 { }
3614};
3615
3616/* toggle speaker-output according to the hp-jack state */
4f5d1706 3617static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3618{
a9fd4f3f 3619 struct alc_spec *spec = codec->spec;
d681518a 3620
a9fd4f3f
TI
3621 spec->autocfg.hp_pins[0] = 0x1b;
3622 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3623}
3624
df99cd33
TI
3625static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3626 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3627 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3630 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3631 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3632 { } /* end */
3633};
3634
3635static struct hda_input_mux alc880_medion_rim_capture_source = {
3636 .num_items = 2,
3637 .items = {
3638 { "Mic", 0x0 },
3639 { "Internal Mic", 0x1 },
3640 },
3641};
3642
3643static struct hda_verb alc880_medion_rim_init_verbs[] = {
3644 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3645
3646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3647 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3648
3649 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3650 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3652 /* Mic2 (as headphone out) for HP output */
3653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3655 /* Internal Speaker */
3656 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3657 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3658
3659 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3660 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3661
3662 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3663 { }
3664};
3665
3666/* toggle speaker-output according to the hp-jack state */
3667static void alc880_medion_rim_automute(struct hda_codec *codec)
3668{
a9fd4f3f
TI
3669 struct alc_spec *spec = codec->spec;
3670 alc_automute_amp(codec);
3671 /* toggle EAPD */
3672 if (spec->jack_present)
df99cd33
TI
3673 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3674 else
3675 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3676}
3677
3678static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3679 unsigned int res)
3680{
3681 /* Looks like the unsol event is incompatible with the standard
3682 * definition. 4bit tag is placed at 28 bit!
3683 */
3684 if ((res >> 28) == ALC880_HP_EVENT)
3685 alc880_medion_rim_automute(codec);
3686}
3687
4f5d1706 3688static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3689{
3690 struct alc_spec *spec = codec->spec;
3691
3692 spec->autocfg.hp_pins[0] = 0x14;
3693 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3694}
3695
cb53c626
TI
3696#ifdef CONFIG_SND_HDA_POWER_SAVE
3697static struct hda_amp_list alc880_loopbacks[] = {
3698 { 0x0b, HDA_INPUT, 0 },
3699 { 0x0b, HDA_INPUT, 1 },
3700 { 0x0b, HDA_INPUT, 2 },
3701 { 0x0b, HDA_INPUT, 3 },
3702 { 0x0b, HDA_INPUT, 4 },
3703 { } /* end */
3704};
3705
3706static struct hda_amp_list alc880_lg_loopbacks[] = {
3707 { 0x0b, HDA_INPUT, 1 },
3708 { 0x0b, HDA_INPUT, 6 },
3709 { 0x0b, HDA_INPUT, 7 },
3710 { } /* end */
3711};
3712#endif
3713
ae6b813a
TI
3714/*
3715 * Common callbacks
e9edcee0
TI
3716 */
3717
1da177e4
LT
3718static int alc_init(struct hda_codec *codec)
3719{
3720 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3721 unsigned int i;
3722
2c3bf9ab 3723 alc_fix_pll(codec);
4a79ba34 3724 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3725
e9edcee0
TI
3726 for (i = 0; i < spec->num_init_verbs; i++)
3727 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3728
3729 if (spec->init_hook)
3730 spec->init_hook(codec);
3731
ad35879a
TI
3732#ifdef CONFIG_SND_HDA_POWER_SAVE
3733 if (codec->patch_ops.check_power_status)
3734 codec->patch_ops.check_power_status(codec, 0x01);
3735#endif
1da177e4
LT
3736 return 0;
3737}
3738
ae6b813a
TI
3739static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3740{
3741 struct alc_spec *spec = codec->spec;
3742
3743 if (spec->unsol_event)
3744 spec->unsol_event(codec, res);
3745}
3746
cb53c626
TI
3747#ifdef CONFIG_SND_HDA_POWER_SAVE
3748static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3749{
3750 struct alc_spec *spec = codec->spec;
3751 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3752}
3753#endif
3754
1da177e4
LT
3755/*
3756 * Analog playback callbacks
3757 */
3758static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3759 struct hda_codec *codec,
c8b6bf9b 3760 struct snd_pcm_substream *substream)
1da177e4
LT
3761{
3762 struct alc_spec *spec = codec->spec;
9a08160b
TI
3763 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3764 hinfo);
1da177e4
LT
3765}
3766
3767static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3768 struct hda_codec *codec,
3769 unsigned int stream_tag,
3770 unsigned int format,
c8b6bf9b 3771 struct snd_pcm_substream *substream)
1da177e4
LT
3772{
3773 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3774 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3775 stream_tag, format, substream);
1da177e4
LT
3776}
3777
3778static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3779 struct hda_codec *codec,
c8b6bf9b 3780 struct snd_pcm_substream *substream)
1da177e4
LT
3781{
3782 struct alc_spec *spec = codec->spec;
3783 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3784}
3785
3786/*
3787 * Digital out
3788 */
3789static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3790 struct hda_codec *codec,
c8b6bf9b 3791 struct snd_pcm_substream *substream)
1da177e4
LT
3792{
3793 struct alc_spec *spec = codec->spec;
3794 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3795}
3796
6b97eb45
TI
3797static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3798 struct hda_codec *codec,
3799 unsigned int stream_tag,
3800 unsigned int format,
3801 struct snd_pcm_substream *substream)
3802{
3803 struct alc_spec *spec = codec->spec;
3804 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3805 stream_tag, format, substream);
3806}
3807
9b5f12e5
TI
3808static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3809 struct hda_codec *codec,
3810 struct snd_pcm_substream *substream)
3811{
3812 struct alc_spec *spec = codec->spec;
3813 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3814}
3815
1da177e4
LT
3816static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3817 struct hda_codec *codec,
c8b6bf9b 3818 struct snd_pcm_substream *substream)
1da177e4
LT
3819{
3820 struct alc_spec *spec = codec->spec;
3821 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3822}
3823
3824/*
3825 * Analog capture
3826 */
6330079f 3827static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3828 struct hda_codec *codec,
3829 unsigned int stream_tag,
3830 unsigned int format,
c8b6bf9b 3831 struct snd_pcm_substream *substream)
1da177e4
LT
3832{
3833 struct alc_spec *spec = codec->spec;
3834
6330079f 3835 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3836 stream_tag, 0, format);
3837 return 0;
3838}
3839
6330079f 3840static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3841 struct hda_codec *codec,
c8b6bf9b 3842 struct snd_pcm_substream *substream)
1da177e4
LT
3843{
3844 struct alc_spec *spec = codec->spec;
3845
888afa15
TI
3846 snd_hda_codec_cleanup_stream(codec,
3847 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3848 return 0;
3849}
3850
840b64c0
TI
3851/* analog capture with dynamic dual-adc changes */
3852static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3853 struct hda_codec *codec,
3854 unsigned int stream_tag,
3855 unsigned int format,
3856 struct snd_pcm_substream *substream)
3857{
3858 struct alc_spec *spec = codec->spec;
3859 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3860 spec->cur_adc_stream_tag = stream_tag;
3861 spec->cur_adc_format = format;
3862 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3863 return 0;
3864}
3865
3866static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3867 struct hda_codec *codec,
3868 struct snd_pcm_substream *substream)
3869{
3870 struct alc_spec *spec = codec->spec;
3871 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3872 spec->cur_adc = 0;
3873 return 0;
3874}
3875
3876static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3877 .substreams = 1,
3878 .channels_min = 2,
3879 .channels_max = 2,
3880 .nid = 0, /* fill later */
3881 .ops = {
3882 .prepare = dualmic_capture_pcm_prepare,
3883 .cleanup = dualmic_capture_pcm_cleanup
3884 },
3885};
1da177e4
LT
3886
3887/*
3888 */
3889static struct hda_pcm_stream alc880_pcm_analog_playback = {
3890 .substreams = 1,
3891 .channels_min = 2,
3892 .channels_max = 8,
e9edcee0 3893 /* NID is set in alc_build_pcms */
1da177e4
LT
3894 .ops = {
3895 .open = alc880_playback_pcm_open,
3896 .prepare = alc880_playback_pcm_prepare,
3897 .cleanup = alc880_playback_pcm_cleanup
3898 },
3899};
3900
3901static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3902 .substreams = 1,
3903 .channels_min = 2,
3904 .channels_max = 2,
3905 /* NID is set in alc_build_pcms */
3906};
3907
3908static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3909 .substreams = 1,
3910 .channels_min = 2,
3911 .channels_max = 2,
3912 /* NID is set in alc_build_pcms */
3913};
3914
3915static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3916 .substreams = 2, /* can be overridden */
1da177e4
LT
3917 .channels_min = 2,
3918 .channels_max = 2,
e9edcee0 3919 /* NID is set in alc_build_pcms */
1da177e4 3920 .ops = {
6330079f
TI
3921 .prepare = alc880_alt_capture_pcm_prepare,
3922 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3923 },
3924};
3925
3926static struct hda_pcm_stream alc880_pcm_digital_playback = {
3927 .substreams = 1,
3928 .channels_min = 2,
3929 .channels_max = 2,
3930 /* NID is set in alc_build_pcms */
3931 .ops = {
3932 .open = alc880_dig_playback_pcm_open,
6b97eb45 3933 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3934 .prepare = alc880_dig_playback_pcm_prepare,
3935 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3936 },
3937};
3938
3939static struct hda_pcm_stream alc880_pcm_digital_capture = {
3940 .substreams = 1,
3941 .channels_min = 2,
3942 .channels_max = 2,
3943 /* NID is set in alc_build_pcms */
3944};
3945
4c5186ed 3946/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3947static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3948 .substreams = 0,
3949 .channels_min = 0,
3950 .channels_max = 0,
3951};
3952
1da177e4
LT
3953static int alc_build_pcms(struct hda_codec *codec)
3954{
3955 struct alc_spec *spec = codec->spec;
3956 struct hda_pcm *info = spec->pcm_rec;
3957 int i;
3958
3959 codec->num_pcms = 1;
3960 codec->pcm_info = info;
3961
e64f14f4
TI
3962 if (spec->no_analog)
3963 goto skip_analog;
3964
812a2cca
TI
3965 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3966 "%s Analog", codec->chip_name);
1da177e4 3967 info->name = spec->stream_name_analog;
274693f3 3968
4a471b7d 3969 if (spec->stream_analog_playback) {
da3cec35
TI
3970 if (snd_BUG_ON(!spec->multiout.dac_nids))
3971 return -EINVAL;
4a471b7d
TI
3972 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3973 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3974 }
3975 if (spec->stream_analog_capture) {
da3cec35
TI
3976 if (snd_BUG_ON(!spec->adc_nids))
3977 return -EINVAL;
4a471b7d
TI
3978 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3979 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3980 }
3981
3982 if (spec->channel_mode) {
3983 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3984 for (i = 0; i < spec->num_channel_mode; i++) {
3985 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3986 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3987 }
1da177e4
LT
3988 }
3989 }
3990
e64f14f4 3991 skip_analog:
e08a007d 3992 /* SPDIF for stream index #1 */
1da177e4 3993 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3994 snprintf(spec->stream_name_digital,
3995 sizeof(spec->stream_name_digital),
3996 "%s Digital", codec->chip_name);
e08a007d 3997 codec->num_pcms = 2;
b25c9da1 3998 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3999 info = spec->pcm_rec + 1;
1da177e4 4000 info->name = spec->stream_name_digital;
8c441982
TI
4001 if (spec->dig_out_type)
4002 info->pcm_type = spec->dig_out_type;
4003 else
4004 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4005 if (spec->multiout.dig_out_nid &&
4006 spec->stream_digital_playback) {
1da177e4
LT
4007 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4008 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4009 }
4a471b7d
TI
4010 if (spec->dig_in_nid &&
4011 spec->stream_digital_capture) {
1da177e4
LT
4012 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4013 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4014 }
963f803f
TI
4015 /* FIXME: do we need this for all Realtek codec models? */
4016 codec->spdif_status_reset = 1;
1da177e4
LT
4017 }
4018
e64f14f4
TI
4019 if (spec->no_analog)
4020 return 0;
4021
e08a007d
TI
4022 /* If the use of more than one ADC is requested for the current
4023 * model, configure a second analog capture-only PCM.
4024 */
4025 /* Additional Analaog capture for index #2 */
6330079f
TI
4026 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4027 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4028 codec->num_pcms = 3;
c06134d7 4029 info = spec->pcm_rec + 2;
e08a007d 4030 info->name = spec->stream_name_analog;
6330079f
TI
4031 if (spec->alt_dac_nid) {
4032 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4033 *spec->stream_analog_alt_playback;
4034 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4035 spec->alt_dac_nid;
4036 } else {
4037 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4038 alc_pcm_null_stream;
4039 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4040 }
4041 if (spec->num_adc_nids > 1) {
4042 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4043 *spec->stream_analog_alt_capture;
4044 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4045 spec->adc_nids[1];
4046 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4047 spec->num_adc_nids - 1;
4048 } else {
4049 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4050 alc_pcm_null_stream;
4051 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4052 }
4053 }
4054
1da177e4
LT
4055 return 0;
4056}
4057
a4e09aa3
TI
4058static inline void alc_shutup(struct hda_codec *codec)
4059{
4060 snd_hda_shutup_pins(codec);
4061}
4062
603c4019
TI
4063static void alc_free_kctls(struct hda_codec *codec)
4064{
4065 struct alc_spec *spec = codec->spec;
4066
4067 if (spec->kctls.list) {
4068 struct snd_kcontrol_new *kctl = spec->kctls.list;
4069 int i;
4070 for (i = 0; i < spec->kctls.used; i++)
4071 kfree(kctl[i].name);
4072 }
4073 snd_array_free(&spec->kctls);
4074}
4075
1da177e4
LT
4076static void alc_free(struct hda_codec *codec)
4077{
e9edcee0 4078 struct alc_spec *spec = codec->spec;
e9edcee0 4079
f12ab1e0 4080 if (!spec)
e9edcee0
TI
4081 return;
4082
a4e09aa3 4083 alc_shutup(codec);
603c4019 4084 alc_free_kctls(codec);
e9edcee0 4085 kfree(spec);
680cd536 4086 snd_hda_detach_beep_device(codec);
1da177e4
LT
4087}
4088
f5de24b0 4089#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4090static void alc_power_eapd(struct hda_codec *codec)
4091{
4092 /* We currently only handle front, HP */
4093 switch (codec->vendor_id) {
4094 case 0x10ec0260:
9e4c8496
TI
4095 set_eapd(codec, 0x0f, 0);
4096 set_eapd(codec, 0x10, 0);
c97259df
DC
4097 break;
4098 case 0x10ec0262:
4099 case 0x10ec0267:
4100 case 0x10ec0268:
4101 case 0x10ec0269:
9e4c8496 4102 case 0x10ec0270:
c97259df
DC
4103 case 0x10ec0272:
4104 case 0x10ec0660:
4105 case 0x10ec0662:
4106 case 0x10ec0663:
4107 case 0x10ec0862:
4108 case 0x10ec0889:
9e4c8496
TI
4109 set_eapd(codec, 0x14, 0);
4110 set_eapd(codec, 0x15, 0);
c97259df
DC
4111 break;
4112 }
4113}
4114
f5de24b0
HM
4115static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4116{
4117 struct alc_spec *spec = codec->spec;
a4e09aa3 4118 alc_shutup(codec);
f5de24b0 4119 if (spec && spec->power_hook)
c97259df 4120 spec->power_hook(codec);
f5de24b0
HM
4121 return 0;
4122}
4123#endif
4124
e044c39a 4125#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4126static int alc_resume(struct hda_codec *codec)
4127{
e044c39a
TI
4128 codec->patch_ops.init(codec);
4129 snd_hda_codec_resume_amp(codec);
4130 snd_hda_codec_resume_cache(codec);
ad35879a
TI
4131#ifdef CONFIG_SND_HDA_POWER_SAVE
4132 if (codec->patch_ops.check_power_status)
4133 codec->patch_ops.check_power_status(codec, 0x01);
4134#endif
e044c39a
TI
4135 return 0;
4136}
e044c39a
TI
4137#endif
4138
1da177e4
LT
4139/*
4140 */
4141static struct hda_codec_ops alc_patch_ops = {
4142 .build_controls = alc_build_controls,
4143 .build_pcms = alc_build_pcms,
4144 .init = alc_init,
4145 .free = alc_free,
ae6b813a 4146 .unsol_event = alc_unsol_event,
e044c39a
TI
4147#ifdef SND_HDA_NEEDS_RESUME
4148 .resume = alc_resume,
4149#endif
cb53c626 4150#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4151 .suspend = alc_suspend,
cb53c626
TI
4152 .check_power_status = alc_check_power_status,
4153#endif
c97259df 4154 .reboot_notify = alc_shutup,
1da177e4
LT
4155};
4156
c027ddcd
KY
4157/* replace the codec chip_name with the given string */
4158static int alc_codec_rename(struct hda_codec *codec, const char *name)
4159{
4160 kfree(codec->chip_name);
4161 codec->chip_name = kstrdup(name, GFP_KERNEL);
4162 if (!codec->chip_name) {
4163 alc_free(codec);
4164 return -ENOMEM;
4165 }
4166 return 0;
4167}
4168
2fa522be
TI
4169/*
4170 * Test configuration for debugging
4171 *
4172 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4173 * enum controls.
4174 */
4175#ifdef CONFIG_SND_DEBUG
4176static hda_nid_t alc880_test_dac_nids[4] = {
4177 0x02, 0x03, 0x04, 0x05
4178};
4179
4180static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4181 .num_items = 7,
2fa522be
TI
4182 .items = {
4183 { "In-1", 0x0 },
4184 { "In-2", 0x1 },
4185 { "In-3", 0x2 },
4186 { "In-4", 0x3 },
4187 { "CD", 0x4 },
ae6b813a
TI
4188 { "Front", 0x5 },
4189 { "Surround", 0x6 },
2fa522be
TI
4190 },
4191};
4192
d2a6d7dc 4193static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4194 { 2, NULL },
fd2c326d 4195 { 4, NULL },
2fa522be 4196 { 6, NULL },
fd2c326d 4197 { 8, NULL },
2fa522be
TI
4198};
4199
9c7f852e
TI
4200static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4201 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4202{
4203 static char *texts[] = {
4204 "N/A", "Line Out", "HP Out",
4205 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4206 };
4207 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4208 uinfo->count = 1;
4209 uinfo->value.enumerated.items = 8;
4210 if (uinfo->value.enumerated.item >= 8)
4211 uinfo->value.enumerated.item = 7;
4212 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4213 return 0;
4214}
4215
9c7f852e
TI
4216static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4217 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4218{
4219 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4220 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4221 unsigned int pin_ctl, item = 0;
4222
4223 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4224 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4225 if (pin_ctl & AC_PINCTL_OUT_EN) {
4226 if (pin_ctl & AC_PINCTL_HP_EN)
4227 item = 2;
4228 else
4229 item = 1;
4230 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4231 switch (pin_ctl & AC_PINCTL_VREFEN) {
4232 case AC_PINCTL_VREF_HIZ: item = 3; break;
4233 case AC_PINCTL_VREF_50: item = 4; break;
4234 case AC_PINCTL_VREF_GRD: item = 5; break;
4235 case AC_PINCTL_VREF_80: item = 6; break;
4236 case AC_PINCTL_VREF_100: item = 7; break;
4237 }
4238 }
4239 ucontrol->value.enumerated.item[0] = item;
4240 return 0;
4241}
4242
9c7f852e
TI
4243static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4244 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4245{
4246 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4247 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4248 static unsigned int ctls[] = {
4249 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4250 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4251 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4252 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4253 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4254 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4255 };
4256 unsigned int old_ctl, new_ctl;
4257
4258 old_ctl = snd_hda_codec_read(codec, nid, 0,
4259 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4260 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4261 if (old_ctl != new_ctl) {
82beb8fd
TI
4262 int val;
4263 snd_hda_codec_write_cache(codec, nid, 0,
4264 AC_VERB_SET_PIN_WIDGET_CONTROL,
4265 new_ctl);
47fd830a
TI
4266 val = ucontrol->value.enumerated.item[0] >= 3 ?
4267 HDA_AMP_MUTE : 0;
4268 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4269 HDA_AMP_MUTE, val);
2fa522be
TI
4270 return 1;
4271 }
4272 return 0;
4273}
4274
9c7f852e
TI
4275static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4276 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4277{
4278 static char *texts[] = {
4279 "Front", "Surround", "CLFE", "Side"
4280 };
4281 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4282 uinfo->count = 1;
4283 uinfo->value.enumerated.items = 4;
4284 if (uinfo->value.enumerated.item >= 4)
4285 uinfo->value.enumerated.item = 3;
4286 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4287 return 0;
4288}
4289
9c7f852e
TI
4290static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4291 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4292{
4293 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4294 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4295 unsigned int sel;
4296
4297 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4298 ucontrol->value.enumerated.item[0] = sel & 3;
4299 return 0;
4300}
4301
9c7f852e
TI
4302static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4303 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4304{
4305 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4306 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4307 unsigned int sel;
4308
4309 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4310 if (ucontrol->value.enumerated.item[0] != sel) {
4311 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4312 snd_hda_codec_write_cache(codec, nid, 0,
4313 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4314 return 1;
4315 }
4316 return 0;
4317}
4318
4319#define PIN_CTL_TEST(xname,nid) { \
4320 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4321 .name = xname, \
5b0cb1d8 4322 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4323 .info = alc_test_pin_ctl_info, \
4324 .get = alc_test_pin_ctl_get, \
4325 .put = alc_test_pin_ctl_put, \
4326 .private_value = nid \
4327 }
4328
4329#define PIN_SRC_TEST(xname,nid) { \
4330 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4331 .name = xname, \
5b0cb1d8 4332 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4333 .info = alc_test_pin_src_info, \
4334 .get = alc_test_pin_src_get, \
4335 .put = alc_test_pin_src_put, \
4336 .private_value = nid \
4337 }
4338
c8b6bf9b 4339static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4340 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4341 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4342 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4343 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4344 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4345 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4346 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4347 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4348 PIN_CTL_TEST("Front Pin Mode", 0x14),
4349 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4350 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4351 PIN_CTL_TEST("Side Pin Mode", 0x17),
4352 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4353 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4354 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4355 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4356 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4357 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4358 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4359 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4360 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4361 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4362 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4363 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4364 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4365 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4366 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4367 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4368 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4369 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4370 {
4371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4372 .name = "Channel Mode",
df694daa
KY
4373 .info = alc_ch_mode_info,
4374 .get = alc_ch_mode_get,
4375 .put = alc_ch_mode_put,
2fa522be
TI
4376 },
4377 { } /* end */
4378};
4379
4380static struct hda_verb alc880_test_init_verbs[] = {
4381 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4384 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4386 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4387 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4388 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4389 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4390 /* Vol output for 0x0c-0x0f */
05acb863
TI
4391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4392 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4393 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4394 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4395 /* Set output pins 0x14-0x17 */
05acb863
TI
4396 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4397 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4398 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4399 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4400 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4401 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4402 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4403 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4404 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4405 /* Set input pins 0x18-0x1c */
16ded525
TI
4406 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4407 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4408 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4409 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4410 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4411 /* Mute input pins 0x18-0x1b */
05acb863
TI
4412 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4413 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4414 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4415 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4416 /* ADC set up */
05acb863 4417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4418 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4419 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4420 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4421 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4422 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4423 /* Analog input/passthru */
4424 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4425 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4426 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4427 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4428 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4429 { }
4430};
4431#endif
4432
1da177e4
LT
4433/*
4434 */
4435
f5fcc13c
TI
4436static const char *alc880_models[ALC880_MODEL_LAST] = {
4437 [ALC880_3ST] = "3stack",
4438 [ALC880_TCL_S700] = "tcl",
4439 [ALC880_3ST_DIG] = "3stack-digout",
4440 [ALC880_CLEVO] = "clevo",
4441 [ALC880_5ST] = "5stack",
4442 [ALC880_5ST_DIG] = "5stack-digout",
4443 [ALC880_W810] = "w810",
4444 [ALC880_Z71V] = "z71v",
4445 [ALC880_6ST] = "6stack",
4446 [ALC880_6ST_DIG] = "6stack-digout",
4447 [ALC880_ASUS] = "asus",
4448 [ALC880_ASUS_W1V] = "asus-w1v",
4449 [ALC880_ASUS_DIG] = "asus-dig",
4450 [ALC880_ASUS_DIG2] = "asus-dig2",
4451 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4452 [ALC880_UNIWILL_P53] = "uniwill-p53",
4453 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4454 [ALC880_F1734] = "F1734",
4455 [ALC880_LG] = "lg",
4456 [ALC880_LG_LW] = "lg-lw",
df99cd33 4457 [ALC880_MEDION_RIM] = "medion",
2fa522be 4458#ifdef CONFIG_SND_DEBUG
f5fcc13c 4459 [ALC880_TEST] = "test",
2fa522be 4460#endif
f5fcc13c
TI
4461 [ALC880_AUTO] = "auto",
4462};
4463
4464static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4465 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4466 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4467 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4468 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4469 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4470 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4471 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4472 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4473 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4474 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4475 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4476 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4477 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4478 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4479 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4480 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4481 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4482 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4483 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4484 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4485 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4486 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4487 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4488 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4489 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4490 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4491 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4492 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4493 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4494 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4495 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4496 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4497 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4498 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4499 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4500 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4501 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4502 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4503 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4504 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4505 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4506 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4507 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4508 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4509 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4510 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4511 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4512 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4513 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4514 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4515 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4516 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
4517 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4518 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4519 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4520 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4521 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4522 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4523 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4524 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4525 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4526 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4527 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4528 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4529 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4530 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4531 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4532 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4533 /* default Intel */
4534 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4535 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4536 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4537 {}
4538};
4539
16ded525 4540/*
df694daa 4541 * ALC880 codec presets
16ded525 4542 */
16ded525
TI
4543static struct alc_config_preset alc880_presets[] = {
4544 [ALC880_3ST] = {
e9edcee0 4545 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4546 .init_verbs = { alc880_volume_init_verbs,
4547 alc880_pin_3stack_init_verbs },
16ded525 4548 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4549 .dac_nids = alc880_dac_nids,
16ded525
TI
4550 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4551 .channel_mode = alc880_threestack_modes,
4e195a7b 4552 .need_dac_fix = 1,
16ded525
TI
4553 .input_mux = &alc880_capture_source,
4554 },
4555 [ALC880_3ST_DIG] = {
e9edcee0 4556 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4557 .init_verbs = { alc880_volume_init_verbs,
4558 alc880_pin_3stack_init_verbs },
16ded525 4559 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4560 .dac_nids = alc880_dac_nids,
4561 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4562 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4563 .channel_mode = alc880_threestack_modes,
4e195a7b 4564 .need_dac_fix = 1,
16ded525
TI
4565 .input_mux = &alc880_capture_source,
4566 },
df694daa
KY
4567 [ALC880_TCL_S700] = {
4568 .mixers = { alc880_tcl_s700_mixer },
4569 .init_verbs = { alc880_volume_init_verbs,
4570 alc880_pin_tcl_S700_init_verbs,
4571 alc880_gpio2_init_verbs },
4572 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4573 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4574 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4575 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4576 .hp_nid = 0x03,
4577 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4578 .channel_mode = alc880_2_jack_modes,
4579 .input_mux = &alc880_capture_source,
4580 },
16ded525 4581 [ALC880_5ST] = {
f12ab1e0
TI
4582 .mixers = { alc880_three_stack_mixer,
4583 alc880_five_stack_mixer},
4584 .init_verbs = { alc880_volume_init_verbs,
4585 alc880_pin_5stack_init_verbs },
16ded525
TI
4586 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4587 .dac_nids = alc880_dac_nids,
16ded525
TI
4588 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4589 .channel_mode = alc880_fivestack_modes,
4590 .input_mux = &alc880_capture_source,
4591 },
4592 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4593 .mixers = { alc880_three_stack_mixer,
4594 alc880_five_stack_mixer },
4595 .init_verbs = { alc880_volume_init_verbs,
4596 alc880_pin_5stack_init_verbs },
16ded525
TI
4597 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4598 .dac_nids = alc880_dac_nids,
4599 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4600 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4601 .channel_mode = alc880_fivestack_modes,
4602 .input_mux = &alc880_capture_source,
4603 },
b6482d48
TI
4604 [ALC880_6ST] = {
4605 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4606 .init_verbs = { alc880_volume_init_verbs,
4607 alc880_pin_6stack_init_verbs },
b6482d48
TI
4608 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4609 .dac_nids = alc880_6st_dac_nids,
4610 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4611 .channel_mode = alc880_sixstack_modes,
4612 .input_mux = &alc880_6stack_capture_source,
4613 },
16ded525 4614 [ALC880_6ST_DIG] = {
e9edcee0 4615 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4616 .init_verbs = { alc880_volume_init_verbs,
4617 alc880_pin_6stack_init_verbs },
16ded525
TI
4618 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4619 .dac_nids = alc880_6st_dac_nids,
4620 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4621 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4622 .channel_mode = alc880_sixstack_modes,
4623 .input_mux = &alc880_6stack_capture_source,
4624 },
4625 [ALC880_W810] = {
e9edcee0 4626 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4627 .init_verbs = { alc880_volume_init_verbs,
4628 alc880_pin_w810_init_verbs,
b0af0de5 4629 alc880_gpio2_init_verbs },
16ded525
TI
4630 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4631 .dac_nids = alc880_w810_dac_nids,
4632 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4633 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4634 .channel_mode = alc880_w810_modes,
4635 .input_mux = &alc880_capture_source,
4636 },
4637 [ALC880_Z71V] = {
e9edcee0 4638 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4639 .init_verbs = { alc880_volume_init_verbs,
4640 alc880_pin_z71v_init_verbs },
16ded525
TI
4641 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4642 .dac_nids = alc880_z71v_dac_nids,
4643 .dig_out_nid = ALC880_DIGOUT_NID,
4644 .hp_nid = 0x03,
e9edcee0
TI
4645 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4646 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4647 .input_mux = &alc880_capture_source,
4648 },
4649 [ALC880_F1734] = {
e9edcee0 4650 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4651 .init_verbs = { alc880_volume_init_verbs,
4652 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4653 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4654 .dac_nids = alc880_f1734_dac_nids,
4655 .hp_nid = 0x02,
4656 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4657 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4658 .input_mux = &alc880_f1734_capture_source,
4659 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4660 .setup = alc880_uniwill_p53_setup,
4661 .init_hook = alc_automute_amp,
16ded525
TI
4662 },
4663 [ALC880_ASUS] = {
e9edcee0 4664 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4665 .init_verbs = { alc880_volume_init_verbs,
4666 alc880_pin_asus_init_verbs,
e9edcee0
TI
4667 alc880_gpio1_init_verbs },
4668 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4669 .dac_nids = alc880_asus_dac_nids,
4670 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4671 .channel_mode = alc880_asus_modes,
4e195a7b 4672 .need_dac_fix = 1,
16ded525
TI
4673 .input_mux = &alc880_capture_source,
4674 },
4675 [ALC880_ASUS_DIG] = {
e9edcee0 4676 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4677 .init_verbs = { alc880_volume_init_verbs,
4678 alc880_pin_asus_init_verbs,
e9edcee0
TI
4679 alc880_gpio1_init_verbs },
4680 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4681 .dac_nids = alc880_asus_dac_nids,
16ded525 4682 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4683 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4684 .channel_mode = alc880_asus_modes,
4e195a7b 4685 .need_dac_fix = 1,
16ded525
TI
4686 .input_mux = &alc880_capture_source,
4687 },
df694daa
KY
4688 [ALC880_ASUS_DIG2] = {
4689 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4690 .init_verbs = { alc880_volume_init_verbs,
4691 alc880_pin_asus_init_verbs,
df694daa
KY
4692 alc880_gpio2_init_verbs }, /* use GPIO2 */
4693 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4694 .dac_nids = alc880_asus_dac_nids,
4695 .dig_out_nid = ALC880_DIGOUT_NID,
4696 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4697 .channel_mode = alc880_asus_modes,
4e195a7b 4698 .need_dac_fix = 1,
df694daa
KY
4699 .input_mux = &alc880_capture_source,
4700 },
16ded525 4701 [ALC880_ASUS_W1V] = {
e9edcee0 4702 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4703 .init_verbs = { alc880_volume_init_verbs,
4704 alc880_pin_asus_init_verbs,
e9edcee0
TI
4705 alc880_gpio1_init_verbs },
4706 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4707 .dac_nids = alc880_asus_dac_nids,
16ded525 4708 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4709 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4710 .channel_mode = alc880_asus_modes,
4e195a7b 4711 .need_dac_fix = 1,
16ded525
TI
4712 .input_mux = &alc880_capture_source,
4713 },
4714 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4715 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4716 .init_verbs = { alc880_volume_init_verbs,
4717 alc880_pin_asus_init_verbs },
e9edcee0
TI
4718 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4719 .dac_nids = alc880_asus_dac_nids,
16ded525 4720 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4721 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4722 .channel_mode = alc880_asus_modes,
4e195a7b 4723 .need_dac_fix = 1,
16ded525
TI
4724 .input_mux = &alc880_capture_source,
4725 },
ccc656ce
KY
4726 [ALC880_UNIWILL] = {
4727 .mixers = { alc880_uniwill_mixer },
4728 .init_verbs = { alc880_volume_init_verbs,
4729 alc880_uniwill_init_verbs },
4730 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4731 .dac_nids = alc880_asus_dac_nids,
4732 .dig_out_nid = ALC880_DIGOUT_NID,
4733 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4734 .channel_mode = alc880_threestack_modes,
4735 .need_dac_fix = 1,
4736 .input_mux = &alc880_capture_source,
4737 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4738 .setup = alc880_uniwill_setup,
a9fd4f3f 4739 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4740 },
4741 [ALC880_UNIWILL_P53] = {
4742 .mixers = { alc880_uniwill_p53_mixer },
4743 .init_verbs = { alc880_volume_init_verbs,
4744 alc880_uniwill_p53_init_verbs },
4745 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4746 .dac_nids = alc880_asus_dac_nids,
4747 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4748 .channel_mode = alc880_threestack_modes,
4749 .input_mux = &alc880_capture_source,
4750 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4751 .setup = alc880_uniwill_p53_setup,
4752 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4753 },
4754 [ALC880_FUJITSU] = {
45bdd1c1 4755 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4756 .init_verbs = { alc880_volume_init_verbs,
4757 alc880_uniwill_p53_init_verbs,
4758 alc880_beep_init_verbs },
4759 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4760 .dac_nids = alc880_dac_nids,
d53d7d9e 4761 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4762 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4763 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4764 .input_mux = &alc880_capture_source,
4765 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4766 .setup = alc880_uniwill_p53_setup,
4767 .init_hook = alc_automute_amp,
ccc656ce 4768 },
df694daa
KY
4769 [ALC880_CLEVO] = {
4770 .mixers = { alc880_three_stack_mixer },
4771 .init_verbs = { alc880_volume_init_verbs,
4772 alc880_pin_clevo_init_verbs },
4773 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4774 .dac_nids = alc880_dac_nids,
4775 .hp_nid = 0x03,
4776 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4777 .channel_mode = alc880_threestack_modes,
4e195a7b 4778 .need_dac_fix = 1,
df694daa
KY
4779 .input_mux = &alc880_capture_source,
4780 },
ae6b813a
TI
4781 [ALC880_LG] = {
4782 .mixers = { alc880_lg_mixer },
4783 .init_verbs = { alc880_volume_init_verbs,
4784 alc880_lg_init_verbs },
4785 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4786 .dac_nids = alc880_lg_dac_nids,
4787 .dig_out_nid = ALC880_DIGOUT_NID,
4788 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4789 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4790 .need_dac_fix = 1,
ae6b813a 4791 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4792 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4793 .setup = alc880_lg_setup,
4794 .init_hook = alc_automute_amp,
cb53c626
TI
4795#ifdef CONFIG_SND_HDA_POWER_SAVE
4796 .loopbacks = alc880_lg_loopbacks,
4797#endif
ae6b813a 4798 },
d681518a
TI
4799 [ALC880_LG_LW] = {
4800 .mixers = { alc880_lg_lw_mixer },
4801 .init_verbs = { alc880_volume_init_verbs,
4802 alc880_lg_lw_init_verbs },
0a8c5da3 4803 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4804 .dac_nids = alc880_dac_nids,
4805 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4806 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4807 .channel_mode = alc880_lg_lw_modes,
d681518a 4808 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4809 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4810 .setup = alc880_lg_lw_setup,
4811 .init_hook = alc_automute_amp,
d681518a 4812 },
df99cd33
TI
4813 [ALC880_MEDION_RIM] = {
4814 .mixers = { alc880_medion_rim_mixer },
4815 .init_verbs = { alc880_volume_init_verbs,
4816 alc880_medion_rim_init_verbs,
4817 alc_gpio2_init_verbs },
4818 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4819 .dac_nids = alc880_dac_nids,
4820 .dig_out_nid = ALC880_DIGOUT_NID,
4821 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4822 .channel_mode = alc880_2_jack_modes,
4823 .input_mux = &alc880_medion_rim_capture_source,
4824 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4825 .setup = alc880_medion_rim_setup,
4826 .init_hook = alc880_medion_rim_automute,
df99cd33 4827 },
16ded525
TI
4828#ifdef CONFIG_SND_DEBUG
4829 [ALC880_TEST] = {
e9edcee0
TI
4830 .mixers = { alc880_test_mixer },
4831 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4832 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4833 .dac_nids = alc880_test_dac_nids,
4834 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4835 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4836 .channel_mode = alc880_test_modes,
4837 .input_mux = &alc880_test_capture_source,
4838 },
4839#endif
4840};
4841
e9edcee0
TI
4842/*
4843 * Automatic parse of I/O pins from the BIOS configuration
4844 */
4845
e9edcee0
TI
4846enum {
4847 ALC_CTL_WIDGET_VOL,
4848 ALC_CTL_WIDGET_MUTE,
4849 ALC_CTL_BIND_MUTE,
4850};
c8b6bf9b 4851static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4852 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4853 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4854 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4855};
4856
4857/* add dynamic controls */
f12ab1e0 4858static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 4859 int cidx, unsigned long val)
e9edcee0 4860{
c8b6bf9b 4861 struct snd_kcontrol_new *knew;
e9edcee0 4862
603c4019
TI
4863 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4864 knew = snd_array_new(&spec->kctls);
4865 if (!knew)
4866 return -ENOMEM;
e9edcee0 4867 *knew = alc880_control_templates[type];
543537bd 4868 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4869 if (!knew->name)
e9edcee0 4870 return -ENOMEM;
66ceeb6b 4871 knew->index = cidx;
4d02d1b6 4872 if (get_amp_nid_(val))
5e26dfd0 4873 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 4874 knew->private_value = val;
e9edcee0
TI
4875 return 0;
4876}
4877
0afe5f89
TI
4878static int add_control_with_pfx(struct alc_spec *spec, int type,
4879 const char *pfx, const char *dir,
66ceeb6b 4880 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
4881{
4882 char name[32];
4883 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 4884 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
4885}
4886
66ceeb6b
TI
4887#define add_pb_vol_ctrl(spec, type, pfx, val) \
4888 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
4889#define add_pb_sw_ctrl(spec, type, pfx, val) \
4890 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
4891#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
4892 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
4893#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
4894 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 4895
e9edcee0
TI
4896#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4897#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4898#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4899#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4900#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4901#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4902#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4903#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4904#define ALC880_PIN_CD_NID 0x1c
4905
4906/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4907static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4908 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4909{
4910 hda_nid_t nid;
4911 int assigned[4];
4912 int i, j;
4913
4914 memset(assigned, 0, sizeof(assigned));
b0af0de5 4915 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4916
4917 /* check the pins hardwired to audio widget */
4918 for (i = 0; i < cfg->line_outs; i++) {
4919 nid = cfg->line_out_pins[i];
4920 if (alc880_is_fixed_pin(nid)) {
4921 int idx = alc880_fixed_pin_idx(nid);
5014f193 4922 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4923 assigned[idx] = 1;
4924 }
4925 }
4926 /* left pins can be connect to any audio widget */
4927 for (i = 0; i < cfg->line_outs; i++) {
4928 nid = cfg->line_out_pins[i];
4929 if (alc880_is_fixed_pin(nid))
4930 continue;
4931 /* search for an empty channel */
4932 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4933 if (!assigned[j]) {
4934 spec->multiout.dac_nids[i] =
4935 alc880_idx_to_dac(j);
e9edcee0
TI
4936 assigned[j] = 1;
4937 break;
4938 }
4939 }
4940 }
4941 spec->multiout.num_dacs = cfg->line_outs;
4942 return 0;
4943}
4944
4945/* add playback controls from the parsed DAC table */
df694daa
KY
4946static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4947 const struct auto_pin_cfg *cfg)
e9edcee0 4948{
f12ab1e0
TI
4949 static const char *chname[4] = {
4950 "Front", "Surround", NULL /*CLFE*/, "Side"
4951 };
e9edcee0
TI
4952 hda_nid_t nid;
4953 int i, err;
4954
4955 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4956 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4957 continue;
4958 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4959 if (i == 2) {
4960 /* Center/LFE */
0afe5f89
TI
4961 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4962 "Center",
f12ab1e0
TI
4963 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4964 HDA_OUTPUT));
4965 if (err < 0)
e9edcee0 4966 return err;
0afe5f89
TI
4967 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4968 "LFE",
f12ab1e0
TI
4969 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4970 HDA_OUTPUT));
4971 if (err < 0)
e9edcee0 4972 return err;
0afe5f89
TI
4973 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4974 "Center",
f12ab1e0
TI
4975 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4976 HDA_INPUT));
4977 if (err < 0)
e9edcee0 4978 return err;
0afe5f89
TI
4979 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4980 "LFE",
f12ab1e0
TI
4981 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4982 HDA_INPUT));
4983 if (err < 0)
e9edcee0
TI
4984 return err;
4985 } else {
cb162b6b
TI
4986 const char *pfx;
4987 if (cfg->line_outs == 1 &&
4988 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4989 pfx = "Speaker";
4990 else
4991 pfx = chname[i];
0afe5f89 4992 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4993 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4994 HDA_OUTPUT));
4995 if (err < 0)
e9edcee0 4996 return err;
0afe5f89 4997 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4998 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4999 HDA_INPUT));
5000 if (err < 0)
e9edcee0
TI
5001 return err;
5002 }
5003 }
e9edcee0
TI
5004 return 0;
5005}
5006
8d88bc3d
TI
5007/* add playback controls for speaker and HP outputs */
5008static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5009 const char *pfx)
e9edcee0
TI
5010{
5011 hda_nid_t nid;
5012 int err;
5013
f12ab1e0 5014 if (!pin)
e9edcee0
TI
5015 return 0;
5016
5017 if (alc880_is_fixed_pin(pin)) {
5018 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5019 /* specify the DAC as the extra output */
f12ab1e0 5020 if (!spec->multiout.hp_nid)
e9edcee0 5021 spec->multiout.hp_nid = nid;
82bc955f
TI
5022 else
5023 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5024 /* control HP volume/switch on the output mixer amp */
5025 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5026 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5027 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5028 if (err < 0)
e9edcee0 5029 return err;
0afe5f89 5030 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5031 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5032 if (err < 0)
e9edcee0
TI
5033 return err;
5034 } else if (alc880_is_multi_pin(pin)) {
5035 /* set manual connection */
e9edcee0 5036 /* we have only a switch on HP-out PIN */
0afe5f89 5037 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5038 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5039 if (err < 0)
e9edcee0
TI
5040 return err;
5041 }
5042 return 0;
5043}
5044
5045/* create input playback/capture controls for the given pin */
f12ab1e0 5046static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5047 const char *ctlname, int ctlidx,
df694daa 5048 int idx, hda_nid_t mix_nid)
e9edcee0 5049{
df694daa 5050 int err;
e9edcee0 5051
66ceeb6b 5052 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5053 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5054 if (err < 0)
e9edcee0 5055 return err;
66ceeb6b 5056 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5057 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5058 if (err < 0)
e9edcee0
TI
5059 return err;
5060 return 0;
5061}
5062
05f5f477
TI
5063static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5064{
5065 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5066 return (pincap & AC_PINCAP_IN) != 0;
5067}
5068
e9edcee0 5069/* create playback/capture controls for input pins */
05f5f477
TI
5070static int alc_auto_create_input_ctls(struct hda_codec *codec,
5071 const struct auto_pin_cfg *cfg,
5072 hda_nid_t mixer,
5073 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5074{
05f5f477 5075 struct alc_spec *spec = codec->spec;
61b9b9b1 5076 struct hda_input_mux *imux = &spec->private_imux[0];
66ceeb6b 5077 int i, err, idx, type, type_idx = 0;
e9edcee0 5078
66ceeb6b 5079 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5080 hda_nid_t pin;
10a20af7 5081 const char *label;
05f5f477 5082
66ceeb6b 5083 pin = cfg->inputs[i].pin;
05f5f477
TI
5084 if (!alc_is_input_pin(codec, pin))
5085 continue;
5086
66ceeb6b
TI
5087 type = cfg->inputs[i].type;
5088 if (i > 0 && type == cfg->inputs[i - 1].type)
5089 type_idx++;
5090 else
5091 type_idx = 0;
10a20af7 5092 label = hda_get_autocfg_input_label(codec, cfg, i);
05f5f477
TI
5093 if (mixer) {
5094 idx = get_connection_index(codec, mixer, pin);
5095 if (idx >= 0) {
5096 err = new_analog_input(spec, pin,
10a20af7
TI
5097 label, type_idx,
5098 idx, mixer);
05f5f477
TI
5099 if (err < 0)
5100 return err;
5101 }
5102 }
5103
5104 if (!cap1)
5105 continue;
5106 idx = get_connection_index(codec, cap1, pin);
5107 if (idx < 0 && cap2)
5108 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5109 if (idx >= 0)
5110 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5111 }
5112 return 0;
5113}
5114
05f5f477
TI
5115static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5116 const struct auto_pin_cfg *cfg)
5117{
5118 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5119}
5120
f6c7e546
TI
5121static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5122 unsigned int pin_type)
5123{
5124 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5125 pin_type);
5126 /* unmute pin */
d260cdf6
TI
5127 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5128 AMP_OUT_UNMUTE);
f6c7e546
TI
5129}
5130
df694daa
KY
5131static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5132 hda_nid_t nid, int pin_type,
e9edcee0
TI
5133 int dac_idx)
5134{
f6c7e546 5135 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5136 /* need the manual connection? */
5137 if (alc880_is_multi_pin(nid)) {
5138 struct alc_spec *spec = codec->spec;
5139 int idx = alc880_multi_pin_idx(nid);
5140 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5141 AC_VERB_SET_CONNECT_SEL,
5142 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5143 }
5144}
5145
baba8ee9
TI
5146static int get_pin_type(int line_out_type)
5147{
5148 if (line_out_type == AUTO_PIN_HP_OUT)
5149 return PIN_HP;
5150 else
5151 return PIN_OUT;
5152}
5153
e9edcee0
TI
5154static void alc880_auto_init_multi_out(struct hda_codec *codec)
5155{
5156 struct alc_spec *spec = codec->spec;
5157 int i;
ea1fb29a 5158
e9edcee0
TI
5159 for (i = 0; i < spec->autocfg.line_outs; i++) {
5160 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5161 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5162 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5163 }
5164}
5165
8d88bc3d 5166static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5167{
5168 struct alc_spec *spec = codec->spec;
5169 hda_nid_t pin;
5170
82bc955f 5171 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5172 if (pin) /* connect to front */
5173 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5174 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5175 if (pin) /* connect to front */
5176 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5177}
5178
5179static void alc880_auto_init_analog_input(struct hda_codec *codec)
5180{
5181 struct alc_spec *spec = codec->spec;
66ceeb6b 5182 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5183 int i;
5184
66ceeb6b
TI
5185 for (i = 0; i < cfg->num_inputs; i++) {
5186 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5187 if (alc_is_input_pin(codec, nid)) {
30ea098f 5188 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5189 if (nid != ALC880_PIN_CD_NID &&
5190 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5191 snd_hda_codec_write(codec, nid, 0,
5192 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5193 AMP_OUT_MUTE);
5194 }
5195 }
5196}
5197
7f311a46
TI
5198static void alc880_auto_init_input_src(struct hda_codec *codec)
5199{
5200 struct alc_spec *spec = codec->spec;
5201 int c;
5202
5203 for (c = 0; c < spec->num_adc_nids; c++) {
5204 unsigned int mux_idx;
5205 const struct hda_input_mux *imux;
5206 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5207 imux = &spec->input_mux[mux_idx];
5208 if (!imux->num_items && mux_idx > 0)
5209 imux = &spec->input_mux[0];
5210 if (imux)
5211 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5212 AC_VERB_SET_CONNECT_SEL,
5213 imux->items[0].index);
5214 }
5215}
5216
e9edcee0 5217/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5218/* return 1 if successful, 0 if the proper config is not found,
5219 * or a negative error code
5220 */
e9edcee0
TI
5221static int alc880_parse_auto_config(struct hda_codec *codec)
5222{
5223 struct alc_spec *spec = codec->spec;
757899ac 5224 int err;
df694daa 5225 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5226
f12ab1e0
TI
5227 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5228 alc880_ignore);
5229 if (err < 0)
e9edcee0 5230 return err;
f12ab1e0 5231 if (!spec->autocfg.line_outs)
e9edcee0 5232 return 0; /* can't find valid BIOS pin config */
df694daa 5233
f12ab1e0
TI
5234 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5235 if (err < 0)
5236 return err;
5237 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5238 if (err < 0)
5239 return err;
5240 err = alc880_auto_create_extra_out(spec,
5241 spec->autocfg.speaker_pins[0],
5242 "Speaker");
5243 if (err < 0)
5244 return err;
5245 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5246 "Headphone");
5247 if (err < 0)
5248 return err;
05f5f477 5249 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5250 if (err < 0)
e9edcee0
TI
5251 return err;
5252
5253 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5254
757899ac 5255 alc_auto_parse_digital(codec);
e9edcee0 5256
603c4019 5257 if (spec->kctls.list)
d88897ea 5258 add_mixer(spec, spec->kctls.list);
e9edcee0 5259
d88897ea 5260 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5261
a1e8d2da 5262 spec->num_mux_defs = 1;
61b9b9b1 5263 spec->input_mux = &spec->private_imux[0];
e9edcee0 5264
6227cdce 5265 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5266
e9edcee0
TI
5267 return 1;
5268}
5269
ae6b813a
TI
5270/* additional initialization for auto-configuration model */
5271static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5272{
f6c7e546 5273 struct alc_spec *spec = codec->spec;
e9edcee0 5274 alc880_auto_init_multi_out(codec);
8d88bc3d 5275 alc880_auto_init_extra_out(codec);
e9edcee0 5276 alc880_auto_init_analog_input(codec);
7f311a46 5277 alc880_auto_init_input_src(codec);
757899ac 5278 alc_auto_init_digital(codec);
f6c7e546 5279 if (spec->unsol_event)
7fb0d78f 5280 alc_inithook(codec);
e9edcee0
TI
5281}
5282
b59bdf3b
TI
5283/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5284 * one of two digital mic pins, e.g. on ALC272
5285 */
5286static void fixup_automic_adc(struct hda_codec *codec)
5287{
5288 struct alc_spec *spec = codec->spec;
5289 int i;
5290
5291 for (i = 0; i < spec->num_adc_nids; i++) {
5292 hda_nid_t cap = spec->capsrc_nids ?
5293 spec->capsrc_nids[i] : spec->adc_nids[i];
5294 int iidx, eidx;
5295
5296 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5297 if (iidx < 0)
5298 continue;
5299 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5300 if (eidx < 0)
5301 continue;
5302 spec->int_mic.mux_idx = iidx;
5303 spec->ext_mic.mux_idx = eidx;
5304 if (spec->capsrc_nids)
5305 spec->capsrc_nids += i;
5306 spec->adc_nids += i;
5307 spec->num_adc_nids = 1;
5308 return;
5309 }
5310 snd_printd(KERN_INFO "hda_codec: %s: "
5311 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5312 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5313 spec->auto_mic = 0; /* disable auto-mic to be sure */
5314}
5315
748cce43
TI
5316/* select or unmute the given capsrc route */
5317static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5318 int idx)
5319{
5320 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5321 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5322 HDA_AMP_MUTE, 0);
5323 } else {
5324 snd_hda_codec_write_cache(codec, cap, 0,
5325 AC_VERB_SET_CONNECT_SEL, idx);
5326 }
5327}
5328
840b64c0
TI
5329/* set the default connection to that pin */
5330static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5331{
5332 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5333 int i;
5334
eaa9b3a7
TI
5335 for (i = 0; i < spec->num_adc_nids; i++) {
5336 hda_nid_t cap = spec->capsrc_nids ?
5337 spec->capsrc_nids[i] : spec->adc_nids[i];
5338 int idx;
5339
5340 idx = get_connection_index(codec, cap, pin);
5341 if (idx < 0)
5342 continue;
748cce43 5343 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5344 return i; /* return the found index */
5345 }
5346 return -1; /* not found */
5347}
5348
5349/* choose the ADC/MUX containing the input pin and initialize the setup */
5350static void fixup_single_adc(struct hda_codec *codec)
5351{
5352 struct alc_spec *spec = codec->spec;
66ceeb6b 5353 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5354 int i;
5355
5356 /* search for the input pin; there must be only one */
66ceeb6b 5357 if (cfg->num_inputs != 1)
eaa9b3a7 5358 return;
66ceeb6b 5359 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5360 if (i >= 0) {
5361 /* use only this ADC */
5362 if (spec->capsrc_nids)
5363 spec->capsrc_nids += i;
5364 spec->adc_nids += i;
5365 spec->num_adc_nids = 1;
eaa9b3a7
TI
5366 }
5367}
5368
840b64c0
TI
5369/* initialize dual adcs */
5370static void fixup_dual_adc_switch(struct hda_codec *codec)
5371{
5372 struct alc_spec *spec = codec->spec;
5373 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5374 init_capsrc_for_pin(codec, spec->int_mic.pin);
5375}
5376
b59bdf3b 5377static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5378{
b59bdf3b 5379 struct alc_spec *spec = codec->spec;
a23b688f
TI
5380 static struct snd_kcontrol_new *caps[2][3] = {
5381 { alc_capture_mixer_nosrc1,
5382 alc_capture_mixer_nosrc2,
5383 alc_capture_mixer_nosrc3 },
5384 { alc_capture_mixer1,
5385 alc_capture_mixer2,
5386 alc_capture_mixer3 },
f9e336f6 5387 };
a23b688f 5388 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5389 int mux = 0;
840b64c0
TI
5390 int num_adcs = spec->num_adc_nids;
5391 if (spec->dual_adc_switch)
5392 fixup_dual_adc_switch(codec);
5393 else if (spec->auto_mic)
b59bdf3b 5394 fixup_automic_adc(codec);
eaa9b3a7
TI
5395 else if (spec->input_mux) {
5396 if (spec->input_mux->num_items > 1)
5397 mux = 1;
5398 else if (spec->input_mux->num_items == 1)
5399 fixup_single_adc(codec);
5400 }
840b64c0
TI
5401 if (spec->dual_adc_switch)
5402 num_adcs = 1;
5403 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5404 }
f9e336f6
TI
5405}
5406
6694635d
TI
5407/* fill adc_nids (and capsrc_nids) containing all active input pins */
5408static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5409 int num_nids)
5410{
5411 struct alc_spec *spec = codec->spec;
66ceeb6b 5412 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5413 int n;
5414 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5415
5416 for (n = 0; n < num_nids; n++) {
5417 hda_nid_t adc, cap;
5418 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5419 int nconns, i, j;
5420
5421 adc = nids[n];
5422 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5423 continue;
5424 cap = adc;
5425 nconns = snd_hda_get_connections(codec, cap, conn,
5426 ARRAY_SIZE(conn));
5427 if (nconns == 1) {
5428 cap = conn[0];
5429 nconns = snd_hda_get_connections(codec, cap, conn,
5430 ARRAY_SIZE(conn));
5431 }
5432 if (nconns <= 0)
5433 continue;
5434 if (!fallback_adc) {
5435 fallback_adc = adc;
5436 fallback_cap = cap;
5437 }
66ceeb6b
TI
5438 for (i = 0; i < cfg->num_inputs; i++) {
5439 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5440 for (j = 0; j < nconns; j++) {
5441 if (conn[j] == nid)
5442 break;
5443 }
5444 if (j >= nconns)
5445 break;
5446 }
66ceeb6b 5447 if (i >= cfg->num_inputs) {
6694635d
TI
5448 int num_adcs = spec->num_adc_nids;
5449 spec->private_adc_nids[num_adcs] = adc;
5450 spec->private_capsrc_nids[num_adcs] = cap;
5451 spec->num_adc_nids++;
5452 spec->adc_nids = spec->private_adc_nids;
5453 if (adc != cap)
5454 spec->capsrc_nids = spec->private_capsrc_nids;
5455 }
5456 }
5457 if (!spec->num_adc_nids) {
5458 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5459 " using fallback 0x%x\n",
5460 codec->chip_name, fallback_adc);
6694635d
TI
5461 spec->private_adc_nids[0] = fallback_adc;
5462 spec->adc_nids = spec->private_adc_nids;
5463 if (fallback_adc != fallback_cap) {
5464 spec->private_capsrc_nids[0] = fallback_cap;
5465 spec->capsrc_nids = spec->private_adc_nids;
5466 }
5467 }
5468}
5469
67d634c0 5470#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5471#define set_beep_amp(spec, nid, idx, dir) \
5472 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5473
5474static struct snd_pci_quirk beep_white_list[] = {
5475 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5476 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5477 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5478 {}
5479};
5480
5481static inline int has_cdefine_beep(struct hda_codec *codec)
5482{
5483 struct alc_spec *spec = codec->spec;
5484 const struct snd_pci_quirk *q;
5485 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5486 if (q)
5487 return q->value;
5488 return spec->cdefine.enable_pcbeep;
5489}
67d634c0
TI
5490#else
5491#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5492#define has_cdefine_beep(codec) 0
67d634c0 5493#endif
45bdd1c1
TI
5494
5495/*
5496 * OK, here we have finally the patch for ALC880
5497 */
5498
1da177e4
LT
5499static int patch_alc880(struct hda_codec *codec)
5500{
5501 struct alc_spec *spec;
5502 int board_config;
df694daa 5503 int err;
1da177e4 5504
e560d8d8 5505 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5506 if (spec == NULL)
5507 return -ENOMEM;
5508
5509 codec->spec = spec;
5510
f5fcc13c
TI
5511 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5512 alc880_models,
5513 alc880_cfg_tbl);
5514 if (board_config < 0) {
9a11f1aa
TI
5515 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5516 codec->chip_name);
e9edcee0 5517 board_config = ALC880_AUTO;
1da177e4 5518 }
1da177e4 5519
e9edcee0
TI
5520 if (board_config == ALC880_AUTO) {
5521 /* automatic parse from the BIOS config */
5522 err = alc880_parse_auto_config(codec);
5523 if (err < 0) {
5524 alc_free(codec);
5525 return err;
f12ab1e0 5526 } else if (!err) {
9c7f852e
TI
5527 printk(KERN_INFO
5528 "hda_codec: Cannot set up configuration "
5529 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5530 board_config = ALC880_3ST;
5531 }
1da177e4
LT
5532 }
5533
680cd536
KK
5534 err = snd_hda_attach_beep_device(codec, 0x1);
5535 if (err < 0) {
5536 alc_free(codec);
5537 return err;
5538 }
5539
df694daa 5540 if (board_config != ALC880_AUTO)
e9c364c0 5541 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5542
1da177e4
LT
5543 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5544 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5545 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5546
1da177e4
LT
5547 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5548 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5549
f12ab1e0 5550 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5551 /* check whether NID 0x07 is valid */
54d17403 5552 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5553 /* get type */
a22d543a 5554 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5555 if (wcap != AC_WID_AUD_IN) {
5556 spec->adc_nids = alc880_adc_nids_alt;
5557 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5558 } else {
5559 spec->adc_nids = alc880_adc_nids;
5560 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5561 }
5562 }
b59bdf3b 5563 set_capture_mixer(codec);
45bdd1c1 5564 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5565
2134ea4f
TI
5566 spec->vmaster_nid = 0x0c;
5567
1da177e4 5568 codec->patch_ops = alc_patch_ops;
e9edcee0 5569 if (board_config == ALC880_AUTO)
ae6b813a 5570 spec->init_hook = alc880_auto_init;
cb53c626
TI
5571#ifdef CONFIG_SND_HDA_POWER_SAVE
5572 if (!spec->loopback.amplist)
5573 spec->loopback.amplist = alc880_loopbacks;
5574#endif
1da177e4
LT
5575
5576 return 0;
5577}
5578
e9edcee0 5579
1da177e4
LT
5580/*
5581 * ALC260 support
5582 */
5583
e9edcee0
TI
5584static hda_nid_t alc260_dac_nids[1] = {
5585 /* front */
5586 0x02,
5587};
5588
5589static hda_nid_t alc260_adc_nids[1] = {
5590 /* ADC0 */
5591 0x04,
5592};
5593
df694daa 5594static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5595 /* ADC1 */
5596 0x05,
5597};
5598
d57fdac0
JW
5599/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5600 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5601 */
5602static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5603 /* ADC0, ADC1 */
5604 0x04, 0x05
5605};
5606
e9edcee0
TI
5607#define ALC260_DIGOUT_NID 0x03
5608#define ALC260_DIGIN_NID 0x06
5609
5610static struct hda_input_mux alc260_capture_source = {
5611 .num_items = 4,
5612 .items = {
5613 { "Mic", 0x0 },
5614 { "Front Mic", 0x1 },
5615 { "Line", 0x2 },
5616 { "CD", 0x4 },
5617 },
5618};
5619
17e7aec6 5620/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5621 * headphone jack and the internal CD lines since these are the only pins at
5622 * which audio can appear. For flexibility, also allow the option of
5623 * recording the mixer output on the second ADC (ADC0 doesn't have a
5624 * connection to the mixer output).
a9430dd8 5625 */
a1e8d2da
JW
5626static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5627 {
5628 .num_items = 3,
5629 .items = {
5630 { "Mic/Line", 0x0 },
5631 { "CD", 0x4 },
5632 { "Headphone", 0x2 },
5633 },
a9430dd8 5634 },
a1e8d2da
JW
5635 {
5636 .num_items = 4,
5637 .items = {
5638 { "Mic/Line", 0x0 },
5639 { "CD", 0x4 },
5640 { "Headphone", 0x2 },
5641 { "Mixer", 0x5 },
5642 },
5643 },
5644
a9430dd8
JW
5645};
5646
a1e8d2da
JW
5647/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5648 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5649 */
a1e8d2da
JW
5650static struct hda_input_mux alc260_acer_capture_sources[2] = {
5651 {
5652 .num_items = 4,
5653 .items = {
5654 { "Mic", 0x0 },
5655 { "Line", 0x2 },
5656 { "CD", 0x4 },
5657 { "Headphone", 0x5 },
5658 },
5659 },
5660 {
5661 .num_items = 5,
5662 .items = {
5663 { "Mic", 0x0 },
5664 { "Line", 0x2 },
5665 { "CD", 0x4 },
5666 { "Headphone", 0x6 },
5667 { "Mixer", 0x5 },
5668 },
0bfc90e9
JW
5669 },
5670};
cc959489
MS
5671
5672/* Maxdata Favorit 100XS */
5673static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5674 {
5675 .num_items = 2,
5676 .items = {
5677 { "Line/Mic", 0x0 },
5678 { "CD", 0x4 },
5679 },
5680 },
5681 {
5682 .num_items = 3,
5683 .items = {
5684 { "Line/Mic", 0x0 },
5685 { "CD", 0x4 },
5686 { "Mixer", 0x5 },
5687 },
5688 },
5689};
5690
1da177e4
LT
5691/*
5692 * This is just place-holder, so there's something for alc_build_pcms to look
5693 * at when it calculates the maximum number of channels. ALC260 has no mixer
5694 * element which allows changing the channel mode, so the verb list is
5695 * never used.
5696 */
d2a6d7dc 5697static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5698 { 2, NULL },
5699};
5700
df694daa
KY
5701
5702/* Mixer combinations
5703 *
5704 * basic: base_output + input + pc_beep + capture
5705 * HP: base_output + input + capture_alt
5706 * HP_3013: hp_3013 + input + capture
5707 * fujitsu: fujitsu + capture
0bfc90e9 5708 * acer: acer + capture
df694daa
KY
5709 */
5710
5711static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5712 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5713 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5714 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5715 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5716 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5717 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5718 { } /* end */
f12ab1e0 5719};
1da177e4 5720
df694daa 5721static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5722 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5723 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5724 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5725 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5727 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5728 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5729 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5730 { } /* end */
5731};
5732
bec15c3a
TI
5733/* update HP, line and mono out pins according to the master switch */
5734static void alc260_hp_master_update(struct hda_codec *codec,
5735 hda_nid_t hp, hda_nid_t line,
5736 hda_nid_t mono)
5737{
5738 struct alc_spec *spec = codec->spec;
5739 unsigned int val = spec->master_sw ? PIN_HP : 0;
5740 /* change HP and line-out pins */
30cde0aa 5741 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5742 val);
30cde0aa 5743 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5744 val);
5745 /* mono (speaker) depending on the HP jack sense */
5746 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5747 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5748 val);
5749}
5750
5751static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5752 struct snd_ctl_elem_value *ucontrol)
5753{
5754 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5755 struct alc_spec *spec = codec->spec;
5756 *ucontrol->value.integer.value = spec->master_sw;
5757 return 0;
5758}
5759
5760static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5761 struct snd_ctl_elem_value *ucontrol)
5762{
5763 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5764 struct alc_spec *spec = codec->spec;
5765 int val = !!*ucontrol->value.integer.value;
5766 hda_nid_t hp, line, mono;
5767
5768 if (val == spec->master_sw)
5769 return 0;
5770 spec->master_sw = val;
5771 hp = (kcontrol->private_value >> 16) & 0xff;
5772 line = (kcontrol->private_value >> 8) & 0xff;
5773 mono = kcontrol->private_value & 0xff;
5774 alc260_hp_master_update(codec, hp, line, mono);
5775 return 1;
5776}
5777
5778static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5779 {
5780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5781 .name = "Master Playback Switch",
5b0cb1d8 5782 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5783 .info = snd_ctl_boolean_mono_info,
5784 .get = alc260_hp_master_sw_get,
5785 .put = alc260_hp_master_sw_put,
5786 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5787 },
5788 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5789 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5790 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5791 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5792 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5793 HDA_OUTPUT),
5794 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5795 { } /* end */
5796};
5797
5798static struct hda_verb alc260_hp_unsol_verbs[] = {
5799 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5800 {},
5801};
5802
5803static void alc260_hp_automute(struct hda_codec *codec)
5804{
5805 struct alc_spec *spec = codec->spec;
bec15c3a 5806
864f92be 5807 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5808 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5809}
5810
5811static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5812{
5813 if ((res >> 26) == ALC880_HP_EVENT)
5814 alc260_hp_automute(codec);
5815}
5816
df694daa 5817static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5818 {
5819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5820 .name = "Master Playback Switch",
5b0cb1d8 5821 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5822 .info = snd_ctl_boolean_mono_info,
5823 .get = alc260_hp_master_sw_get,
5824 .put = alc260_hp_master_sw_put,
30cde0aa 5825 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5826 },
df694daa
KY
5827 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5828 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5829 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5830 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5831 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5832 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5833 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5834 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5835 { } /* end */
5836};
5837
3f878308
KY
5838static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5839 .ops = &snd_hda_bind_vol,
5840 .values = {
5841 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5842 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5843 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5844 0
5845 },
5846};
5847
5848static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5849 .ops = &snd_hda_bind_sw,
5850 .values = {
5851 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5852 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5853 0
5854 },
5855};
5856
5857static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5858 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5859 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5860 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5861 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5862 { } /* end */
5863};
5864
bec15c3a
TI
5865static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5866 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5867 {},
5868};
5869
5870static void alc260_hp_3013_automute(struct hda_codec *codec)
5871{
5872 struct alc_spec *spec = codec->spec;
bec15c3a 5873
864f92be 5874 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5875 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5876}
5877
5878static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5879 unsigned int res)
5880{
5881 if ((res >> 26) == ALC880_HP_EVENT)
5882 alc260_hp_3013_automute(codec);
5883}
5884
3f878308
KY
5885static void alc260_hp_3012_automute(struct hda_codec *codec)
5886{
864f92be 5887 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5888
3f878308
KY
5889 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5890 bits);
5891 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5892 bits);
5893 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5894 bits);
5895}
5896
5897static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5898 unsigned int res)
5899{
5900 if ((res >> 26) == ALC880_HP_EVENT)
5901 alc260_hp_3012_automute(codec);
5902}
5903
5904/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5905 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5906 */
c8b6bf9b 5907static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5908 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5909 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5910 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5911 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5912 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5913 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5914 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5915 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5916 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5917 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5918 { } /* end */
5919};
5920
a1e8d2da
JW
5921/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5922 * versions of the ALC260 don't act on requests to enable mic bias from NID
5923 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5924 * datasheet doesn't mention this restriction. At this stage it's not clear
5925 * whether this behaviour is intentional or is a hardware bug in chip
5926 * revisions available in early 2006. Therefore for now allow the
5927 * "Headphone Jack Mode" control to span all choices, but if it turns out
5928 * that the lack of mic bias for this NID is intentional we could change the
5929 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5930 *
5931 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5932 * don't appear to make the mic bias available from the "line" jack, even
5933 * though the NID used for this jack (0x14) can supply it. The theory is
5934 * that perhaps Acer have included blocking capacitors between the ALC260
5935 * and the output jack. If this turns out to be the case for all such
5936 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5937 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5938 *
5939 * The C20x Tablet series have a mono internal speaker which is controlled
5940 * via the chip's Mono sum widget and pin complex, so include the necessary
5941 * controls for such models. On models without a "mono speaker" the control
5942 * won't do anything.
a1e8d2da 5943 */
0bfc90e9
JW
5944static struct snd_kcontrol_new alc260_acer_mixer[] = {
5945 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5946 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5947 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5948 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5949 HDA_OUTPUT),
31bffaa9 5950 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5951 HDA_INPUT),
0bfc90e9
JW
5952 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5953 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5954 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5955 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5956 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5957 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5958 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5959 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5960 { } /* end */
5961};
5962
cc959489
MS
5963/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5964 */
5965static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5966 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5967 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5968 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5969 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5970 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5971 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5972 { } /* end */
5973};
5974
bc9f98a9
KY
5975/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5976 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5977 */
5978static struct snd_kcontrol_new alc260_will_mixer[] = {
5979 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5980 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5981 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5982 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5983 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5984 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5985 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5986 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5987 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5988 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5989 { } /* end */
5990};
5991
5992/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5993 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5994 */
5995static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5996 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5997 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5998 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5999 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6000 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6001 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6002 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6003 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6004 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6005 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6006 { } /* end */
6007};
6008
df694daa
KY
6009/*
6010 * initialization verbs
6011 */
1da177e4
LT
6012static struct hda_verb alc260_init_verbs[] = {
6013 /* Line In pin widget for input */
05acb863 6014 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6015 /* CD pin widget for input */
05acb863 6016 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6017 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6018 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6019 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6020 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6021 /* LINE-2 is used for line-out in rear */
05acb863 6022 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6023 /* select line-out */
fd56f2db 6024 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6025 /* LINE-OUT pin */
05acb863 6026 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6027 /* enable HP */
05acb863 6028 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6029 /* enable Mono */
05acb863
TI
6030 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6031 /* mute capture amp left and right */
16ded525 6032 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6033 /* set connection select to line in (default select for this ADC) */
6034 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6035 /* mute capture amp left and right */
6036 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6037 /* set connection select to line in (default select for this ADC) */
6038 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6039 /* set vol=0 Line-Out mixer amp left and right */
6040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6041 /* unmute pin widget amp left and right (no gain on this amp) */
6042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6043 /* set vol=0 HP mixer amp left and right */
6044 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6045 /* unmute pin widget amp left and right (no gain on this amp) */
6046 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6047 /* set vol=0 Mono mixer amp left and right */
6048 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6049 /* unmute pin widget amp left and right (no gain on this amp) */
6050 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6051 /* unmute LINE-2 out pin */
6052 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6053 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6054 * Line In 2 = 0x03
6055 */
cb53c626
TI
6056 /* mute analog inputs */
6057 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6058 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6062 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6063 /* mute Front out path */
6064 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6065 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6066 /* mute Headphone out path */
6067 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6068 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6069 /* mute Mono out path */
6070 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6071 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6072 { }
6073};
6074
474167d6 6075#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6076static struct hda_verb alc260_hp_init_verbs[] = {
6077 /* Headphone and output */
6078 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6079 /* mono output */
6080 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6081 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6082 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6083 /* Mic2 (front panel) pin widget for input and vref at 80% */
6084 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6085 /* Line In pin widget for input */
6086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6087 /* Line-2 pin widget for output */
6088 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6089 /* CD pin widget for input */
6090 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6091 /* unmute amp left and right */
6092 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6093 /* set connection select to line in (default select for this ADC) */
6094 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6095 /* unmute Line-Out mixer amp left and right (volume = 0) */
6096 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6097 /* mute pin widget amp left and right (no gain on this amp) */
6098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6099 /* unmute HP mixer amp left and right (volume = 0) */
6100 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6101 /* mute pin widget amp left and right (no gain on this amp) */
6102 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6103 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6104 * Line In 2 = 0x03
6105 */
cb53c626
TI
6106 /* mute analog inputs */
6107 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6108 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6109 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6110 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6112 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6113 /* Unmute Front out path */
6114 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6115 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6116 /* Unmute Headphone out path */
6117 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6118 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6119 /* Unmute Mono out path */
6120 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6121 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6122 { }
6123};
474167d6 6124#endif
df694daa
KY
6125
6126static struct hda_verb alc260_hp_3013_init_verbs[] = {
6127 /* Line out and output */
6128 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6129 /* mono output */
6130 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6131 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6132 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6133 /* Mic2 (front panel) pin widget for input and vref at 80% */
6134 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6135 /* Line In pin widget for input */
6136 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6137 /* Headphone pin widget for output */
6138 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6139 /* CD pin widget for input */
6140 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6141 /* unmute amp left and right */
6142 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6143 /* set connection select to line in (default select for this ADC) */
6144 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6145 /* unmute Line-Out mixer amp left and right (volume = 0) */
6146 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6147 /* mute pin widget amp left and right (no gain on this amp) */
6148 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6149 /* unmute HP mixer amp left and right (volume = 0) */
6150 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6151 /* mute pin widget amp left and right (no gain on this amp) */
6152 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6153 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6154 * Line In 2 = 0x03
6155 */
cb53c626
TI
6156 /* mute analog inputs */
6157 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6158 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6159 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6160 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6162 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6163 /* Unmute Front out path */
6164 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6165 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6166 /* Unmute Headphone out path */
6167 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6168 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6169 /* Unmute Mono out path */
6170 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6171 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6172 { }
6173};
6174
a9430dd8 6175/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6176 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6177 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6178 */
6179static struct hda_verb alc260_fujitsu_init_verbs[] = {
6180 /* Disable all GPIOs */
6181 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6182 /* Internal speaker is connected to headphone pin */
6183 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6184 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6186 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6187 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6188 /* Ensure all other unused pins are disabled and muted. */
6189 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6190 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6191 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6192 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6193 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6194 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6195 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6196 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6197
6198 /* Disable digital (SPDIF) pins */
6199 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6200 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6201
ea1fb29a 6202 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6203 * when acting as an output.
6204 */
6205 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6206
f7ace40d 6207 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6208 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6209 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6210 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6211 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6212 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6213 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6214 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6215 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6216 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6217
f7ace40d
JW
6218 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6219 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6220 /* Unmute Line1 pin widget output buffer since it starts as an output.
6221 * If the pin mode is changed by the user the pin mode control will
6222 * take care of enabling the pin's input/output buffers as needed.
6223 * Therefore there's no need to enable the input buffer at this
6224 * stage.
cdcd9268 6225 */
f7ace40d 6226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6227 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6228 * mixer ctrl)
6229 */
f7ace40d
JW
6230 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6231
6232 /* Mute capture amp left and right */
6233 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6234 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6235 * in (on mic1 pin)
6236 */
6237 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6238
6239 /* Do the same for the second ADC: mute capture input amp and
6240 * set ADC connection to line in (on mic1 pin)
6241 */
6242 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6243 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6244
6245 /* Mute all inputs to mixer widget (even unconnected ones) */
6246 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6247 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6248 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6249 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6250 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6251 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6252 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6253 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6254
6255 { }
a9430dd8
JW
6256};
6257
0bfc90e9
JW
6258/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6259 * similar laptops (adapted from Fujitsu init verbs).
6260 */
6261static struct hda_verb alc260_acer_init_verbs[] = {
6262 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6263 * the headphone jack. Turn this on and rely on the standard mute
6264 * methods whenever the user wants to turn these outputs off.
6265 */
6266 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6267 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6268 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6269 /* Internal speaker/Headphone jack is connected to Line-out pin */
6270 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6271 /* Internal microphone/Mic jack is connected to Mic1 pin */
6272 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6273 /* Line In jack is connected to Line1 pin */
6274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6275 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6276 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6277 /* Ensure all other unused pins are disabled and muted. */
6278 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6279 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6280 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6281 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6284 /* Disable digital (SPDIF) pins */
6285 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6286 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6287
ea1fb29a 6288 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6289 * bus when acting as outputs.
6290 */
6291 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6292 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6293
6294 /* Start with output sum widgets muted and their output gains at min */
6295 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6296 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6297 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6298 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6299 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6300 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6301 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6302 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6303 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6304
f12ab1e0
TI
6305 /* Unmute Line-out pin widget amp left and right
6306 * (no equiv mixer ctrl)
6307 */
0bfc90e9 6308 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6309 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6310 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6311 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6312 * inputs. If the pin mode is changed by the user the pin mode control
6313 * will take care of enabling the pin's input/output buffers as needed.
6314 * Therefore there's no need to enable the input buffer at this
6315 * stage.
6316 */
6317 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6318 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6319
6320 /* Mute capture amp left and right */
6321 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6322 /* Set ADC connection select to match default mixer setting - mic
6323 * (on mic1 pin)
6324 */
6325 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6326
6327 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6328 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6329 */
6330 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6331 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6332
6333 /* Mute all inputs to mixer widget (even unconnected ones) */
6334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6335 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6336 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6337 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6338 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6339 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6340 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6341 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6342
6343 { }
6344};
6345
cc959489
MS
6346/* Initialisation sequence for Maxdata Favorit 100XS
6347 * (adapted from Acer init verbs).
6348 */
6349static struct hda_verb alc260_favorit100_init_verbs[] = {
6350 /* GPIO 0 enables the output jack.
6351 * Turn this on and rely on the standard mute
6352 * methods whenever the user wants to turn these outputs off.
6353 */
6354 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6355 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6356 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6357 /* Line/Mic input jack is connected to Mic1 pin */
6358 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6359 /* Ensure all other unused pins are disabled and muted. */
6360 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6361 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6362 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6363 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6364 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6365 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6366 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6367 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6369 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6370 /* Disable digital (SPDIF) pins */
6371 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6372 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6373
6374 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6375 * bus when acting as outputs.
6376 */
6377 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6378 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6379
6380 /* Start with output sum widgets muted and their output gains at min */
6381 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6382 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6383 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6384 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6385 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6387 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6388 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6389 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6390
6391 /* Unmute Line-out pin widget amp left and right
6392 * (no equiv mixer ctrl)
6393 */
6394 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6395 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6396 * inputs. If the pin mode is changed by the user the pin mode control
6397 * will take care of enabling the pin's input/output buffers as needed.
6398 * Therefore there's no need to enable the input buffer at this
6399 * stage.
6400 */
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)},
6405 /* Set ADC connection select to match default mixer setting - mic
6406 * (on mic1 pin)
6407 */
6408 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6409
6410 /* Do similar with the second ADC: mute capture input amp and
6411 * set ADC connection to mic to match ALSA's default state.
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 */
6425
6426 { }
6427};
6428
bc9f98a9
KY
6429static struct hda_verb alc260_will_verbs[] = {
6430 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6431 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6432 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6433 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6434 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6435 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6436 {}
6437};
6438
6439static struct hda_verb alc260_replacer_672v_verbs[] = {
6440 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6441 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6442 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6443
6444 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6445 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6446 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6447
6448 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6449 {}
6450};
6451
6452/* toggle speaker-output according to the hp-jack state */
6453static void alc260_replacer_672v_automute(struct hda_codec *codec)
6454{
6455 unsigned int present;
6456
6457 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6458 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6459 if (present) {
82beb8fd
TI
6460 snd_hda_codec_write_cache(codec, 0x01, 0,
6461 AC_VERB_SET_GPIO_DATA, 1);
6462 snd_hda_codec_write_cache(codec, 0x0f, 0,
6463 AC_VERB_SET_PIN_WIDGET_CONTROL,
6464 PIN_HP);
bc9f98a9 6465 } else {
82beb8fd
TI
6466 snd_hda_codec_write_cache(codec, 0x01, 0,
6467 AC_VERB_SET_GPIO_DATA, 0);
6468 snd_hda_codec_write_cache(codec, 0x0f, 0,
6469 AC_VERB_SET_PIN_WIDGET_CONTROL,
6470 PIN_OUT);
bc9f98a9
KY
6471 }
6472}
6473
6474static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6475 unsigned int res)
6476{
6477 if ((res >> 26) == ALC880_HP_EVENT)
6478 alc260_replacer_672v_automute(codec);
6479}
6480
3f878308
KY
6481static struct hda_verb alc260_hp_dc7600_verbs[] = {
6482 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6483 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6484 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6485 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6486 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6488 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6489 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6490 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6491 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6492 {}
6493};
6494
7cf51e48
JW
6495/* Test configuration for debugging, modelled after the ALC880 test
6496 * configuration.
6497 */
6498#ifdef CONFIG_SND_DEBUG
6499static hda_nid_t alc260_test_dac_nids[1] = {
6500 0x02,
6501};
6502static hda_nid_t alc260_test_adc_nids[2] = {
6503 0x04, 0x05,
6504};
a1e8d2da 6505/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6506 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6507 * is NID 0x04.
17e7aec6 6508 */
a1e8d2da
JW
6509static struct hda_input_mux alc260_test_capture_sources[2] = {
6510 {
6511 .num_items = 7,
6512 .items = {
6513 { "MIC1 pin", 0x0 },
6514 { "MIC2 pin", 0x1 },
6515 { "LINE1 pin", 0x2 },
6516 { "LINE2 pin", 0x3 },
6517 { "CD pin", 0x4 },
6518 { "LINE-OUT pin", 0x5 },
6519 { "HP-OUT pin", 0x6 },
6520 },
6521 },
6522 {
6523 .num_items = 8,
6524 .items = {
6525 { "MIC1 pin", 0x0 },
6526 { "MIC2 pin", 0x1 },
6527 { "LINE1 pin", 0x2 },
6528 { "LINE2 pin", 0x3 },
6529 { "CD pin", 0x4 },
6530 { "Mixer", 0x5 },
6531 { "LINE-OUT pin", 0x6 },
6532 { "HP-OUT pin", 0x7 },
6533 },
7cf51e48
JW
6534 },
6535};
6536static struct snd_kcontrol_new alc260_test_mixer[] = {
6537 /* Output driver widgets */
6538 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6539 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6540 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6541 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6542 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6543 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6544
a1e8d2da
JW
6545 /* Modes for retasking pin widgets
6546 * Note: the ALC260 doesn't seem to act on requests to enable mic
6547 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6548 * mention this restriction. At this stage it's not clear whether
6549 * this behaviour is intentional or is a hardware bug in chip
6550 * revisions available at least up until early 2006. Therefore for
6551 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6552 * choices, but if it turns out that the lack of mic bias for these
6553 * NIDs is intentional we could change their modes from
6554 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6555 */
7cf51e48
JW
6556 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6557 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6558 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6559 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6560 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6561 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6562
6563 /* Loopback mixer controls */
6564 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6565 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6566 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6567 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6568 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6569 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6570 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6571 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6572 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6573 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6574 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6575 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6576 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6577 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6578
6579 /* Controls for GPIO pins, assuming they are configured as outputs */
6580 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6581 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6582 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6583 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6584
92621f13
JW
6585 /* Switches to allow the digital IO pins to be enabled. The datasheet
6586 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6587 * make this output available should provide clarification.
92621f13
JW
6588 */
6589 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6590 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6591
f8225f6d
JW
6592 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6593 * this output to turn on an external amplifier.
6594 */
6595 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6596 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6597
7cf51e48
JW
6598 { } /* end */
6599};
6600static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6601 /* Enable all GPIOs as outputs with an initial value of 0 */
6602 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6603 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6604 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6605
7cf51e48
JW
6606 /* Enable retasking pins as output, initially without power amp */
6607 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6608 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6610 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6611 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6612 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6613
92621f13
JW
6614 /* Disable digital (SPDIF) pins initially, but users can enable
6615 * them via a mixer switch. In the case of SPDIF-out, this initverb
6616 * payload also sets the generation to 0, output to be in "consumer"
6617 * PCM format, copyright asserted, no pre-emphasis and no validity
6618 * control.
6619 */
7cf51e48
JW
6620 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6621 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6622
ea1fb29a 6623 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6624 * OUT1 sum bus when acting as an output.
6625 */
6626 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6627 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6628 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6629 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6630
6631 /* Start with output sum widgets muted and their output gains at min */
6632 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6633 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6634 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6635 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6636 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6637 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6638 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6639 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6640 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6641
cdcd9268
JW
6642 /* Unmute retasking pin widget output buffers since the default
6643 * state appears to be output. As the pin mode is changed by the
6644 * user the pin mode control will take care of enabling the pin's
6645 * input/output buffers as needed.
6646 */
7cf51e48
JW
6647 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6648 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6650 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6651 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6652 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6653 /* Also unmute the mono-out pin widget */
6654 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6655
7cf51e48
JW
6656 /* Mute capture amp left and right */
6657 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6658 /* Set ADC connection select to match default mixer setting (mic1
6659 * pin)
7cf51e48
JW
6660 */
6661 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6662
6663 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6664 * set ADC connection to mic1 pin
7cf51e48
JW
6665 */
6666 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6667 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6668
6669 /* Mute all inputs to mixer widget (even unconnected ones) */
6670 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6671 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6672 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6673 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6674 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6675 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6676 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6677 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6678
6679 { }
6680};
6681#endif
6682
6330079f
TI
6683#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6684#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6685
a3bcba38
TI
6686#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6687#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6688
df694daa
KY
6689/*
6690 * for BIOS auto-configuration
6691 */
16ded525 6692
df694daa 6693static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6694 const char *pfx, int *vol_bits)
df694daa
KY
6695{
6696 hda_nid_t nid_vol;
6697 unsigned long vol_val, sw_val;
df694daa
KY
6698 int err;
6699
6700 if (nid >= 0x0f && nid < 0x11) {
6701 nid_vol = nid - 0x7;
6702 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6703 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6704 } else if (nid == 0x11) {
6705 nid_vol = nid - 0x7;
6706 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6707 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6708 } else if (nid >= 0x12 && nid <= 0x15) {
6709 nid_vol = 0x08;
6710 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6711 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6712 } else
6713 return 0; /* N/A */
ea1fb29a 6714
863b4518
TI
6715 if (!(*vol_bits & (1 << nid_vol))) {
6716 /* first control for the volume widget */
0afe5f89 6717 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6718 if (err < 0)
6719 return err;
6720 *vol_bits |= (1 << nid_vol);
6721 }
0afe5f89 6722 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6723 if (err < 0)
df694daa
KY
6724 return err;
6725 return 1;
6726}
6727
6728/* add playback controls from the parsed DAC table */
6729static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6730 const struct auto_pin_cfg *cfg)
6731{
6732 hda_nid_t nid;
6733 int err;
863b4518 6734 int vols = 0;
df694daa
KY
6735
6736 spec->multiout.num_dacs = 1;
6737 spec->multiout.dac_nids = spec->private_dac_nids;
6738 spec->multiout.dac_nids[0] = 0x02;
6739
6740 nid = cfg->line_out_pins[0];
6741 if (nid) {
23112d6d
TI
6742 const char *pfx;
6743 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6744 pfx = "Master";
6745 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6746 pfx = "Speaker";
6747 else
6748 pfx = "Front";
6749 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6750 if (err < 0)
6751 return err;
6752 }
6753
82bc955f 6754 nid = cfg->speaker_pins[0];
df694daa 6755 if (nid) {
863b4518 6756 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6757 if (err < 0)
6758 return err;
6759 }
6760
eb06ed8f 6761 nid = cfg->hp_pins[0];
df694daa 6762 if (nid) {
863b4518
TI
6763 err = alc260_add_playback_controls(spec, nid, "Headphone",
6764 &vols);
df694daa
KY
6765 if (err < 0)
6766 return err;
6767 }
f12ab1e0 6768 return 0;
df694daa
KY
6769}
6770
6771/* create playback/capture controls for input pins */
05f5f477 6772static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6773 const struct auto_pin_cfg *cfg)
6774{
05f5f477 6775 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6776}
6777
6778static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6779 hda_nid_t nid, int pin_type,
6780 int sel_idx)
6781{
f6c7e546 6782 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6783 /* need the manual connection? */
6784 if (nid >= 0x12) {
6785 int idx = nid - 0x12;
6786 snd_hda_codec_write(codec, idx + 0x0b, 0,
6787 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6788 }
6789}
6790
6791static void alc260_auto_init_multi_out(struct hda_codec *codec)
6792{
6793 struct alc_spec *spec = codec->spec;
6794 hda_nid_t nid;
6795
f12ab1e0 6796 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6797 if (nid) {
6798 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6799 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6800 }
ea1fb29a 6801
82bc955f 6802 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6803 if (nid)
6804 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6805
eb06ed8f 6806 nid = spec->autocfg.hp_pins[0];
df694daa 6807 if (nid)
baba8ee9 6808 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6809}
df694daa
KY
6810
6811#define ALC260_PIN_CD_NID 0x16
6812static void alc260_auto_init_analog_input(struct hda_codec *codec)
6813{
6814 struct alc_spec *spec = codec->spec;
66ceeb6b 6815 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6816 int i;
6817
66ceeb6b
TI
6818 for (i = 0; i < cfg->num_inputs; i++) {
6819 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6820 if (nid >= 0x12) {
30ea098f 6821 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6822 if (nid != ALC260_PIN_CD_NID &&
6823 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6824 snd_hda_codec_write(codec, nid, 0,
6825 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6826 AMP_OUT_MUTE);
6827 }
6828 }
6829}
6830
7f311a46
TI
6831#define alc260_auto_init_input_src alc880_auto_init_input_src
6832
df694daa
KY
6833/*
6834 * generic initialization of ADC, input mixers and output mixers
6835 */
6836static struct hda_verb alc260_volume_init_verbs[] = {
6837 /*
6838 * Unmute ADC0-1 and set the default input to mic-in
6839 */
6840 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6841 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6842 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6843 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6844
df694daa
KY
6845 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6846 * mixer widget
f12ab1e0
TI
6847 * Note: PASD motherboards uses the Line In 2 as the input for
6848 * front panel mic (mic 2)
df694daa
KY
6849 */
6850 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6851 /* mute analog inputs */
6852 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6853 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6854 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6855 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6856 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6857
6858 /*
6859 * Set up output mixers (0x08 - 0x0a)
6860 */
6861 /* set vol=0 to output mixers */
6862 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6863 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6864 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6865 /* set up input amps for analog loopback */
6866 /* Amp Indices: DAC = 0, mixer = 1 */
6867 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6868 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6869 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6870 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6871 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6872 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6873
df694daa
KY
6874 { }
6875};
6876
6877static int alc260_parse_auto_config(struct hda_codec *codec)
6878{
6879 struct alc_spec *spec = codec->spec;
df694daa
KY
6880 int err;
6881 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6882
f12ab1e0
TI
6883 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6884 alc260_ignore);
6885 if (err < 0)
df694daa 6886 return err;
f12ab1e0
TI
6887 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6888 if (err < 0)
4a471b7d 6889 return err;
603c4019 6890 if (!spec->kctls.list)
df694daa 6891 return 0; /* can't find valid BIOS pin config */
05f5f477 6892 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6893 if (err < 0)
df694daa
KY
6894 return err;
6895
6896 spec->multiout.max_channels = 2;
6897
0852d7a6 6898 if (spec->autocfg.dig_outs)
df694daa 6899 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6900 if (spec->kctls.list)
d88897ea 6901 add_mixer(spec, spec->kctls.list);
df694daa 6902
d88897ea 6903 add_verb(spec, alc260_volume_init_verbs);
df694daa 6904
a1e8d2da 6905 spec->num_mux_defs = 1;
61b9b9b1 6906 spec->input_mux = &spec->private_imux[0];
df694daa 6907
6227cdce 6908 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6909
df694daa
KY
6910 return 1;
6911}
6912
ae6b813a
TI
6913/* additional initialization for auto-configuration model */
6914static void alc260_auto_init(struct hda_codec *codec)
df694daa 6915{
f6c7e546 6916 struct alc_spec *spec = codec->spec;
df694daa
KY
6917 alc260_auto_init_multi_out(codec);
6918 alc260_auto_init_analog_input(codec);
7f311a46 6919 alc260_auto_init_input_src(codec);
757899ac 6920 alc_auto_init_digital(codec);
f6c7e546 6921 if (spec->unsol_event)
7fb0d78f 6922 alc_inithook(codec);
df694daa
KY
6923}
6924
cb53c626
TI
6925#ifdef CONFIG_SND_HDA_POWER_SAVE
6926static struct hda_amp_list alc260_loopbacks[] = {
6927 { 0x07, HDA_INPUT, 0 },
6928 { 0x07, HDA_INPUT, 1 },
6929 { 0x07, HDA_INPUT, 2 },
6930 { 0x07, HDA_INPUT, 3 },
6931 { 0x07, HDA_INPUT, 4 },
6932 { } /* end */
6933};
6934#endif
6935
fc091769
TI
6936/*
6937 * Pin config fixes
6938 */
6939enum {
6940 PINFIX_HP_DC5750,
6941};
6942
fc091769
TI
6943static const struct alc_fixup alc260_fixups[] = {
6944 [PINFIX_HP_DC5750] = {
73413b12
TI
6945 .pins = (const struct alc_pincfg[]) {
6946 { 0x11, 0x90130110 }, /* speaker */
6947 { }
6948 }
fc091769
TI
6949 },
6950};
6951
6952static struct snd_pci_quirk alc260_fixup_tbl[] = {
6953 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
6954 {}
6955};
6956
df694daa
KY
6957/*
6958 * ALC260 configurations
6959 */
f5fcc13c
TI
6960static const char *alc260_models[ALC260_MODEL_LAST] = {
6961 [ALC260_BASIC] = "basic",
6962 [ALC260_HP] = "hp",
6963 [ALC260_HP_3013] = "hp-3013",
2922c9af 6964 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6965 [ALC260_FUJITSU_S702X] = "fujitsu",
6966 [ALC260_ACER] = "acer",
bc9f98a9
KY
6967 [ALC260_WILL] = "will",
6968 [ALC260_REPLACER_672V] = "replacer",
cc959489 6969 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6970#ifdef CONFIG_SND_DEBUG
f5fcc13c 6971 [ALC260_TEST] = "test",
7cf51e48 6972#endif
f5fcc13c
TI
6973 [ALC260_AUTO] = "auto",
6974};
6975
6976static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6977 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6978 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6979 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6980 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6981 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6982 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6983 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6984 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6985 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6986 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6987 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6988 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6989 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6990 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6991 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6992 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6993 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6994 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6995 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6996 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6997 {}
6998};
6999
7000static struct alc_config_preset alc260_presets[] = {
7001 [ALC260_BASIC] = {
7002 .mixers = { alc260_base_output_mixer,
45bdd1c1 7003 alc260_input_mixer },
df694daa
KY
7004 .init_verbs = { alc260_init_verbs },
7005 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7006 .dac_nids = alc260_dac_nids,
f9e336f6 7007 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7008 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7009 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7010 .channel_mode = alc260_modes,
7011 .input_mux = &alc260_capture_source,
7012 },
7013 [ALC260_HP] = {
bec15c3a 7014 .mixers = { alc260_hp_output_mixer,
f9e336f6 7015 alc260_input_mixer },
bec15c3a
TI
7016 .init_verbs = { alc260_init_verbs,
7017 alc260_hp_unsol_verbs },
df694daa
KY
7018 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7019 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7020 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7021 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7022 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7023 .channel_mode = alc260_modes,
7024 .input_mux = &alc260_capture_source,
bec15c3a
TI
7025 .unsol_event = alc260_hp_unsol_event,
7026 .init_hook = alc260_hp_automute,
df694daa 7027 },
3f878308
KY
7028 [ALC260_HP_DC7600] = {
7029 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7030 alc260_input_mixer },
3f878308
KY
7031 .init_verbs = { alc260_init_verbs,
7032 alc260_hp_dc7600_verbs },
7033 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7034 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7035 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7036 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7037 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7038 .channel_mode = alc260_modes,
7039 .input_mux = &alc260_capture_source,
7040 .unsol_event = alc260_hp_3012_unsol_event,
7041 .init_hook = alc260_hp_3012_automute,
7042 },
df694daa
KY
7043 [ALC260_HP_3013] = {
7044 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7045 alc260_input_mixer },
bec15c3a
TI
7046 .init_verbs = { alc260_hp_3013_init_verbs,
7047 alc260_hp_3013_unsol_verbs },
df694daa
KY
7048 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7049 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7050 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7051 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7052 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7053 .channel_mode = alc260_modes,
7054 .input_mux = &alc260_capture_source,
bec15c3a
TI
7055 .unsol_event = alc260_hp_3013_unsol_event,
7056 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7057 },
7058 [ALC260_FUJITSU_S702X] = {
f9e336f6 7059 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7060 .init_verbs = { alc260_fujitsu_init_verbs },
7061 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7062 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7063 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7064 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7065 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7066 .channel_mode = alc260_modes,
a1e8d2da
JW
7067 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7068 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7069 },
0bfc90e9 7070 [ALC260_ACER] = {
f9e336f6 7071 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7072 .init_verbs = { alc260_acer_init_verbs },
7073 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7074 .dac_nids = alc260_dac_nids,
7075 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7076 .adc_nids = alc260_dual_adc_nids,
7077 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7078 .channel_mode = alc260_modes,
a1e8d2da
JW
7079 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7080 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7081 },
cc959489
MS
7082 [ALC260_FAVORIT100] = {
7083 .mixers = { alc260_favorit100_mixer },
7084 .init_verbs = { alc260_favorit100_init_verbs },
7085 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7086 .dac_nids = alc260_dac_nids,
7087 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7088 .adc_nids = alc260_dual_adc_nids,
7089 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7090 .channel_mode = alc260_modes,
7091 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7092 .input_mux = alc260_favorit100_capture_sources,
7093 },
bc9f98a9 7094 [ALC260_WILL] = {
f9e336f6 7095 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7096 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7097 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7098 .dac_nids = alc260_dac_nids,
7099 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7100 .adc_nids = alc260_adc_nids,
7101 .dig_out_nid = ALC260_DIGOUT_NID,
7102 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7103 .channel_mode = alc260_modes,
7104 .input_mux = &alc260_capture_source,
7105 },
7106 [ALC260_REPLACER_672V] = {
f9e336f6 7107 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7108 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7109 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7110 .dac_nids = alc260_dac_nids,
7111 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7112 .adc_nids = alc260_adc_nids,
7113 .dig_out_nid = ALC260_DIGOUT_NID,
7114 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7115 .channel_mode = alc260_modes,
7116 .input_mux = &alc260_capture_source,
7117 .unsol_event = alc260_replacer_672v_unsol_event,
7118 .init_hook = alc260_replacer_672v_automute,
7119 },
7cf51e48
JW
7120#ifdef CONFIG_SND_DEBUG
7121 [ALC260_TEST] = {
f9e336f6 7122 .mixers = { alc260_test_mixer },
7cf51e48
JW
7123 .init_verbs = { alc260_test_init_verbs },
7124 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7125 .dac_nids = alc260_test_dac_nids,
7126 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7127 .adc_nids = alc260_test_adc_nids,
7128 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7129 .channel_mode = alc260_modes,
a1e8d2da
JW
7130 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7131 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7132 },
7133#endif
df694daa
KY
7134};
7135
7136static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7137{
7138 struct alc_spec *spec;
df694daa 7139 int err, board_config;
1da177e4 7140
e560d8d8 7141 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7142 if (spec == NULL)
7143 return -ENOMEM;
7144
7145 codec->spec = spec;
7146
f5fcc13c
TI
7147 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7148 alc260_models,
7149 alc260_cfg_tbl);
7150 if (board_config < 0) {
9a11f1aa 7151 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7152 codec->chip_name);
df694daa 7153 board_config = ALC260_AUTO;
16ded525 7154 }
1da177e4 7155
fc091769
TI
7156 if (board_config == ALC260_AUTO)
7157 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1);
7158
df694daa
KY
7159 if (board_config == ALC260_AUTO) {
7160 /* automatic parse from the BIOS config */
7161 err = alc260_parse_auto_config(codec);
7162 if (err < 0) {
7163 alc_free(codec);
7164 return err;
f12ab1e0 7165 } else if (!err) {
9c7f852e
TI
7166 printk(KERN_INFO
7167 "hda_codec: Cannot set up configuration "
7168 "from BIOS. Using base mode...\n");
df694daa
KY
7169 board_config = ALC260_BASIC;
7170 }
a9430dd8 7171 }
e9edcee0 7172
680cd536
KK
7173 err = snd_hda_attach_beep_device(codec, 0x1);
7174 if (err < 0) {
7175 alc_free(codec);
7176 return err;
7177 }
7178
df694daa 7179 if (board_config != ALC260_AUTO)
e9c364c0 7180 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7181
1da177e4
LT
7182 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7183 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7184 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7185
a3bcba38
TI
7186 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7187 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7188
4ef0ef19
TI
7189 if (!spec->adc_nids && spec->input_mux) {
7190 /* check whether NID 0x04 is valid */
7191 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7192 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7193 /* get type */
7194 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7195 spec->adc_nids = alc260_adc_nids_alt;
7196 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7197 } else {
7198 spec->adc_nids = alc260_adc_nids;
7199 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7200 }
7201 }
b59bdf3b 7202 set_capture_mixer(codec);
45bdd1c1 7203 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7204
fc091769
TI
7205 if (board_config == ALC260_AUTO)
7206 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0);
7207
2134ea4f
TI
7208 spec->vmaster_nid = 0x08;
7209
1da177e4 7210 codec->patch_ops = alc_patch_ops;
df694daa 7211 if (board_config == ALC260_AUTO)
ae6b813a 7212 spec->init_hook = alc260_auto_init;
cb53c626
TI
7213#ifdef CONFIG_SND_HDA_POWER_SAVE
7214 if (!spec->loopback.amplist)
7215 spec->loopback.amplist = alc260_loopbacks;
7216#endif
1da177e4
LT
7217
7218 return 0;
7219}
7220
e9edcee0 7221
1da177e4 7222/*
4953550a 7223 * ALC882/883/885/888/889 support
1da177e4
LT
7224 *
7225 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7226 * configuration. Each pin widget can choose any input DACs and a mixer.
7227 * Each ADC is connected from a mixer of all inputs. This makes possible
7228 * 6-channel independent captures.
7229 *
7230 * In addition, an independent DAC for the multi-playback (not used in this
7231 * driver yet).
7232 */
df694daa
KY
7233#define ALC882_DIGOUT_NID 0x06
7234#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7235#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7236#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7237#define ALC1200_DIGOUT_NID 0x10
7238
1da177e4 7239
d2a6d7dc 7240static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7241 { 8, NULL }
7242};
7243
4953550a 7244/* DACs */
1da177e4
LT
7245static hda_nid_t alc882_dac_nids[4] = {
7246 /* front, rear, clfe, rear_surr */
7247 0x02, 0x03, 0x04, 0x05
7248};
4953550a 7249#define alc883_dac_nids alc882_dac_nids
1da177e4 7250
4953550a 7251/* ADCs */
df694daa
KY
7252#define alc882_adc_nids alc880_adc_nids
7253#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7254#define alc883_adc_nids alc882_adc_nids_alt
7255static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7256static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7257#define alc889_adc_nids alc880_adc_nids
1da177e4 7258
e1406348
TI
7259static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7260static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7261#define alc883_capsrc_nids alc882_capsrc_nids_alt
7262static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7263#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7264
1da177e4
LT
7265/* input MUX */
7266/* FIXME: should be a matrix-type input source selection */
7267
7268static struct hda_input_mux alc882_capture_source = {
7269 .num_items = 4,
7270 .items = {
7271 { "Mic", 0x0 },
7272 { "Front Mic", 0x1 },
7273 { "Line", 0x2 },
7274 { "CD", 0x4 },
7275 },
7276};
41d5545d 7277
4953550a
TI
7278#define alc883_capture_source alc882_capture_source
7279
87a8c370
JK
7280static struct hda_input_mux alc889_capture_source = {
7281 .num_items = 3,
7282 .items = {
7283 { "Front Mic", 0x0 },
7284 { "Mic", 0x3 },
7285 { "Line", 0x2 },
7286 },
7287};
7288
41d5545d
KS
7289static struct hda_input_mux mb5_capture_source = {
7290 .num_items = 3,
7291 .items = {
7292 { "Mic", 0x1 },
b8f171e7 7293 { "Line", 0x7 },
41d5545d
KS
7294 { "CD", 0x4 },
7295 },
7296};
7297
e458b1fa
LY
7298static struct hda_input_mux macmini3_capture_source = {
7299 .num_items = 2,
7300 .items = {
7301 { "Line", 0x2 },
7302 { "CD", 0x4 },
7303 },
7304};
7305
4953550a
TI
7306static struct hda_input_mux alc883_3stack_6ch_intel = {
7307 .num_items = 4,
7308 .items = {
7309 { "Mic", 0x1 },
7310 { "Front Mic", 0x0 },
7311 { "Line", 0x2 },
7312 { "CD", 0x4 },
7313 },
7314};
7315
7316static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7317 .num_items = 2,
7318 .items = {
7319 { "Mic", 0x1 },
7320 { "Line", 0x2 },
7321 },
7322};
7323
7324static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7325 .num_items = 4,
7326 .items = {
7327 { "Mic", 0x0 },
150b432f 7328 { "Int Mic", 0x1 },
4953550a
TI
7329 { "Line", 0x2 },
7330 { "CD", 0x4 },
7331 },
7332};
7333
7334static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7335 .num_items = 2,
7336 .items = {
7337 { "Mic", 0x0 },
7338 { "Int Mic", 0x1 },
7339 },
7340};
7341
7342static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7343 .num_items = 3,
7344 .items = {
7345 { "Mic", 0x0 },
7346 { "Front Mic", 0x1 },
7347 { "Line", 0x4 },
7348 },
7349};
7350
7351static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7352 .num_items = 2,
7353 .items = {
7354 { "Mic", 0x0 },
7355 { "Line", 0x2 },
7356 },
7357};
7358
7359static struct hda_input_mux alc889A_mb31_capture_source = {
7360 .num_items = 2,
7361 .items = {
7362 { "Mic", 0x0 },
7363 /* Front Mic (0x01) unused */
7364 { "Line", 0x2 },
7365 /* Line 2 (0x03) unused */
af901ca1 7366 /* CD (0x04) unused? */
4953550a
TI
7367 },
7368};
7369
b7cccc52
JM
7370static struct hda_input_mux alc889A_imac91_capture_source = {
7371 .num_items = 2,
7372 .items = {
7373 { "Mic", 0x01 },
7374 { "Line", 0x2 }, /* Not sure! */
7375 },
7376};
7377
4953550a
TI
7378/*
7379 * 2ch mode
7380 */
7381static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7382 { 2, NULL }
7383};
7384
272a527c
KY
7385/*
7386 * 2ch mode
7387 */
7388static struct hda_verb alc882_3ST_ch2_init[] = {
7389 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7390 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7391 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7392 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7393 { } /* end */
7394};
7395
4953550a
TI
7396/*
7397 * 4ch mode
7398 */
7399static struct hda_verb alc882_3ST_ch4_init[] = {
7400 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7401 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7402 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7403 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7404 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7405 { } /* end */
7406};
7407
272a527c
KY
7408/*
7409 * 6ch mode
7410 */
7411static struct hda_verb alc882_3ST_ch6_init[] = {
7412 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7413 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7414 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7415 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7416 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7417 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7418 { } /* end */
7419};
7420
4953550a 7421static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7422 { 2, alc882_3ST_ch2_init },
4953550a 7423 { 4, alc882_3ST_ch4_init },
272a527c
KY
7424 { 6, alc882_3ST_ch6_init },
7425};
7426
4953550a
TI
7427#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7428
a65cc60f 7429/*
7430 * 2ch mode
7431 */
7432static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7433 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7434 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7435 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7436 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7437 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7438 { } /* end */
7439};
7440
7441/*
7442 * 4ch mode
7443 */
7444static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7445 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7446 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7447 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7448 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7449 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7450 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7451 { } /* end */
7452};
7453
7454/*
7455 * 6ch mode
7456 */
7457static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7458 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7459 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7460 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7461 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7462 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7463 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7464 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7465 { } /* end */
7466};
7467
7468static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7469 { 2, alc883_3ST_ch2_clevo_init },
7470 { 4, alc883_3ST_ch4_clevo_init },
7471 { 6, alc883_3ST_ch6_clevo_init },
7472};
7473
7474
df694daa
KY
7475/*
7476 * 6ch mode
7477 */
7478static struct hda_verb alc882_sixstack_ch6_init[] = {
7479 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7480 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7481 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7482 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7483 { } /* end */
7484};
7485
7486/*
7487 * 8ch mode
7488 */
7489static struct hda_verb alc882_sixstack_ch8_init[] = {
7490 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7491 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7492 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7493 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7494 { } /* end */
7495};
7496
7497static struct hda_channel_mode alc882_sixstack_modes[2] = {
7498 { 6, alc882_sixstack_ch6_init },
7499 { 8, alc882_sixstack_ch8_init },
7500};
7501
76e6f5a9
RH
7502
7503/* Macbook Air 2,1 */
7504
7505static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7506 { 2, NULL },
7507};
7508
87350ad0 7509/*
def319f9 7510 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7511 */
7512
7513/*
7514 * 2ch mode
7515 */
7516static struct hda_verb alc885_mbp_ch2_init[] = {
7517 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7518 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7519 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7520 { } /* end */
7521};
7522
7523/*
a3f730af 7524 * 4ch mode
87350ad0 7525 */
a3f730af 7526static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7527 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7528 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7529 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7530 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7531 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7532 { } /* end */
7533};
7534
a3f730af 7535static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7536 { 2, alc885_mbp_ch2_init },
a3f730af 7537 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7538};
7539
92b9de83
KS
7540/*
7541 * 2ch
7542 * Speakers/Woofer/HP = Front
7543 * LineIn = Input
7544 */
7545static struct hda_verb alc885_mb5_ch2_init[] = {
7546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7548 { } /* end */
7549};
7550
7551/*
7552 * 6ch mode
7553 * Speakers/HP = Front
7554 * Woofer = LFE
7555 * LineIn = Surround
7556 */
7557static struct hda_verb alc885_mb5_ch6_init[] = {
7558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7560 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7561 { } /* end */
7562};
7563
7564static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7565 { 2, alc885_mb5_ch2_init },
7566 { 6, alc885_mb5_ch6_init },
7567};
87350ad0 7568
d01aecdf 7569#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7570
7571/*
7572 * 2ch mode
7573 */
7574static struct hda_verb alc883_4ST_ch2_init[] = {
7575 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7576 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7577 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7578 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7579 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7580 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7581 { } /* end */
7582};
7583
7584/*
7585 * 4ch mode
7586 */
7587static struct hda_verb alc883_4ST_ch4_init[] = {
7588 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7589 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7590 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7591 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7592 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7593 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7594 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7595 { } /* end */
7596};
7597
7598/*
7599 * 6ch mode
7600 */
7601static struct hda_verb alc883_4ST_ch6_init[] = {
7602 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7603 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7604 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7605 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7606 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7607 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7608 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7609 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7610 { } /* end */
7611};
7612
7613/*
7614 * 8ch mode
7615 */
7616static struct hda_verb alc883_4ST_ch8_init[] = {
7617 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7618 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7619 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7620 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7621 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7622 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7623 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7624 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7625 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7626 { } /* end */
7627};
7628
7629static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7630 { 2, alc883_4ST_ch2_init },
7631 { 4, alc883_4ST_ch4_init },
7632 { 6, alc883_4ST_ch6_init },
7633 { 8, alc883_4ST_ch8_init },
7634};
7635
7636
7637/*
7638 * 2ch mode
7639 */
7640static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7641 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7642 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7643 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7644 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7645 { } /* end */
7646};
7647
7648/*
7649 * 4ch mode
7650 */
7651static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7652 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7653 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7654 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7655 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7656 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7657 { } /* end */
7658};
7659
7660/*
7661 * 6ch mode
7662 */
7663static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7664 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7665 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7666 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7667 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7668 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7669 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7670 { } /* end */
7671};
7672
7673static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7674 { 2, alc883_3ST_ch2_intel_init },
7675 { 4, alc883_3ST_ch4_intel_init },
7676 { 6, alc883_3ST_ch6_intel_init },
7677};
7678
dd7714c9
WF
7679/*
7680 * 2ch mode
7681 */
7682static struct hda_verb alc889_ch2_intel_init[] = {
7683 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7684 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7685 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7686 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7687 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7688 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7689 { } /* end */
7690};
7691
87a8c370
JK
7692/*
7693 * 6ch mode
7694 */
7695static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7696 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7697 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7698 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7699 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7700 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7701 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7702 { } /* end */
7703};
7704
7705/*
7706 * 8ch mode
7707 */
7708static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7709 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7710 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7711 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7712 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7713 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7714 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7715 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7716 { } /* end */
7717};
7718
dd7714c9
WF
7719static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7720 { 2, alc889_ch2_intel_init },
87a8c370
JK
7721 { 6, alc889_ch6_intel_init },
7722 { 8, alc889_ch8_intel_init },
7723};
7724
4953550a
TI
7725/*
7726 * 6ch mode
7727 */
7728static struct hda_verb alc883_sixstack_ch6_init[] = {
7729 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7730 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7731 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7732 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7733 { } /* end */
7734};
7735
7736/*
7737 * 8ch mode
7738 */
7739static struct hda_verb alc883_sixstack_ch8_init[] = {
7740 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7741 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7742 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7743 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7744 { } /* end */
7745};
7746
7747static struct hda_channel_mode alc883_sixstack_modes[2] = {
7748 { 6, alc883_sixstack_ch6_init },
7749 { 8, alc883_sixstack_ch8_init },
7750};
7751
7752
1da177e4
LT
7753/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7754 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7755 */
c8b6bf9b 7756static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7757 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7758 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7759 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7760 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7761 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7762 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7763 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7764 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7765 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7766 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7767 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7768 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7769 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7770 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7771 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7772 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7773 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7774 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7775 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7776 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7777 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7778 { } /* end */
7779};
7780
76e6f5a9
RH
7781/* Macbook Air 2,1 same control for HP and internal Speaker */
7782
7783static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7784 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7785 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7786 { }
7787};
7788
7789
87350ad0 7790static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7791 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7792 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7794 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7795 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7796 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7797 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7798 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7799 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7800 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7801 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7802 { } /* end */
7803};
41d5545d
KS
7804
7805static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7806 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7807 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7808 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7809 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7810 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7811 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7812 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7813 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7814 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7815 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7817 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7818 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7819 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7820 { } /* end */
7821};
92b9de83 7822
e458b1fa
LY
7823static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7824 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7825 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7826 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7827 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7828 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7829 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7830 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7831 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7832 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7833 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7834 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7835 { } /* end */
7836};
7837
4b7e1803 7838static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7839 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7840 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7841 { } /* end */
7842};
7843
7844
bdd148a3
KY
7845static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7846 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7847 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7848 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7849 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7850 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7851 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7853 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7854 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7855 { } /* end */
7856};
7857
272a527c
KY
7858static struct snd_kcontrol_new alc882_targa_mixer[] = {
7859 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7860 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7861 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7862 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7863 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7864 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7865 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7866 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7867 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7868 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7869 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7870 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7871 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7872 { } /* end */
7873};
7874
7875/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7876 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7877 */
7878static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7879 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7880 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7881 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7882 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7883 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7884 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7885 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7886 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7887 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7888 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7889 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7890 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7891 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7892 { } /* end */
7893};
7894
914759b7
TI
7895static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7896 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7897 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7898 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7899 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7900 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7901 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7902 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7903 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7904 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7906 { } /* end */
7907};
7908
df694daa
KY
7909static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7910 {
7911 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7912 .name = "Channel Mode",
7913 .info = alc_ch_mode_info,
7914 .get = alc_ch_mode_get,
7915 .put = alc_ch_mode_put,
7916 },
7917 { } /* end */
7918};
7919
4953550a 7920static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7921 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7922 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7923 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7924 /* Rear mixer */
05acb863
TI
7925 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7926 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7927 /* CLFE mixer */
05acb863
TI
7928 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7929 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7930 /* Side mixer */
05acb863
TI
7931 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7932 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7933
e9edcee0 7934 /* Front Pin: output 0 (0x0c) */
05acb863 7935 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7936 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7937 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7938 /* Rear Pin: output 1 (0x0d) */
05acb863 7939 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7940 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7941 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7942 /* CLFE Pin: output 2 (0x0e) */
05acb863 7943 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7944 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7945 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7946 /* Side Pin: output 3 (0x0f) */
05acb863 7947 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7948 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7949 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7950 /* Mic (rear) pin: input vref at 80% */
16ded525 7951 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7952 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7953 /* Front Mic pin: input vref at 80% */
16ded525 7954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7955 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7956 /* Line In pin: input */
05acb863 7957 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7958 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7959 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7960 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7961 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7962 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7963 /* CD pin widget for input */
05acb863 7964 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7965
7966 /* FIXME: use matrix-type input source selection */
7967 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7968 /* Input mixer2 */
05acb863 7969 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7970 /* Input mixer3 */
05acb863 7971 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7972 /* ADC2: mute amp left and right */
7973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7974 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7975 /* ADC3: mute amp left and right */
7976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7977 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7978
7979 { }
7980};
7981
4953550a
TI
7982static struct hda_verb alc882_adc1_init_verbs[] = {
7983 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7984 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7985 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7986 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7987 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7988 /* ADC1: mute amp left and right */
7989 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7990 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7991 { }
7992};
7993
4b146cb0
TI
7994static struct hda_verb alc882_eapd_verbs[] = {
7995 /* change to EAPD mode */
7996 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7997 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7998 { }
4b146cb0
TI
7999};
8000
87a8c370
JK
8001static struct hda_verb alc889_eapd_verbs[] = {
8002 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8003 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8004 { }
8005};
8006
6732bd0d
WF
8007static struct hda_verb alc_hp15_unsol_verbs[] = {
8008 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8010 {}
8011};
87a8c370
JK
8012
8013static struct hda_verb alc885_init_verbs[] = {
8014 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8015 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8016 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8017 /* Rear mixer */
88102f3f
KY
8018 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8019 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8020 /* CLFE mixer */
88102f3f
KY
8021 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8023 /* Side mixer */
88102f3f
KY
8024 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8025 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8026
8027 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8028 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8029 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8030 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8031 /* Front Pin: output 0 (0x0c) */
8032 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8033 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8034 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8035 /* Rear Pin: output 1 (0x0d) */
8036 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8037 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8038 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8039 /* CLFE Pin: output 2 (0x0e) */
8040 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8041 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8042 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8043 /* Side Pin: output 3 (0x0f) */
8044 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8045 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8046 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8047 /* Mic (rear) pin: input vref at 80% */
8048 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8049 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8050 /* Front Mic pin: input vref at 80% */
8051 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8053 /* Line In pin: input */
8054 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8055 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8056
8057 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8058 /* Input mixer1 */
88102f3f 8059 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8060 /* Input mixer2 */
8061 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8062 /* Input mixer3 */
88102f3f 8063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8064 /* ADC2: mute amp left and right */
8065 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8066 /* ADC3: mute amp left and right */
8067 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8068
8069 { }
8070};
8071
8072static struct hda_verb alc885_init_input_verbs[] = {
8073 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8076 { }
8077};
8078
8079
8080/* Unmute Selector 24h and set the default input to front mic */
8081static struct hda_verb alc889_init_input_verbs[] = {
8082 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8083 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8084 { }
8085};
8086
8087
4953550a
TI
8088#define alc883_init_verbs alc882_base_init_verbs
8089
9102cd1c
TD
8090/* Mac Pro test */
8091static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8092 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8093 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8094 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8095 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8096 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8097 /* FIXME: this looks suspicious...
d355c82a
JK
8098 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8099 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8100 */
9102cd1c
TD
8101 { } /* end */
8102};
8103
8104static struct hda_verb alc882_macpro_init_verbs[] = {
8105 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8107 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8108 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8109 /* Front Pin: output 0 (0x0c) */
8110 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8112 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8113 /* Front Mic pin: input vref at 80% */
8114 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8115 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8116 /* Speaker: output */
8117 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8118 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8119 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8120 /* Headphone output (output 0 - 0x0c) */
8121 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8122 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8123 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8124
8125 /* FIXME: use matrix-type input source selection */
8126 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8127 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8128 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8129 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8130 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8131 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8132 /* Input mixer2 */
8133 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8134 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8135 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8136 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8137 /* Input mixer3 */
8138 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8139 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8140 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8141 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8142 /* ADC1: mute amp left and right */
8143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8144 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8145 /* ADC2: mute amp left and right */
8146 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8147 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8148 /* ADC3: mute amp left and right */
8149 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8150 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8151
8152 { }
8153};
f12ab1e0 8154
41d5545d
KS
8155/* Macbook 5,1 */
8156static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8157 /* DACs */
8158 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8159 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8160 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8161 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8162 /* Front mixer */
41d5545d
KS
8163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8164 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8165 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8166 /* Surround mixer */
8167 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8168 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8169 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8170 /* LFE mixer */
8171 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8172 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8173 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8174 /* HP mixer */
8175 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8176 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8177 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8178 /* Front Pin (0x0c) */
41d5545d
KS
8179 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8180 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8181 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8182 /* LFE Pin (0x0e) */
8183 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8184 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8185 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8186 /* HP Pin (0x0f) */
41d5545d
KS
8187 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8188 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8189 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8190 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8191 /* Front Mic pin: input vref at 80% */
8192 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8193 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8194 /* Line In pin */
8195 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8196 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8197
b8f171e7
AM
8198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8200 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8201 { }
8202};
8203
e458b1fa
LY
8204/* Macmini 3,1 */
8205static struct hda_verb alc885_macmini3_init_verbs[] = {
8206 /* DACs */
8207 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8208 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8209 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8210 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8211 /* Front mixer */
8212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8215 /* Surround mixer */
8216 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8217 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8218 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8219 /* LFE mixer */
8220 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8222 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8223 /* HP mixer */
8224 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8225 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8226 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8227 /* Front Pin (0x0c) */
8228 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8229 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8230 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8231 /* LFE Pin (0x0e) */
8232 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8233 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8234 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8235 /* HP Pin (0x0f) */
8236 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8237 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8238 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8239 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8240 /* Line In pin */
8241 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8242 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8243
8244 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8245 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8247 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8248 { }
8249};
8250
76e6f5a9
RH
8251
8252static struct hda_verb alc885_mba21_init_verbs[] = {
8253 /*Internal and HP Speaker Mixer*/
8254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8257 /*Internal Speaker Pin (0x0c)*/
8258 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8259 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8260 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8261 /* HP Pin: output 0 (0x0e) */
8262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8264 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8265 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8266 /* Line in (is hp when jack connected)*/
8267 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8269
8270 { }
8271 };
8272
8273
87350ad0
TI
8274/* Macbook Pro rev3 */
8275static struct hda_verb alc885_mbp3_init_verbs[] = {
8276 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8277 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8278 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8279 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8280 /* Rear mixer */
8281 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8282 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8283 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8284 /* HP mixer */
8285 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8287 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8288 /* Front Pin: output 0 (0x0c) */
8289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8290 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8291 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8292 /* HP Pin: output 0 (0x0e) */
87350ad0 8293 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8294 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8295 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8296 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8297 /* Mic (rear) pin: input vref at 80% */
8298 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8299 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8300 /* Front Mic pin: input vref at 80% */
8301 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8302 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8303 /* Line In pin: use output 1 when in LineOut mode */
8304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8305 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8306 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8307
8308 /* FIXME: use matrix-type input source selection */
8309 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8310 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8311 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8312 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8313 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8315 /* Input mixer2 */
8316 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8317 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8318 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8320 /* Input mixer3 */
8321 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8325 /* ADC1: mute amp left and right */
8326 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8327 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8328 /* ADC2: mute amp left and right */
8329 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8330 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8331 /* ADC3: mute amp left and right */
8332 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8333 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8334
8335 { }
8336};
8337
4b7e1803
JM
8338/* iMac 9,1 */
8339static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8340 /* Internal Speaker Pin (0x0c) */
8341 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8342 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8343 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8344 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8345 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8346 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8347 /* HP Pin: Rear */
4b7e1803
JM
8348 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8349 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8350 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8351 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8352 /* Line in Rear */
8353 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8354 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8355 /* Front Mic pin: input vref at 80% */
8356 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8357 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8358 /* Rear mixer */
8359 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8360 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8361 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8362 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8364 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8365 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8366 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8367 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8368 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8369 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8370 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8371 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8372 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8373 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8374 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8375 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8376 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8377 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8379 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8380 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8381 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8382 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8383 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8384 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8385 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8386 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8387 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8388 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8389 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8390 { }
8391};
8392
c54728d8
NF
8393/* iMac 24 mixer. */
8394static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8395 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8396 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8397 { } /* end */
8398};
8399
8400/* iMac 24 init verbs. */
8401static struct hda_verb alc885_imac24_init_verbs[] = {
8402 /* Internal speakers: output 0 (0x0c) */
8403 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8404 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8405 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8406 /* Internal speakers: output 0 (0x0c) */
8407 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8408 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8409 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8410 /* Headphone: output 0 (0x0c) */
8411 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8412 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8413 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8414 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8415 /* Front Mic: input vref at 80% */
8416 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8417 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8418 { }
8419};
8420
8421/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8422static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8423{
a9fd4f3f 8424 struct alc_spec *spec = codec->spec;
c54728d8 8425
a9fd4f3f
TI
8426 spec->autocfg.hp_pins[0] = 0x14;
8427 spec->autocfg.speaker_pins[0] = 0x18;
8428 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8429}
8430
9d54f08b
TI
8431#define alc885_mb5_setup alc885_imac24_setup
8432#define alc885_macmini3_setup alc885_imac24_setup
8433
76e6f5a9
RH
8434/* Macbook Air 2,1 */
8435static void alc885_mba21_setup(struct hda_codec *codec)
8436{
8437 struct alc_spec *spec = codec->spec;
8438
8439 spec->autocfg.hp_pins[0] = 0x14;
8440 spec->autocfg.speaker_pins[0] = 0x18;
8441}
8442
8443
8444
4f5d1706 8445static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8446{
a9fd4f3f 8447 struct alc_spec *spec = codec->spec;
87350ad0 8448
a9fd4f3f
TI
8449 spec->autocfg.hp_pins[0] = 0x15;
8450 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8451}
8452
9d54f08b 8453static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8454{
9d54f08b 8455 struct alc_spec *spec = codec->spec;
4b7e1803 8456
9d54f08b 8457 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8458 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8459 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8460}
87350ad0 8461
272a527c
KY
8462static struct hda_verb alc882_targa_verbs[] = {
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8465
8466 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8467 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8468
272a527c
KY
8469 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8470 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8471 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8472
8473 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8474 { } /* end */
8475};
8476
8477/* toggle speaker-output according to the hp-jack state */
8478static void alc882_targa_automute(struct hda_codec *codec)
8479{
a9fd4f3f
TI
8480 struct alc_spec *spec = codec->spec;
8481 alc_automute_amp(codec);
82beb8fd 8482 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8483 spec->jack_present ? 1 : 3);
8484}
8485
4f5d1706 8486static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8487{
8488 struct alc_spec *spec = codec->spec;
8489
8490 spec->autocfg.hp_pins[0] = 0x14;
8491 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8492}
8493
8494static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8495{
a9fd4f3f 8496 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8497 alc882_targa_automute(codec);
272a527c
KY
8498}
8499
8500static struct hda_verb alc882_asus_a7j_verbs[] = {
8501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8503
8504 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8506 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8507
272a527c
KY
8508 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8509 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8510 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8511
8512 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8513 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8514 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8515 { } /* end */
8516};
8517
914759b7
TI
8518static struct hda_verb alc882_asus_a7m_verbs[] = {
8519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8521
8522 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8523 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8524 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8525
914759b7
TI
8526 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8527 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8528 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8529
8530 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8531 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8532 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8533 { } /* end */
8534};
8535
9102cd1c
TD
8536static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8537{
8538 unsigned int gpiostate, gpiomask, gpiodir;
8539
8540 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8541 AC_VERB_GET_GPIO_DATA, 0);
8542
8543 if (!muted)
8544 gpiostate |= (1 << pin);
8545 else
8546 gpiostate &= ~(1 << pin);
8547
8548 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8549 AC_VERB_GET_GPIO_MASK, 0);
8550 gpiomask |= (1 << pin);
8551
8552 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8553 AC_VERB_GET_GPIO_DIRECTION, 0);
8554 gpiodir |= (1 << pin);
8555
8556
8557 snd_hda_codec_write(codec, codec->afg, 0,
8558 AC_VERB_SET_GPIO_MASK, gpiomask);
8559 snd_hda_codec_write(codec, codec->afg, 0,
8560 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8561
8562 msleep(1);
8563
8564 snd_hda_codec_write(codec, codec->afg, 0,
8565 AC_VERB_SET_GPIO_DATA, gpiostate);
8566}
8567
7debbe51
TI
8568/* set up GPIO at initialization */
8569static void alc885_macpro_init_hook(struct hda_codec *codec)
8570{
8571 alc882_gpio_mute(codec, 0, 0);
8572 alc882_gpio_mute(codec, 1, 0);
8573}
8574
8575/* set up GPIO and update auto-muting at initialization */
8576static void alc885_imac24_init_hook(struct hda_codec *codec)
8577{
8578 alc885_macpro_init_hook(codec);
4f5d1706 8579 alc_automute_amp(codec);
7debbe51
TI
8580}
8581
df694daa
KY
8582/*
8583 * generic initialization of ADC, input mixers and output mixers
8584 */
4953550a 8585static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8586 /*
8587 * Unmute ADC0-2 and set the default input to mic-in
8588 */
4953550a
TI
8589 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8590 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8591 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8593
4953550a
TI
8594 /*
8595 * Set up output mixers (0x0c - 0x0f)
8596 */
8597 /* set vol=0 to output mixers */
8598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8599 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8600 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8601 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8602 /* set up input amps for analog loopback */
8603 /* Amp Indices: DAC = 0, mixer = 1 */
8604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8608 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8609 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8610 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8611 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8612 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8613 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8614
4953550a
TI
8615 /* FIXME: use matrix-type input source selection */
8616 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8617 /* Input mixer2 */
88102f3f 8618 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8619 /* Input mixer3 */
88102f3f 8620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8621 { }
9c7f852e
TI
8622};
8623
eb4c41d3
TS
8624/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8625static struct hda_verb alc889A_mb31_ch2_init[] = {
8626 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8627 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8628 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8630 { } /* end */
8631};
8632
8633/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8634static struct hda_verb alc889A_mb31_ch4_init[] = {
8635 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8636 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8637 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8639 { } /* end */
8640};
8641
8642/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8643static struct hda_verb alc889A_mb31_ch5_init[] = {
8644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8645 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8646 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8647 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8648 { } /* end */
8649};
8650
8651/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8652static struct hda_verb alc889A_mb31_ch6_init[] = {
8653 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8654 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8655 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8656 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8657 { } /* end */
8658};
8659
8660static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8661 { 2, alc889A_mb31_ch2_init },
8662 { 4, alc889A_mb31_ch4_init },
8663 { 5, alc889A_mb31_ch5_init },
8664 { 6, alc889A_mb31_ch6_init },
8665};
8666
b373bdeb
AN
8667static struct hda_verb alc883_medion_eapd_verbs[] = {
8668 /* eanable EAPD on medion laptop */
8669 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8670 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8671 { }
8672};
8673
4953550a 8674#define alc883_base_mixer alc882_base_mixer
834be88d 8675
a8848bd6
AS
8676static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8677 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8678 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8679 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8680 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8681 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8682 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8684 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8685 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8687 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8688 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8689 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8690 { } /* end */
8691};
8692
0c4cc443 8693static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8694 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8695 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8696 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8697 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8698 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8699 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8700 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8701 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8702 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8703 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8704 { } /* end */
8705};
8706
fb97dc67
J
8707static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8708 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8709 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8710 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8711 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8712 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8713 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8714 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8715 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8716 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8717 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8718 { } /* end */
8719};
8720
9c7f852e
TI
8721static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8722 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8723 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8724 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8725 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8726 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8727 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8728 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8729 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8730 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8731 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8732 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8733 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8734 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8735 { } /* end */
8736};
df694daa 8737
9c7f852e
TI
8738static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8739 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8740 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8741 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8742 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8743 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8744 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8745 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8746 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8747 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8748 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8749 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8750 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8751 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8752 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8753 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8754 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8755 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8756 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8757 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8758 { } /* end */
8759};
8760
17bba1b7
J
8761static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8762 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8763 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8764 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8765 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8766 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8767 HDA_OUTPUT),
8768 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8769 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8770 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8771 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8772 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8773 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8774 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8775 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8776 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8777 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8778 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8779 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8780 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8781 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8782 { } /* end */
8783};
8784
87a8c370
JK
8785static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8786 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8787 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8788 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8789 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8790 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8791 HDA_OUTPUT),
8792 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8793 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8794 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8795 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8796 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8797 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8798 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8799 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8801 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8802 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8803 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8804 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8805 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8806 { } /* end */
8807};
8808
d1d985f0 8809static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8810 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8811 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8812 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8813 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8814 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8815 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8816 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8817 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8818 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8819 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8820 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8821 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8822 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8824 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8826 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8827 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8828 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8829 { } /* end */
8830};
8831
c259249f 8832static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8833 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8834 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8836 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8837 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8838 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8839 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8840 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8841 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8842 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8843 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8844 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8845 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8846 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8847 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8848 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8849 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8850 { } /* end */
f12ab1e0 8851};
ccc656ce 8852
c259249f 8853static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8854 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8855 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8856 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8857 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8858 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8859 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8863 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8864 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8865 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8866 { } /* end */
f12ab1e0 8867};
ccc656ce 8868
b99dba34
TI
8869static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8870 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8871 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8872 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8873 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8874 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8875 { } /* end */
8876};
8877
bc9f98a9
KY
8878static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8879 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8880 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8881 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8882 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8883 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8884 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8886 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8887 { } /* end */
f12ab1e0 8888};
bc9f98a9 8889
272a527c
KY
8890static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8891 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8892 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8894 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8895 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
150b432f
DH
8898 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8899 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8900 { } /* end */
8901};
8902
8903static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8904 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8905 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8906 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8907 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8908 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8909 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8911 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8912 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8913 { } /* end */
ea1fb29a 8914};
272a527c 8915
7ad7b218
MC
8916static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8917 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8918 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8919 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8920 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8921 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8922 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8923 { } /* end */
8924};
8925
8926static struct hda_verb alc883_medion_wim2160_verbs[] = {
8927 /* Unmute front mixer */
8928 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8930
8931 /* Set speaker pin to front mixer */
8932 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8933
8934 /* Init headphone pin */
8935 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8936 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8937 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8938 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8939
8940 { } /* end */
8941};
8942
8943/* toggle speaker-output according to the hp-jack state */
8944static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8945{
8946 struct alc_spec *spec = codec->spec;
8947
8948 spec->autocfg.hp_pins[0] = 0x1a;
8949 spec->autocfg.speaker_pins[0] = 0x15;
8950}
8951
2880a867 8952static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8953 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8954 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8956 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8957 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8958 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8959 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8960 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8961 { } /* end */
d1a991a6 8962};
2880a867 8963
d2fd4b09
TV
8964static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8965 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 8966 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
8967 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8968 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8969 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8970 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8972 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8974 { } /* end */
8975};
8976
e2757d5e
KY
8977static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8978 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8979 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8980 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8981 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8982 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8983 0x0d, 1, 0x0, HDA_OUTPUT),
8984 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8985 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8986 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8987 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8988 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8989 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8990 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8994 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8996 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8997 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8998 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8999 { } /* end */
9000};
9001
eb4c41d3
TS
9002static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9003 /* Output mixers */
9004 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9005 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9006 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9007 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9008 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9009 HDA_OUTPUT),
9010 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9011 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9012 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9013 /* Output switches */
9014 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9015 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9016 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9017 /* Boost mixers */
9018 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
9019 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
9020 /* Input mixers */
9021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9022 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9023 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9024 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9025 { } /* end */
9026};
9027
3e1647c5
GG
9028static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9029 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9030 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9032 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9033 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9034 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9035 { } /* end */
9036};
9037
e2757d5e
KY
9038static struct hda_bind_ctls alc883_bind_cap_vol = {
9039 .ops = &snd_hda_bind_vol,
9040 .values = {
9041 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9042 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9043 0
9044 },
9045};
9046
9047static struct hda_bind_ctls alc883_bind_cap_switch = {
9048 .ops = &snd_hda_bind_sw,
9049 .values = {
9050 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9051 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9052 0
9053 },
9054};
9055
9056static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9057 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9058 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9060 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9061 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
9063 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9064 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9065 { } /* end */
9066};
df694daa 9067
4953550a
TI
9068static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9069 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9070 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9071 {
9072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9073 /* .name = "Capture Source", */
9074 .name = "Input Source",
9075 .count = 1,
9076 .info = alc_mux_enum_info,
9077 .get = alc_mux_enum_get,
9078 .put = alc_mux_enum_put,
9079 },
9080 { } /* end */
9081};
9c7f852e 9082
4953550a
TI
9083static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9084 {
9085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9086 .name = "Channel Mode",
9087 .info = alc_ch_mode_info,
9088 .get = alc_ch_mode_get,
9089 .put = alc_ch_mode_put,
9090 },
9091 { } /* end */
9c7f852e
TI
9092};
9093
a8848bd6 9094/* toggle speaker-output according to the hp-jack state */
4f5d1706 9095static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9096{
a9fd4f3f 9097 struct alc_spec *spec = codec->spec;
a8848bd6 9098
a9fd4f3f
TI
9099 spec->autocfg.hp_pins[0] = 0x15;
9100 spec->autocfg.speaker_pins[0] = 0x14;
9101 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9102}
9103
9104/* auto-toggle front mic */
9105/*
9106static void alc883_mitac_mic_automute(struct hda_codec *codec)
9107{
864f92be 9108 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 9109
a8848bd6
AS
9110 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
9111}
9112*/
9113
a8848bd6
AS
9114static struct hda_verb alc883_mitac_verbs[] = {
9115 /* HP */
9116 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9117 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9118 /* Subwoofer */
9119 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9120 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9121
9122 /* enable unsolicited event */
9123 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9124 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9125
9126 { } /* end */
9127};
9128
a65cc60f 9129static struct hda_verb alc883_clevo_m540r_verbs[] = {
9130 /* HP */
9131 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9132 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9133 /* Int speaker */
9134 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9135
9136 /* enable unsolicited event */
9137 /*
9138 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9139 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9140 */
9141
9142 { } /* end */
9143};
9144
0c4cc443 9145static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9146 /* HP */
9147 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9148 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9149 /* Int speaker */
9150 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9151 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9152
9153 /* enable unsolicited event */
9154 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9155 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9156
9157 { } /* end */
9158};
9159
fb97dc67
J
9160static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9161 /* HP */
9162 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9163 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9164 /* Subwoofer */
9165 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9166 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9167
9168 /* enable unsolicited event */
9169 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9170
9171 { } /* end */
9172};
9173
c259249f 9174static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9175 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9176 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9177
9178 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9179 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9180
64a8be74
DH
9181/* Connect Line-Out side jack (SPDIF) to Side */
9182 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9183 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9184 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9185/* Connect Mic jack to CLFE */
9186 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9187 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9188 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9189/* Connect Line-in jack to Surround */
9190 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9191 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9192 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9193/* Connect HP out jack to Front */
9194 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9195 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9196 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9197
9198 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9199
9200 { } /* end */
9201};
9202
bc9f98a9
KY
9203static struct hda_verb alc883_lenovo_101e_verbs[] = {
9204 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9205 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9206 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9207 { } /* end */
9208};
9209
272a527c
KY
9210static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9211 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9212 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9213 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9214 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9215 { } /* end */
9216};
9217
9218static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9221 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9222 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9223 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9224 { } /* end */
9225};
9226
189609ae
KY
9227static struct hda_verb alc883_haier_w66_verbs[] = {
9228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9229 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9230
9231 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9232
9233 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9234 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9235 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9236 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9237 { } /* end */
9238};
9239
e2757d5e
KY
9240static struct hda_verb alc888_lenovo_sky_verbs[] = {
9241 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9242 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9243 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9244 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9245 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9246 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9247 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9248 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9249 { } /* end */
9250};
9251
8718b700
HRK
9252static struct hda_verb alc888_6st_dell_verbs[] = {
9253 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9254 { }
9255};
9256
3e1647c5
GG
9257static struct hda_verb alc883_vaiott_verbs[] = {
9258 /* HP */
9259 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9260 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9261
9262 /* enable unsolicited event */
9263 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9264
9265 { } /* end */
9266};
9267
4f5d1706 9268static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9269{
a9fd4f3f 9270 struct alc_spec *spec = codec->spec;
8718b700 9271
a9fd4f3f
TI
9272 spec->autocfg.hp_pins[0] = 0x1b;
9273 spec->autocfg.speaker_pins[0] = 0x14;
9274 spec->autocfg.speaker_pins[1] = 0x16;
9275 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9276}
9277
4723c022 9278static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9279 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9280 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9281 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9282 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9283 { } /* end */
5795b9e6
CM
9284};
9285
3ea0d7cf
HRK
9286/*
9287 * 2ch mode
9288 */
4723c022 9289static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9290 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9291 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9292 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9293 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9294 { } /* end */
8341de60
CM
9295};
9296
3ea0d7cf
HRK
9297/*
9298 * 4ch mode
9299 */
9300static struct hda_verb alc888_3st_hp_4ch_init[] = {
9301 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9302 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9303 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9304 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9305 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9306 { } /* end */
9307};
9308
9309/*
9310 * 6ch mode
9311 */
4723c022 9312static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9313 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9314 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9315 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9316 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9317 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9318 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9319 { } /* end */
8341de60
CM
9320};
9321
3ea0d7cf 9322static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9323 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9324 { 4, alc888_3st_hp_4ch_init },
4723c022 9325 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9326};
9327
272a527c
KY
9328/* toggle front-jack and RCA according to the hp-jack state */
9329static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9330{
864f92be 9331 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9332
47fd830a
TI
9333 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9334 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9335 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9336 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9337}
9338
9339/* toggle RCA according to the front-jack state */
9340static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9341{
864f92be 9342 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9343
47fd830a
TI
9344 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9345 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9346}
47fd830a 9347
272a527c
KY
9348static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9349 unsigned int res)
9350{
9351 if ((res >> 26) == ALC880_HP_EVENT)
9352 alc888_lenovo_ms7195_front_automute(codec);
9353 if ((res >> 26) == ALC880_FRONT_EVENT)
9354 alc888_lenovo_ms7195_rca_automute(codec);
9355}
9356
9357static struct hda_verb alc883_medion_md2_verbs[] = {
9358 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9360
9361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9362
9363 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9364 { } /* end */
9365};
9366
9367/* toggle speaker-output according to the hp-jack state */
4f5d1706 9368static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 9369{
a9fd4f3f 9370 struct alc_spec *spec = codec->spec;
272a527c 9371
a9fd4f3f
TI
9372 spec->autocfg.hp_pins[0] = 0x14;
9373 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9374}
9375
ccc656ce 9376/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9377#define alc883_targa_init_hook alc882_targa_init_hook
9378#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9379
0c4cc443
HRK
9380static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9381{
9382 unsigned int present;
9383
d56757ab 9384 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
9385 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9386 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9387}
9388
4f5d1706 9389static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9390{
a9fd4f3f
TI
9391 struct alc_spec *spec = codec->spec;
9392
9393 spec->autocfg.hp_pins[0] = 0x15;
9394 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9395}
9396
9397static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9398{
a9fd4f3f 9399 alc_automute_amp(codec);
0c4cc443
HRK
9400 alc883_clevo_m720_mic_automute(codec);
9401}
9402
9403static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9404 unsigned int res)
9405{
0c4cc443 9406 switch (res >> 26) {
0c4cc443
HRK
9407 case ALC880_MIC_EVENT:
9408 alc883_clevo_m720_mic_automute(codec);
9409 break;
a9fd4f3f
TI
9410 default:
9411 alc_automute_amp_unsol_event(codec, res);
9412 break;
0c4cc443 9413 }
368c7a95
J
9414}
9415
fb97dc67 9416/* toggle speaker-output according to the hp-jack state */
4f5d1706 9417static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9418{
a9fd4f3f 9419 struct alc_spec *spec = codec->spec;
fb97dc67 9420
a9fd4f3f
TI
9421 spec->autocfg.hp_pins[0] = 0x14;
9422 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9423}
9424
4f5d1706 9425static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9426{
a9fd4f3f 9427 struct alc_spec *spec = codec->spec;
189609ae 9428
a9fd4f3f
TI
9429 spec->autocfg.hp_pins[0] = 0x1b;
9430 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9431}
9432
bc9f98a9
KY
9433static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9434{
864f92be 9435 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9436
47fd830a
TI
9437 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9438 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9439}
9440
9441static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9442{
864f92be 9443 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9444
47fd830a
TI
9445 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9446 HDA_AMP_MUTE, bits);
9447 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9448 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9449}
9450
9451static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9452 unsigned int res)
9453{
9454 if ((res >> 26) == ALC880_HP_EVENT)
9455 alc883_lenovo_101e_all_automute(codec);
9456 if ((res >> 26) == ALC880_FRONT_EVENT)
9457 alc883_lenovo_101e_ispeaker_automute(codec);
9458}
9459
676a9b53 9460/* toggle speaker-output according to the hp-jack state */
4f5d1706 9461static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9462{
a9fd4f3f 9463 struct alc_spec *spec = codec->spec;
676a9b53 9464
a9fd4f3f
TI
9465 spec->autocfg.hp_pins[0] = 0x14;
9466 spec->autocfg.speaker_pins[0] = 0x15;
9467 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9468}
9469
d1a991a6
KY
9470static struct hda_verb alc883_acer_eapd_verbs[] = {
9471 /* HP Pin: output 0 (0x0c) */
9472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9474 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9475 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9478 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9479 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9480 /* eanable EAPD on medion laptop */
9481 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9482 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9483 /* enable unsolicited event */
9484 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9485 { }
9486};
9487
fc86f954
DK
9488static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9489 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9490 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9491 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9492 { } /* end */
9493};
9494
4f5d1706 9495static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9496{
a9fd4f3f 9497 struct alc_spec *spec = codec->spec;
5795b9e6 9498
a9fd4f3f
TI
9499 spec->autocfg.hp_pins[0] = 0x1b;
9500 spec->autocfg.speaker_pins[0] = 0x14;
9501 spec->autocfg.speaker_pins[1] = 0x15;
9502 spec->autocfg.speaker_pins[2] = 0x16;
9503 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9504}
9505
4f5d1706 9506static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9507{
a9fd4f3f 9508 struct alc_spec *spec = codec->spec;
e2757d5e 9509
a9fd4f3f
TI
9510 spec->autocfg.hp_pins[0] = 0x1b;
9511 spec->autocfg.speaker_pins[0] = 0x14;
9512 spec->autocfg.speaker_pins[1] = 0x15;
9513 spec->autocfg.speaker_pins[2] = 0x16;
9514 spec->autocfg.speaker_pins[3] = 0x17;
9515 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9516}
9517
4f5d1706 9518static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9519{
9520 struct alc_spec *spec = codec->spec;
9521
9522 spec->autocfg.hp_pins[0] = 0x15;
9523 spec->autocfg.speaker_pins[0] = 0x14;
9524 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9525}
9526
e2757d5e
KY
9527static struct hda_verb alc888_asus_m90v_verbs[] = {
9528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9531 /* enable unsolicited event */
9532 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9533 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9534 { } /* end */
9535};
9536
4f5d1706 9537static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9538{
a9fd4f3f 9539 struct alc_spec *spec = codec->spec;
e2757d5e 9540
a9fd4f3f
TI
9541 spec->autocfg.hp_pins[0] = 0x1b;
9542 spec->autocfg.speaker_pins[0] = 0x14;
9543 spec->autocfg.speaker_pins[1] = 0x15;
9544 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9545 spec->ext_mic.pin = 0x18;
9546 spec->int_mic.pin = 0x19;
9547 spec->ext_mic.mux_idx = 0;
9548 spec->int_mic.mux_idx = 1;
9549 spec->auto_mic = 1;
e2757d5e
KY
9550}
9551
9552static struct hda_verb alc888_asus_eee1601_verbs[] = {
9553 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9554 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9555 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9556 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9557 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9558 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9559 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9560 /* enable unsolicited event */
9561 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9562 { } /* end */
9563};
9564
e2757d5e
KY
9565static void alc883_eee1601_inithook(struct hda_codec *codec)
9566{
a9fd4f3f
TI
9567 struct alc_spec *spec = codec->spec;
9568
9569 spec->autocfg.hp_pins[0] = 0x14;
9570 spec->autocfg.speaker_pins[0] = 0x1b;
9571 alc_automute_pin(codec);
e2757d5e
KY
9572}
9573
eb4c41d3
TS
9574static struct hda_verb alc889A_mb31_verbs[] = {
9575 /* Init rear pin (used as headphone output) */
9576 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9577 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9578 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9579 /* Init line pin (used as output in 4ch and 6ch mode) */
9580 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9581 /* Init line 2 pin (used as headphone out by default) */
9582 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9583 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9584 { } /* end */
9585};
9586
9587/* Mute speakers according to the headphone jack state */
9588static void alc889A_mb31_automute(struct hda_codec *codec)
9589{
9590 unsigned int present;
9591
9592 /* Mute only in 2ch or 4ch mode */
9593 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9594 == 0x00) {
864f92be 9595 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9596 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9597 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9598 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9599 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9600 }
9601}
9602
9603static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9604{
9605 if ((res >> 26) == ALC880_HP_EVENT)
9606 alc889A_mb31_automute(codec);
9607}
9608
4953550a 9609
cb53c626 9610#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9611#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9612#endif
9613
def319f9 9614/* pcm configuration: identical with ALC880 */
4953550a
TI
9615#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9616#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9617#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9618#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9619
9620static hda_nid_t alc883_slave_dig_outs[] = {
9621 ALC1200_DIGOUT_NID, 0,
9622};
9623
9624static hda_nid_t alc1200_slave_dig_outs[] = {
9625 ALC883_DIGOUT_NID, 0,
9626};
9c7f852e
TI
9627
9628/*
9629 * configuration and preset
9630 */
4953550a
TI
9631static const char *alc882_models[ALC882_MODEL_LAST] = {
9632 [ALC882_3ST_DIG] = "3stack-dig",
9633 [ALC882_6ST_DIG] = "6stack-dig",
9634 [ALC882_ARIMA] = "arima",
9635 [ALC882_W2JC] = "w2jc",
9636 [ALC882_TARGA] = "targa",
9637 [ALC882_ASUS_A7J] = "asus-a7j",
9638 [ALC882_ASUS_A7M] = "asus-a7m",
9639 [ALC885_MACPRO] = "macpro",
9640 [ALC885_MB5] = "mb5",
e458b1fa 9641 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9642 [ALC885_MBA21] = "mba21",
4953550a
TI
9643 [ALC885_MBP3] = "mbp3",
9644 [ALC885_IMAC24] = "imac24",
4b7e1803 9645 [ALC885_IMAC91] = "imac91",
4953550a 9646 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9647 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9648 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9649 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9650 [ALC883_TARGA_DIG] = "targa-dig",
9651 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9652 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9653 [ALC883_ACER] = "acer",
2880a867 9654 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9655 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9656 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9657 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9658 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9659 [ALC883_MEDION] = "medion",
272a527c 9660 [ALC883_MEDION_MD2] = "medion-md2",
7ad7b218 9661 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9662 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9663 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9664 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9665 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9666 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9667 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9668 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9669 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9670 [ALC883_MITAC] = "mitac",
a65cc60f 9671 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9672 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9673 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9674 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9675 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9676 [ALC889A_INTEL] = "intel-alc889a",
9677 [ALC889_INTEL] = "intel-x58",
3ab90935 9678 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9679 [ALC889A_MB31] = "mb31",
3e1647c5 9680 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9681 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9682};
9683
4953550a
TI
9684static struct snd_pci_quirk alc882_cfg_tbl[] = {
9685 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9686
ac3e3741 9687 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9688 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9689 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9690 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9691 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9692 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9693 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9694 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9695 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9696 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9697 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9698 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9699 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9700 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9701 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9702 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9703 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9704 ALC888_ACER_ASPIRE_6530G),
cc374c47 9705 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9706 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9707 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9708 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9709 /* default Acer -- disabled as it causes more problems.
9710 * model=auto should work fine now
9711 */
9712 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9713
5795b9e6 9714 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9715
febe3375 9716 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9717 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9718 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9719 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9720 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9721 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9722
9723 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9724 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9725 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9726 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9727 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9728 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9729 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9730 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9731 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9732 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9733 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9734
9735 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9736 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9737 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9738 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9739 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9740 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9741 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9742 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9743 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9744
6f3bf657 9745 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9746 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9747 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9748 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9749 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9750 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9751 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9752 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9753 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9754 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9755 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9756 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9757 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9758 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9759 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9760 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9761 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9762 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9763 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9764 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9765 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9766 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9767 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9768 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9769 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9770 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9771 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9772 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9773 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9774 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9775 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9776
ac3e3741 9777 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9778 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9779 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9780 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9781 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9782 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9783 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9784 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9785 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9786 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9787 ALC883_FUJITSU_PI2515),
bfb53037 9788 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9789 ALC888_FUJITSU_XA3530),
272a527c 9790 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9791 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9792 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9793 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9794 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9795 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9796 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9797 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9798 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9799
17bba1b7
J
9800 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9801 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9802 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9803 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9804 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9805 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9806 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9807
4953550a 9808 {}
f3cd3f5d
WF
9809};
9810
4953550a
TI
9811/* codec SSID table for Intel Mac */
9812static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9813 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9814 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9815 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9816 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9817 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9818 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9819 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9820 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9821 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9822 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9823 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9824 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9825 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9826 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9827 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9828 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9829 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9830 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9831 * so apparently no perfect solution yet
4953550a
TI
9832 */
9833 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9834 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9835 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9836 {} /* terminator */
b25c9da1
WF
9837};
9838
4953550a
TI
9839static struct alc_config_preset alc882_presets[] = {
9840 [ALC882_3ST_DIG] = {
9841 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9842 .init_verbs = { alc882_base_init_verbs,
9843 alc882_adc1_init_verbs },
4953550a
TI
9844 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9845 .dac_nids = alc882_dac_nids,
9846 .dig_out_nid = ALC882_DIGOUT_NID,
9847 .dig_in_nid = ALC882_DIGIN_NID,
9848 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9849 .channel_mode = alc882_ch_modes,
9850 .need_dac_fix = 1,
9851 .input_mux = &alc882_capture_source,
9852 },
9853 [ALC882_6ST_DIG] = {
9854 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9855 .init_verbs = { alc882_base_init_verbs,
9856 alc882_adc1_init_verbs },
4953550a
TI
9857 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9858 .dac_nids = alc882_dac_nids,
9859 .dig_out_nid = ALC882_DIGOUT_NID,
9860 .dig_in_nid = ALC882_DIGIN_NID,
9861 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9862 .channel_mode = alc882_sixstack_modes,
9863 .input_mux = &alc882_capture_source,
9864 },
9865 [ALC882_ARIMA] = {
9866 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9867 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9868 alc882_eapd_verbs },
4953550a
TI
9869 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9870 .dac_nids = alc882_dac_nids,
9871 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9872 .channel_mode = alc882_sixstack_modes,
9873 .input_mux = &alc882_capture_source,
9874 },
9875 [ALC882_W2JC] = {
9876 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9877 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9878 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9879 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9880 .dac_nids = alc882_dac_nids,
9881 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9882 .channel_mode = alc880_threestack_modes,
9883 .need_dac_fix = 1,
9884 .input_mux = &alc882_capture_source,
9885 .dig_out_nid = ALC882_DIGOUT_NID,
9886 },
76e6f5a9
RH
9887 [ALC885_MBA21] = {
9888 .mixers = { alc885_mba21_mixer },
9889 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9890 .num_dacs = 2,
9891 .dac_nids = alc882_dac_nids,
9892 .channel_mode = alc885_mba21_ch_modes,
9893 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9894 .input_mux = &alc882_capture_source,
9895 .unsol_event = alc_automute_amp_unsol_event,
9896 .setup = alc885_mba21_setup,
9897 .init_hook = alc_automute_amp,
9898 },
4953550a
TI
9899 [ALC885_MBP3] = {
9900 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9901 .init_verbs = { alc885_mbp3_init_verbs,
9902 alc880_gpio1_init_verbs },
be0ae923 9903 .num_dacs = 2,
4953550a 9904 .dac_nids = alc882_dac_nids,
be0ae923
TI
9905 .hp_nid = 0x04,
9906 .channel_mode = alc885_mbp_4ch_modes,
9907 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9908 .input_mux = &alc882_capture_source,
9909 .dig_out_nid = ALC882_DIGOUT_NID,
9910 .dig_in_nid = ALC882_DIGIN_NID,
9911 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9912 .setup = alc885_mbp3_setup,
9913 .init_hook = alc_automute_amp,
4953550a
TI
9914 },
9915 [ALC885_MB5] = {
9916 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9917 .init_verbs = { alc885_mb5_init_verbs,
9918 alc880_gpio1_init_verbs },
9919 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9920 .dac_nids = alc882_dac_nids,
9921 .channel_mode = alc885_mb5_6ch_modes,
9922 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9923 .input_mux = &mb5_capture_source,
9924 .dig_out_nid = ALC882_DIGOUT_NID,
9925 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9926 .unsol_event = alc_automute_amp_unsol_event,
9927 .setup = alc885_mb5_setup,
9928 .init_hook = alc_automute_amp,
4953550a 9929 },
e458b1fa
LY
9930 [ALC885_MACMINI3] = {
9931 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9932 .init_verbs = { alc885_macmini3_init_verbs,
9933 alc880_gpio1_init_verbs },
9934 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9935 .dac_nids = alc882_dac_nids,
9936 .channel_mode = alc885_macmini3_6ch_modes,
9937 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9938 .input_mux = &macmini3_capture_source,
9939 .dig_out_nid = ALC882_DIGOUT_NID,
9940 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9941 .unsol_event = alc_automute_amp_unsol_event,
9942 .setup = alc885_macmini3_setup,
9943 .init_hook = alc_automute_amp,
e458b1fa 9944 },
4953550a
TI
9945 [ALC885_MACPRO] = {
9946 .mixers = { alc882_macpro_mixer },
9947 .init_verbs = { alc882_macpro_init_verbs },
9948 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9949 .dac_nids = alc882_dac_nids,
9950 .dig_out_nid = ALC882_DIGOUT_NID,
9951 .dig_in_nid = ALC882_DIGIN_NID,
9952 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9953 .channel_mode = alc882_ch_modes,
9954 .input_mux = &alc882_capture_source,
9955 .init_hook = alc885_macpro_init_hook,
9956 },
9957 [ALC885_IMAC24] = {
9958 .mixers = { alc885_imac24_mixer },
9959 .init_verbs = { alc885_imac24_init_verbs },
9960 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9961 .dac_nids = alc882_dac_nids,
9962 .dig_out_nid = ALC882_DIGOUT_NID,
9963 .dig_in_nid = ALC882_DIGIN_NID,
9964 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9965 .channel_mode = alc882_ch_modes,
9966 .input_mux = &alc882_capture_source,
9967 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9968 .setup = alc885_imac24_setup,
4953550a
TI
9969 .init_hook = alc885_imac24_init_hook,
9970 },
4b7e1803 9971 [ALC885_IMAC91] = {
b7cccc52 9972 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
9973 .init_verbs = { alc885_imac91_init_verbs,
9974 alc880_gpio1_init_verbs },
9975 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9976 .dac_nids = alc882_dac_nids,
b7cccc52
JM
9977 .channel_mode = alc885_mba21_ch_modes,
9978 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9979 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
9980 .dig_out_nid = ALC882_DIGOUT_NID,
9981 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9982 .unsol_event = alc_automute_amp_unsol_event,
9983 .setup = alc885_imac91_setup,
9984 .init_hook = alc_automute_amp,
4b7e1803 9985 },
4953550a
TI
9986 [ALC882_TARGA] = {
9987 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9988 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9989 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9990 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9991 .dac_nids = alc882_dac_nids,
9992 .dig_out_nid = ALC882_DIGOUT_NID,
9993 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9994 .adc_nids = alc882_adc_nids,
9995 .capsrc_nids = alc882_capsrc_nids,
9996 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9997 .channel_mode = alc882_3ST_6ch_modes,
9998 .need_dac_fix = 1,
9999 .input_mux = &alc882_capture_source,
10000 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10001 .setup = alc882_targa_setup,
10002 .init_hook = alc882_targa_automute,
4953550a
TI
10003 },
10004 [ALC882_ASUS_A7J] = {
10005 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10006 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10007 alc882_asus_a7j_verbs},
4953550a
TI
10008 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10009 .dac_nids = alc882_dac_nids,
10010 .dig_out_nid = ALC882_DIGOUT_NID,
10011 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10012 .adc_nids = alc882_adc_nids,
10013 .capsrc_nids = alc882_capsrc_nids,
10014 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10015 .channel_mode = alc882_3ST_6ch_modes,
10016 .need_dac_fix = 1,
10017 .input_mux = &alc882_capture_source,
10018 },
10019 [ALC882_ASUS_A7M] = {
10020 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10021 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10022 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10023 alc882_asus_a7m_verbs },
10024 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10025 .dac_nids = alc882_dac_nids,
10026 .dig_out_nid = ALC882_DIGOUT_NID,
10027 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10028 .channel_mode = alc880_threestack_modes,
10029 .need_dac_fix = 1,
10030 .input_mux = &alc882_capture_source,
10031 },
9c7f852e
TI
10032 [ALC883_3ST_2ch_DIG] = {
10033 .mixers = { alc883_3ST_2ch_mixer },
10034 .init_verbs = { alc883_init_verbs },
10035 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10036 .dac_nids = alc883_dac_nids,
10037 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10038 .dig_in_nid = ALC883_DIGIN_NID,
10039 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10040 .channel_mode = alc883_3ST_2ch_modes,
10041 .input_mux = &alc883_capture_source,
10042 },
10043 [ALC883_3ST_6ch_DIG] = {
10044 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10045 .init_verbs = { alc883_init_verbs },
10046 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10047 .dac_nids = alc883_dac_nids,
10048 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10049 .dig_in_nid = ALC883_DIGIN_NID,
10050 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10051 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10052 .need_dac_fix = 1,
9c7f852e 10053 .input_mux = &alc883_capture_source,
f12ab1e0 10054 },
9c7f852e
TI
10055 [ALC883_3ST_6ch] = {
10056 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10057 .init_verbs = { alc883_init_verbs },
10058 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10059 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10060 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10061 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10062 .need_dac_fix = 1,
9c7f852e 10063 .input_mux = &alc883_capture_source,
f12ab1e0 10064 },
17bba1b7
J
10065 [ALC883_3ST_6ch_INTEL] = {
10066 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10067 .init_verbs = { alc883_init_verbs },
10068 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10069 .dac_nids = alc883_dac_nids,
10070 .dig_out_nid = ALC883_DIGOUT_NID,
10071 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10072 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10073 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10074 .channel_mode = alc883_3ST_6ch_intel_modes,
10075 .need_dac_fix = 1,
10076 .input_mux = &alc883_3stack_6ch_intel,
10077 },
87a8c370
JK
10078 [ALC889A_INTEL] = {
10079 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10080 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10081 alc_hp15_unsol_verbs },
87a8c370
JK
10082 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10083 .dac_nids = alc883_dac_nids,
10084 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10085 .adc_nids = alc889_adc_nids,
10086 .dig_out_nid = ALC883_DIGOUT_NID,
10087 .dig_in_nid = ALC883_DIGIN_NID,
10088 .slave_dig_outs = alc883_slave_dig_outs,
10089 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10090 .channel_mode = alc889_8ch_intel_modes,
10091 .capsrc_nids = alc889_capsrc_nids,
10092 .input_mux = &alc889_capture_source,
4f5d1706
TI
10093 .setup = alc889_automute_setup,
10094 .init_hook = alc_automute_amp,
6732bd0d 10095 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10096 .need_dac_fix = 1,
10097 },
10098 [ALC889_INTEL] = {
10099 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10100 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10101 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10102 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10103 .dac_nids = alc883_dac_nids,
10104 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10105 .adc_nids = alc889_adc_nids,
10106 .dig_out_nid = ALC883_DIGOUT_NID,
10107 .dig_in_nid = ALC883_DIGIN_NID,
10108 .slave_dig_outs = alc883_slave_dig_outs,
10109 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10110 .channel_mode = alc889_8ch_intel_modes,
10111 .capsrc_nids = alc889_capsrc_nids,
10112 .input_mux = &alc889_capture_source,
4f5d1706 10113 .setup = alc889_automute_setup,
6732bd0d
WF
10114 .init_hook = alc889_intel_init_hook,
10115 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10116 .need_dac_fix = 1,
10117 },
9c7f852e
TI
10118 [ALC883_6ST_DIG] = {
10119 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10120 .init_verbs = { alc883_init_verbs },
10121 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10122 .dac_nids = alc883_dac_nids,
10123 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10124 .dig_in_nid = ALC883_DIGIN_NID,
10125 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10126 .channel_mode = alc883_sixstack_modes,
10127 .input_mux = &alc883_capture_source,
10128 },
ccc656ce 10129 [ALC883_TARGA_DIG] = {
c259249f 10130 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10131 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10132 alc883_targa_verbs},
ccc656ce
KY
10133 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10134 .dac_nids = alc883_dac_nids,
10135 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10136 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10137 .channel_mode = alc883_3ST_6ch_modes,
10138 .need_dac_fix = 1,
10139 .input_mux = &alc883_capture_source,
c259249f 10140 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10141 .setup = alc882_targa_setup,
10142 .init_hook = alc882_targa_automute,
ccc656ce
KY
10143 },
10144 [ALC883_TARGA_2ch_DIG] = {
c259249f 10145 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10146 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10147 alc883_targa_verbs},
ccc656ce
KY
10148 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10149 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10150 .adc_nids = alc883_adc_nids_alt,
10151 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10152 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10153 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10154 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10155 .channel_mode = alc883_3ST_2ch_modes,
10156 .input_mux = &alc883_capture_source,
c259249f 10157 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10158 .setup = alc882_targa_setup,
10159 .init_hook = alc882_targa_automute,
ccc656ce 10160 },
64a8be74 10161 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10162 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10163 alc883_chmode_mixer },
64a8be74 10164 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10165 alc883_targa_verbs },
64a8be74
DH
10166 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10167 .dac_nids = alc883_dac_nids,
10168 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10169 .adc_nids = alc883_adc_nids_rev,
10170 .capsrc_nids = alc883_capsrc_nids_rev,
10171 .dig_out_nid = ALC883_DIGOUT_NID,
10172 .dig_in_nid = ALC883_DIGIN_NID,
10173 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10174 .channel_mode = alc883_4ST_8ch_modes,
10175 .need_dac_fix = 1,
10176 .input_mux = &alc883_capture_source,
c259249f 10177 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10178 .setup = alc882_targa_setup,
10179 .init_hook = alc882_targa_automute,
64a8be74 10180 },
bab282b9 10181 [ALC883_ACER] = {
676a9b53 10182 .mixers = { alc883_base_mixer },
bab282b9
VA
10183 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10184 * and the headphone jack. Turn this on and rely on the
10185 * standard mute methods whenever the user wants to turn
10186 * these outputs off.
10187 */
10188 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10189 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10190 .dac_nids = alc883_dac_nids,
bab282b9
VA
10191 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10192 .channel_mode = alc883_3ST_2ch_modes,
10193 .input_mux = &alc883_capture_source,
10194 },
2880a867 10195 [ALC883_ACER_ASPIRE] = {
676a9b53 10196 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10197 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10198 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10199 .dac_nids = alc883_dac_nids,
10200 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10201 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10202 .channel_mode = alc883_3ST_2ch_modes,
10203 .input_mux = &alc883_capture_source,
a9fd4f3f 10204 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10205 .setup = alc883_acer_aspire_setup,
10206 .init_hook = alc_automute_amp,
d1a991a6 10207 },
5b2d1eca 10208 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10209 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10210 alc883_chmode_mixer },
10211 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10212 alc888_acer_aspire_4930g_verbs },
10213 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10214 .dac_nids = alc883_dac_nids,
10215 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10216 .adc_nids = alc883_adc_nids_rev,
10217 .capsrc_nids = alc883_capsrc_nids_rev,
10218 .dig_out_nid = ALC883_DIGOUT_NID,
10219 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10220 .channel_mode = alc883_3ST_6ch_modes,
10221 .need_dac_fix = 1,
973b8cb0 10222 .const_channel_count = 6,
5b2d1eca 10223 .num_mux_defs =
ef8ef5fb
VP
10224 ARRAY_SIZE(alc888_2_capture_sources),
10225 .input_mux = alc888_2_capture_sources,
d2fd4b09 10226 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10227 .setup = alc888_acer_aspire_4930g_setup,
10228 .init_hook = alc_automute_amp,
d2fd4b09
TV
10229 },
10230 [ALC888_ACER_ASPIRE_6530G] = {
10231 .mixers = { alc888_acer_aspire_6530_mixer },
10232 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10233 alc888_acer_aspire_6530g_verbs },
10234 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10235 .dac_nids = alc883_dac_nids,
10236 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10237 .adc_nids = alc883_adc_nids_rev,
10238 .capsrc_nids = alc883_capsrc_nids_rev,
10239 .dig_out_nid = ALC883_DIGOUT_NID,
10240 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10241 .channel_mode = alc883_3ST_2ch_modes,
10242 .num_mux_defs =
10243 ARRAY_SIZE(alc888_2_capture_sources),
10244 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10245 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10246 .setup = alc888_acer_aspire_6530g_setup,
10247 .init_hook = alc_automute_amp,
5b2d1eca 10248 },
3b315d70 10249 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10250 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10251 alc883_chmode_mixer },
10252 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10253 alc889_acer_aspire_8930g_verbs,
10254 alc889_eapd_verbs},
3b315d70
HM
10255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256 .dac_nids = alc883_dac_nids,
018df418
HM
10257 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10258 .adc_nids = alc889_adc_nids,
10259 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10260 .dig_out_nid = ALC883_DIGOUT_NID,
10261 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10262 .channel_mode = alc883_3ST_6ch_modes,
10263 .need_dac_fix = 1,
10264 .const_channel_count = 6,
10265 .num_mux_defs =
018df418
HM
10266 ARRAY_SIZE(alc889_capture_sources),
10267 .input_mux = alc889_capture_sources,
3b315d70 10268 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10269 .setup = alc889_acer_aspire_8930g_setup,
10270 .init_hook = alc_automute_amp,
f5de24b0 10271#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10272 .power_hook = alc_power_eapd,
f5de24b0 10273#endif
3b315d70 10274 },
fc86f954
DK
10275 [ALC888_ACER_ASPIRE_7730G] = {
10276 .mixers = { alc883_3ST_6ch_mixer,
10277 alc883_chmode_mixer },
10278 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10279 alc888_acer_aspire_7730G_verbs },
10280 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10281 .dac_nids = alc883_dac_nids,
10282 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10283 .adc_nids = alc883_adc_nids_rev,
10284 .capsrc_nids = alc883_capsrc_nids_rev,
10285 .dig_out_nid = ALC883_DIGOUT_NID,
10286 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10287 .channel_mode = alc883_3ST_6ch_modes,
10288 .need_dac_fix = 1,
10289 .const_channel_count = 6,
10290 .input_mux = &alc883_capture_source,
10291 .unsol_event = alc_automute_amp_unsol_event,
10292 .setup = alc888_acer_aspire_6530g_setup,
10293 .init_hook = alc_automute_amp,
10294 },
c07584c8
TD
10295 [ALC883_MEDION] = {
10296 .mixers = { alc883_fivestack_mixer,
10297 alc883_chmode_mixer },
10298 .init_verbs = { alc883_init_verbs,
b373bdeb 10299 alc883_medion_eapd_verbs },
c07584c8
TD
10300 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10301 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10302 .adc_nids = alc883_adc_nids_alt,
10303 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10304 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10305 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10306 .channel_mode = alc883_sixstack_modes,
10307 .input_mux = &alc883_capture_source,
b373bdeb 10308 },
272a527c
KY
10309 [ALC883_MEDION_MD2] = {
10310 .mixers = { alc883_medion_md2_mixer},
10311 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10312 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10313 .dac_nids = alc883_dac_nids,
10314 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10315 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10316 .channel_mode = alc883_3ST_2ch_modes,
10317 .input_mux = &alc883_capture_source,
a9fd4f3f 10318 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10319 .setup = alc883_medion_md2_setup,
10320 .init_hook = alc_automute_amp,
ea1fb29a 10321 },
7ad7b218
MC
10322 [ALC883_MEDION_WIM2160] = {
10323 .mixers = { alc883_medion_wim2160_mixer },
10324 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10325 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10326 .dac_nids = alc883_dac_nids,
10327 .dig_out_nid = ALC883_DIGOUT_NID,
10328 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10329 .adc_nids = alc883_adc_nids,
10330 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10331 .channel_mode = alc883_3ST_2ch_modes,
10332 .input_mux = &alc883_capture_source,
10333 .unsol_event = alc_automute_amp_unsol_event,
10334 .setup = alc883_medion_wim2160_setup,
10335 .init_hook = alc_automute_amp,
10336 },
b373bdeb 10337 [ALC883_LAPTOP_EAPD] = {
676a9b53 10338 .mixers = { alc883_base_mixer },
b373bdeb
AN
10339 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10340 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10341 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10342 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10343 .channel_mode = alc883_3ST_2ch_modes,
10344 .input_mux = &alc883_capture_source,
10345 },
a65cc60f 10346 [ALC883_CLEVO_M540R] = {
10347 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10348 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10349 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10350 .dac_nids = alc883_dac_nids,
10351 .dig_out_nid = ALC883_DIGOUT_NID,
10352 .dig_in_nid = ALC883_DIGIN_NID,
10353 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10354 .channel_mode = alc883_3ST_6ch_clevo_modes,
10355 .need_dac_fix = 1,
10356 .input_mux = &alc883_capture_source,
10357 /* This machine has the hardware HP auto-muting, thus
10358 * we need no software mute via unsol event
10359 */
10360 },
0c4cc443
HRK
10361 [ALC883_CLEVO_M720] = {
10362 .mixers = { alc883_clevo_m720_mixer },
10363 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10364 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10365 .dac_nids = alc883_dac_nids,
10366 .dig_out_nid = ALC883_DIGOUT_NID,
10367 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10368 .channel_mode = alc883_3ST_2ch_modes,
10369 .input_mux = &alc883_capture_source,
0c4cc443 10370 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10371 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10372 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10373 },
bc9f98a9
KY
10374 [ALC883_LENOVO_101E_2ch] = {
10375 .mixers = { alc883_lenovo_101e_2ch_mixer},
10376 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10377 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10378 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10379 .adc_nids = alc883_adc_nids_alt,
10380 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10381 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10382 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10383 .channel_mode = alc883_3ST_2ch_modes,
10384 .input_mux = &alc883_lenovo_101e_capture_source,
10385 .unsol_event = alc883_lenovo_101e_unsol_event,
10386 .init_hook = alc883_lenovo_101e_all_automute,
10387 },
272a527c
KY
10388 [ALC883_LENOVO_NB0763] = {
10389 .mixers = { alc883_lenovo_nb0763_mixer },
10390 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10391 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10392 .dac_nids = alc883_dac_nids,
272a527c
KY
10393 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10394 .channel_mode = alc883_3ST_2ch_modes,
10395 .need_dac_fix = 1,
10396 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10397 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10398 .setup = alc883_medion_md2_setup,
10399 .init_hook = alc_automute_amp,
272a527c
KY
10400 },
10401 [ALC888_LENOVO_MS7195_DIG] = {
10402 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10403 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10404 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10405 .dac_nids = alc883_dac_nids,
10406 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10407 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10408 .channel_mode = alc883_3ST_6ch_modes,
10409 .need_dac_fix = 1,
10410 .input_mux = &alc883_capture_source,
10411 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10412 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10413 },
10414 [ALC883_HAIER_W66] = {
c259249f 10415 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10416 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10417 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10418 .dac_nids = alc883_dac_nids,
10419 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10420 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10421 .channel_mode = alc883_3ST_2ch_modes,
10422 .input_mux = &alc883_capture_source,
a9fd4f3f 10423 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10424 .setup = alc883_haier_w66_setup,
10425 .init_hook = alc_automute_amp,
eea6419e 10426 },
4723c022 10427 [ALC888_3ST_HP] = {
eea6419e 10428 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10429 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10430 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10431 .dac_nids = alc883_dac_nids,
4723c022
CM
10432 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10433 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10434 .need_dac_fix = 1,
10435 .input_mux = &alc883_capture_source,
a9fd4f3f 10436 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10437 .setup = alc888_3st_hp_setup,
10438 .init_hook = alc_automute_amp,
8341de60 10439 },
5795b9e6 10440 [ALC888_6ST_DELL] = {
f24dbdc6 10441 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10442 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10443 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10444 .dac_nids = alc883_dac_nids,
10445 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10446 .dig_in_nid = ALC883_DIGIN_NID,
10447 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10448 .channel_mode = alc883_sixstack_modes,
10449 .input_mux = &alc883_capture_source,
a9fd4f3f 10450 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10451 .setup = alc888_6st_dell_setup,
10452 .init_hook = alc_automute_amp,
5795b9e6 10453 },
a8848bd6
AS
10454 [ALC883_MITAC] = {
10455 .mixers = { alc883_mitac_mixer },
10456 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10457 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10458 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10459 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10460 .channel_mode = alc883_3ST_2ch_modes,
10461 .input_mux = &alc883_capture_source,
a9fd4f3f 10462 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10463 .setup = alc883_mitac_setup,
10464 .init_hook = alc_automute_amp,
a8848bd6 10465 },
fb97dc67
J
10466 [ALC883_FUJITSU_PI2515] = {
10467 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10468 .init_verbs = { alc883_init_verbs,
10469 alc883_2ch_fujitsu_pi2515_verbs},
10470 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10471 .dac_nids = alc883_dac_nids,
10472 .dig_out_nid = ALC883_DIGOUT_NID,
10473 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10474 .channel_mode = alc883_3ST_2ch_modes,
10475 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10476 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10477 .setup = alc883_2ch_fujitsu_pi2515_setup,
10478 .init_hook = alc_automute_amp,
fb97dc67 10479 },
ef8ef5fb
VP
10480 [ALC888_FUJITSU_XA3530] = {
10481 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10482 .init_verbs = { alc883_init_verbs,
10483 alc888_fujitsu_xa3530_verbs },
10484 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10485 .dac_nids = alc883_dac_nids,
10486 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10487 .adc_nids = alc883_adc_nids_rev,
10488 .capsrc_nids = alc883_capsrc_nids_rev,
10489 .dig_out_nid = ALC883_DIGOUT_NID,
10490 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10491 .channel_mode = alc888_4ST_8ch_intel_modes,
10492 .num_mux_defs =
10493 ARRAY_SIZE(alc888_2_capture_sources),
10494 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10495 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10496 .setup = alc888_fujitsu_xa3530_setup,
10497 .init_hook = alc_automute_amp,
ef8ef5fb 10498 },
e2757d5e
KY
10499 [ALC888_LENOVO_SKY] = {
10500 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10501 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10502 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10503 .dac_nids = alc883_dac_nids,
10504 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10505 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10506 .channel_mode = alc883_sixstack_modes,
10507 .need_dac_fix = 1,
10508 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10509 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10510 .setup = alc888_lenovo_sky_setup,
10511 .init_hook = alc_automute_amp,
e2757d5e
KY
10512 },
10513 [ALC888_ASUS_M90V] = {
10514 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10515 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10516 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10517 .dac_nids = alc883_dac_nids,
10518 .dig_out_nid = ALC883_DIGOUT_NID,
10519 .dig_in_nid = ALC883_DIGIN_NID,
10520 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10521 .channel_mode = alc883_3ST_6ch_modes,
10522 .need_dac_fix = 1,
10523 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10524 .unsol_event = alc_sku_unsol_event,
10525 .setup = alc883_mode2_setup,
10526 .init_hook = alc_inithook,
e2757d5e
KY
10527 },
10528 [ALC888_ASUS_EEE1601] = {
10529 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10530 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10531 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10532 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10533 .dac_nids = alc883_dac_nids,
10534 .dig_out_nid = ALC883_DIGOUT_NID,
10535 .dig_in_nid = ALC883_DIGIN_NID,
10536 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10537 .channel_mode = alc883_3ST_2ch_modes,
10538 .need_dac_fix = 1,
10539 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10540 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10541 .init_hook = alc883_eee1601_inithook,
10542 },
3ab90935
WF
10543 [ALC1200_ASUS_P5Q] = {
10544 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10545 .init_verbs = { alc883_init_verbs },
10546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10547 .dac_nids = alc883_dac_nids,
10548 .dig_out_nid = ALC1200_DIGOUT_NID,
10549 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10550 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10551 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10552 .channel_mode = alc883_sixstack_modes,
10553 .input_mux = &alc883_capture_source,
10554 },
eb4c41d3
TS
10555 [ALC889A_MB31] = {
10556 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10557 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10558 alc880_gpio1_init_verbs },
10559 .adc_nids = alc883_adc_nids,
10560 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10561 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10562 .dac_nids = alc883_dac_nids,
10563 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10564 .channel_mode = alc889A_mb31_6ch_modes,
10565 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10566 .input_mux = &alc889A_mb31_capture_source,
10567 .dig_out_nid = ALC883_DIGOUT_NID,
10568 .unsol_event = alc889A_mb31_unsol_event,
10569 .init_hook = alc889A_mb31_automute,
10570 },
3e1647c5
GG
10571 [ALC883_SONY_VAIO_TT] = {
10572 .mixers = { alc883_vaiott_mixer },
10573 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10574 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10575 .dac_nids = alc883_dac_nids,
10576 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10577 .channel_mode = alc883_3ST_2ch_modes,
10578 .input_mux = &alc883_capture_source,
10579 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10580 .setup = alc883_vaiott_setup,
10581 .init_hook = alc_automute_amp,
3e1647c5 10582 },
9c7f852e
TI
10583};
10584
10585
4953550a
TI
10586/*
10587 * Pin config fixes
10588 */
10589enum {
954a29c8
TI
10590 PINFIX_ABIT_AW9D_MAX,
10591 PINFIX_PB_M5210,
4953550a
TI
10592};
10593
f8f25ba3
TI
10594static const struct alc_fixup alc882_fixups[] = {
10595 [PINFIX_ABIT_AW9D_MAX] = {
73413b12
TI
10596 .pins = (const struct alc_pincfg[]) {
10597 { 0x15, 0x01080104 }, /* side */
10598 { 0x16, 0x01011012 }, /* rear */
10599 { 0x17, 0x01016011 }, /* clfe */
10600 { }
10601 }
f8f25ba3 10602 },
954a29c8 10603 [PINFIX_PB_M5210] = {
73413b12
TI
10604 .verbs = (const struct hda_verb[]) {
10605 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10606 {}
10607 }
954a29c8 10608 },
4953550a
TI
10609};
10610
f8f25ba3 10611static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10612 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a
TI
10613 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10614 {}
10615};
10616
9c7f852e
TI
10617/*
10618 * BIOS auto configuration
10619 */
05f5f477
TI
10620static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10621 const struct auto_pin_cfg *cfg)
10622{
10623 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10624}
10625
4953550a 10626static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10627 hda_nid_t nid, int pin_type,
489008cd 10628 hda_nid_t dac)
9c7f852e 10629{
f12ab1e0
TI
10630 int idx;
10631
489008cd 10632 /* set as output */
f6c7e546 10633 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10634
10635 if (dac == 0x25)
9c7f852e 10636 idx = 4;
489008cd
TI
10637 else if (dac >= 0x02 && dac <= 0x05)
10638 idx = dac - 2;
f9700d5a 10639 else
489008cd 10640 return;
9c7f852e 10641 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10642}
10643
4953550a 10644static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10645{
10646 struct alc_spec *spec = codec->spec;
10647 int i;
10648
10649 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10650 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10651 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10652 if (nid)
4953550a 10653 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10654 spec->multiout.dac_nids[i]);
9c7f852e
TI
10655 }
10656}
10657
4953550a 10658static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10659{
10660 struct alc_spec *spec = codec->spec;
489008cd 10661 hda_nid_t pin, dac;
5855fb80 10662 int i;
9c7f852e 10663
5855fb80
TI
10664 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10665 pin = spec->autocfg.hp_pins[i];
10666 if (!pin)
10667 break;
489008cd
TI
10668 dac = spec->multiout.hp_nid;
10669 if (!dac)
10670 dac = spec->multiout.dac_nids[0]; /* to front */
10671 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10672 }
5855fb80
TI
10673 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10674 pin = spec->autocfg.speaker_pins[i];
10675 if (!pin)
10676 break;
489008cd
TI
10677 dac = spec->multiout.extra_out_nid[0];
10678 if (!dac)
10679 dac = spec->multiout.dac_nids[0]; /* to front */
10680 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10681 }
9c7f852e
TI
10682}
10683
4953550a 10684static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10685{
10686 struct alc_spec *spec = codec->spec;
66ceeb6b 10687 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10688 int i;
10689
66ceeb6b
TI
10690 for (i = 0; i < cfg->num_inputs; i++) {
10691 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10692 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10693 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10694 snd_hda_codec_write(codec, nid, 0,
10695 AC_VERB_SET_AMP_GAIN_MUTE,
10696 AMP_OUT_MUTE);
10697 }
10698}
10699
10700static void alc882_auto_init_input_src(struct hda_codec *codec)
10701{
10702 struct alc_spec *spec = codec->spec;
10703 int c;
10704
10705 for (c = 0; c < spec->num_adc_nids; c++) {
10706 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10707 hda_nid_t nid = spec->capsrc_nids[c];
10708 unsigned int mux_idx;
10709 const struct hda_input_mux *imux;
10710 int conns, mute, idx, item;
10711
10712 conns = snd_hda_get_connections(codec, nid, conn_list,
10713 ARRAY_SIZE(conn_list));
10714 if (conns < 0)
10715 continue;
10716 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10717 imux = &spec->input_mux[mux_idx];
5311114d
TI
10718 if (!imux->num_items && mux_idx > 0)
10719 imux = &spec->input_mux[0];
4953550a
TI
10720 for (idx = 0; idx < conns; idx++) {
10721 /* if the current connection is the selected one,
10722 * unmute it as default - otherwise mute it
10723 */
10724 mute = AMP_IN_MUTE(idx);
10725 for (item = 0; item < imux->num_items; item++) {
10726 if (imux->items[item].index == idx) {
10727 if (spec->cur_mux[c] == item)
10728 mute = AMP_IN_UNMUTE(idx);
10729 break;
10730 }
10731 }
10732 /* check if we have a selector or mixer
10733 * we could check for the widget type instead, but
10734 * just check for Amp-In presence (in case of mixer
10735 * without amp-in there is something wrong, this
10736 * function shouldn't be used or capsrc nid is wrong)
10737 */
10738 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10739 snd_hda_codec_write(codec, nid, 0,
10740 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10741 mute);
10742 else if (mute != AMP_IN_MUTE(idx))
10743 snd_hda_codec_write(codec, nid, 0,
10744 AC_VERB_SET_CONNECT_SEL,
10745 idx);
9c7f852e
TI
10746 }
10747 }
10748}
10749
4953550a
TI
10750/* add mic boosts if needed */
10751static int alc_auto_add_mic_boost(struct hda_codec *codec)
10752{
10753 struct alc_spec *spec = codec->spec;
66ceeb6b
TI
10754 struct auto_pin_cfg *cfg = &spec->autocfg;
10755 int i, err;
4953550a
TI
10756 hda_nid_t nid;
10757
66ceeb6b 10758 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10759 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10760 break;
10761 nid = cfg->inputs[i].pin;
10762 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10a20af7
TI
10763 char label[32];
10764 snprintf(label, sizeof(label), "%s Boost",
10765 hda_get_autocfg_input_label(codec, cfg, i));
66ceeb6b 10766 err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0,
4953550a 10767 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10768 if (err < 0)
10769 return err;
10770 }
4953550a
TI
10771 }
10772 return 0;
10773}
f511b01c 10774
9c7f852e 10775/* almost identical with ALC880 parser... */
4953550a 10776static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10777{
10778 struct alc_spec *spec = codec->spec;
05f5f477 10779 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10780 int err;
9c7f852e 10781
05f5f477
TI
10782 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10783 alc882_ignore);
9c7f852e
TI
10784 if (err < 0)
10785 return err;
05f5f477
TI
10786 if (!spec->autocfg.line_outs)
10787 return 0; /* can't find valid BIOS pin config */
776e184e 10788
05f5f477
TI
10789 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10790 if (err < 0)
10791 return err;
10792 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10793 if (err < 0)
10794 return err;
10795 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10796 "Headphone");
05f5f477
TI
10797 if (err < 0)
10798 return err;
10799 err = alc880_auto_create_extra_out(spec,
10800 spec->autocfg.speaker_pins[0],
10801 "Speaker");
10802 if (err < 0)
10803 return err;
05f5f477 10804 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10805 if (err < 0)
10806 return err;
10807
05f5f477
TI
10808 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10809
757899ac 10810 alc_auto_parse_digital(codec);
05f5f477
TI
10811
10812 if (spec->kctls.list)
10813 add_mixer(spec, spec->kctls.list);
10814
10815 add_verb(spec, alc883_auto_init_verbs);
4953550a 10816 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10817 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10818 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10819
05f5f477
TI
10820 spec->num_mux_defs = 1;
10821 spec->input_mux = &spec->private_imux[0];
10822
6227cdce 10823 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10824
10825 err = alc_auto_add_mic_boost(codec);
10826 if (err < 0)
10827 return err;
61b9b9b1 10828
776e184e 10829 return 1; /* config found */
9c7f852e
TI
10830}
10831
10832/* additional initialization for auto-configuration model */
4953550a 10833static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10834{
f6c7e546 10835 struct alc_spec *spec = codec->spec;
4953550a
TI
10836 alc882_auto_init_multi_out(codec);
10837 alc882_auto_init_hp_out(codec);
10838 alc882_auto_init_analog_input(codec);
10839 alc882_auto_init_input_src(codec);
757899ac 10840 alc_auto_init_digital(codec);
f6c7e546 10841 if (spec->unsol_event)
7fb0d78f 10842 alc_inithook(codec);
9c7f852e
TI
10843}
10844
4953550a 10845static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10846{
10847 struct alc_spec *spec;
10848 int err, board_config;
10849
10850 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10851 if (spec == NULL)
10852 return -ENOMEM;
10853
10854 codec->spec = spec;
10855
da00c244
KY
10856 alc_auto_parse_customize_define(codec);
10857
4953550a
TI
10858 switch (codec->vendor_id) {
10859 case 0x10ec0882:
10860 case 0x10ec0885:
10861 break;
10862 default:
10863 /* ALC883 and variants */
10864 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10865 break;
10866 }
2c3bf9ab 10867
4953550a
TI
10868 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10869 alc882_models,
10870 alc882_cfg_tbl);
10871
10872 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10873 board_config = snd_hda_check_board_codec_sid_config(codec,
10874 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10875
10876 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10877 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10878 codec->chip_name);
10879 board_config = ALC882_AUTO;
9c7f852e
TI
10880 }
10881
7fa90e87
TI
10882 if (board_config == ALC882_AUTO)
10883 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a
TI
10884
10885 if (board_config == ALC882_AUTO) {
9c7f852e 10886 /* automatic parse from the BIOS config */
4953550a 10887 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10888 if (err < 0) {
10889 alc_free(codec);
10890 return err;
f12ab1e0 10891 } else if (!err) {
9c7f852e
TI
10892 printk(KERN_INFO
10893 "hda_codec: Cannot set up configuration "
10894 "from BIOS. Using base mode...\n");
4953550a 10895 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10896 }
10897 }
10898
dc1eae25 10899 if (has_cdefine_beep(codec)) {
8af2591d
TI
10900 err = snd_hda_attach_beep_device(codec, 0x1);
10901 if (err < 0) {
10902 alc_free(codec);
10903 return err;
10904 }
680cd536
KK
10905 }
10906
4953550a 10907 if (board_config != ALC882_AUTO)
e9c364c0 10908 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10909
4953550a
TI
10910 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10911 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10912 /* FIXME: setup DAC5 */
10913 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10914 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10915
10916 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10917 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10918
4953550a 10919 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10920 int i, j;
4953550a
TI
10921 spec->num_adc_nids = 0;
10922 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10923 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10924 hda_nid_t cap;
d11f74c6 10925 hda_nid_t items[16];
4953550a
TI
10926 hda_nid_t nid = alc882_adc_nids[i];
10927 unsigned int wcap = get_wcaps(codec, nid);
10928 /* get type */
a22d543a 10929 wcap = get_wcaps_type(wcap);
4953550a
TI
10930 if (wcap != AC_WID_AUD_IN)
10931 continue;
10932 spec->private_adc_nids[spec->num_adc_nids] = nid;
10933 err = snd_hda_get_connections(codec, nid, &cap, 1);
10934 if (err < 0)
10935 continue;
d11f74c6
TI
10936 err = snd_hda_get_connections(codec, cap, items,
10937 ARRAY_SIZE(items));
10938 if (err < 0)
10939 continue;
10940 for (j = 0; j < imux->num_items; j++)
10941 if (imux->items[j].index >= err)
10942 break;
10943 if (j < imux->num_items)
10944 continue;
4953550a
TI
10945 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10946 spec->num_adc_nids++;
61b9b9b1 10947 }
4953550a
TI
10948 spec->adc_nids = spec->private_adc_nids;
10949 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10950 }
10951
b59bdf3b 10952 set_capture_mixer(codec);
da00c244 10953
dc1eae25 10954 if (has_cdefine_beep(codec))
da00c244 10955 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10956
7fa90e87
TI
10957 if (board_config == ALC882_AUTO)
10958 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10959
2134ea4f
TI
10960 spec->vmaster_nid = 0x0c;
10961
9c7f852e 10962 codec->patch_ops = alc_patch_ops;
4953550a
TI
10963 if (board_config == ALC882_AUTO)
10964 spec->init_hook = alc882_auto_init;
cb53c626
TI
10965#ifdef CONFIG_SND_HDA_POWER_SAVE
10966 if (!spec->loopback.amplist)
4953550a 10967 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10968#endif
9c7f852e
TI
10969
10970 return 0;
10971}
10972
4953550a 10973
9c7f852e
TI
10974/*
10975 * ALC262 support
10976 */
10977
10978#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10979#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10980
10981#define alc262_dac_nids alc260_dac_nids
10982#define alc262_adc_nids alc882_adc_nids
10983#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10984#define alc262_capsrc_nids alc882_capsrc_nids
10985#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10986
10987#define alc262_modes alc260_modes
10988#define alc262_capture_source alc882_capture_source
10989
4e555fe5
KY
10990static hda_nid_t alc262_dmic_adc_nids[1] = {
10991 /* ADC0 */
10992 0x09
10993};
10994
10995static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10996
9c7f852e
TI
10997static struct snd_kcontrol_new alc262_base_mixer[] = {
10998 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10999 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11000 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11001 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11005 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 11006 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11007 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11008 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 11009 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11010 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11012 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11013 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11014 { } /* end */
11015};
11016
ce875f07
TI
11017/* update HP, line and mono-out pins according to the master switch */
11018static void alc262_hp_master_update(struct hda_codec *codec)
11019{
11020 struct alc_spec *spec = codec->spec;
11021 int val = spec->master_sw;
11022
11023 /* HP & line-out */
11024 snd_hda_codec_write_cache(codec, 0x1b, 0,
11025 AC_VERB_SET_PIN_WIDGET_CONTROL,
11026 val ? PIN_HP : 0);
11027 snd_hda_codec_write_cache(codec, 0x15, 0,
11028 AC_VERB_SET_PIN_WIDGET_CONTROL,
11029 val ? PIN_HP : 0);
11030 /* mono (speaker) depending on the HP jack sense */
11031 val = val && !spec->jack_present;
11032 snd_hda_codec_write_cache(codec, 0x16, 0,
11033 AC_VERB_SET_PIN_WIDGET_CONTROL,
11034 val ? PIN_OUT : 0);
11035}
11036
11037static void alc262_hp_bpc_automute(struct hda_codec *codec)
11038{
11039 struct alc_spec *spec = codec->spec;
864f92be
WF
11040
11041 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11042 alc262_hp_master_update(codec);
11043}
11044
11045static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11046{
11047 if ((res >> 26) != ALC880_HP_EVENT)
11048 return;
11049 alc262_hp_bpc_automute(codec);
11050}
11051
11052static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11053{
11054 struct alc_spec *spec = codec->spec;
864f92be
WF
11055
11056 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11057 alc262_hp_master_update(codec);
11058}
11059
11060static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11061 unsigned int res)
11062{
11063 if ((res >> 26) != ALC880_HP_EVENT)
11064 return;
11065 alc262_hp_wildwest_automute(codec);
11066}
11067
b72519b5 11068#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11069
11070static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11071 struct snd_ctl_elem_value *ucontrol)
11072{
11073 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11074 struct alc_spec *spec = codec->spec;
11075 int val = !!*ucontrol->value.integer.value;
11076
11077 if (val == spec->master_sw)
11078 return 0;
11079 spec->master_sw = val;
11080 alc262_hp_master_update(codec);
11081 return 1;
11082}
11083
b72519b5
TI
11084#define ALC262_HP_MASTER_SWITCH \
11085 { \
11086 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11087 .name = "Master Playback Switch", \
11088 .info = snd_ctl_boolean_mono_info, \
11089 .get = alc262_hp_master_sw_get, \
11090 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11091 }, \
11092 { \
11093 .iface = NID_MAPPING, \
11094 .name = "Master Playback Switch", \
11095 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11096 }
11097
5b0cb1d8 11098
9c7f852e 11099static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11100 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11101 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11102 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11103 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11104 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11105 HDA_OUTPUT),
11106 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11107 HDA_OUTPUT),
9c7f852e
TI
11108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 11110 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11111 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11112 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 11113 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11114 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11115 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11116 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11117 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11118 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11119 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11120 { } /* end */
11121};
11122
cd7509a4 11123static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11124 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11125 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11126 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11127 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11128 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11129 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11130 HDA_OUTPUT),
11131 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11132 HDA_OUTPUT),
cd7509a4
KY
11133 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11134 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 11135 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11136 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11137 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11138 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11139 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11140 { } /* end */
11141};
11142
11143static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11144 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11145 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 11146 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11147 { } /* end */
11148};
11149
66d2a9d6 11150/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11151static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11152{
11153 struct alc_spec *spec = codec->spec;
66d2a9d6 11154
a9fd4f3f 11155 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11156 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11157}
11158
66d2a9d6 11159static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11160 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11161 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11162 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11165 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11166 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11167 { } /* end */
11168};
11169
11170static struct hda_verb alc262_hp_t5735_verbs[] = {
11171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11172 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11173
11174 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11175 { }
11176};
11177
8c427226 11178static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11179 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11180 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11181 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11182 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11183 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11184 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11185 { } /* end */
11186};
11187
11188static struct hda_verb alc262_hp_rp5700_verbs[] = {
11189 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11190 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11191 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11192 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11193 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11194 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11195 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11196 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11197 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11199 {}
11200};
11201
11202static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11203 .num_items = 1,
11204 .items = {
11205 { "Line", 0x1 },
11206 },
11207};
11208
42171c17
TI
11209/* bind hp and internal speaker mute (with plug check) as master switch */
11210static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11211{
42171c17
TI
11212 struct alc_spec *spec = codec->spec;
11213 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11214 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11215 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11216 unsigned int mute;
0724ea2a 11217
42171c17
TI
11218 /* HP */
11219 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11220 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11221 HDA_AMP_MUTE, mute);
11222 /* mute internal speaker per jack sense */
11223 if (spec->jack_present)
11224 mute = HDA_AMP_MUTE;
11225 if (line_nid)
11226 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11227 HDA_AMP_MUTE, mute);
11228 if (speaker_nid && speaker_nid != line_nid)
11229 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11230 HDA_AMP_MUTE, mute);
42171c17
TI
11231}
11232
11233#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11234
11235static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11236 struct snd_ctl_elem_value *ucontrol)
11237{
11238 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11239 struct alc_spec *spec = codec->spec;
11240 int val = !!*ucontrol->value.integer.value;
11241
11242 if (val == spec->master_sw)
11243 return 0;
11244 spec->master_sw = val;
11245 alc262_hippo_master_update(codec);
11246 return 1;
11247}
11248
11249#define ALC262_HIPPO_MASTER_SWITCH \
11250 { \
11251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11252 .name = "Master Playback Switch", \
11253 .info = snd_ctl_boolean_mono_info, \
11254 .get = alc262_hippo_master_sw_get, \
11255 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11256 }, \
11257 { \
11258 .iface = NID_MAPPING, \
11259 .name = "Master Playback Switch", \
11260 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11261 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11262 }
42171c17
TI
11263
11264static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11265 ALC262_HIPPO_MASTER_SWITCH,
11266 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11267 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11268 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11273 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11274 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11275 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11276 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11277 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11278 { } /* end */
11279};
11280
11281static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11282 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11283 ALC262_HIPPO_MASTER_SWITCH,
11284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11286 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11287 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11288 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11289 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11290 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11291 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11292 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11293 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11294 { } /* end */
11295};
11296
11297/* mute/unmute internal speaker according to the hp jack and mute state */
11298static void alc262_hippo_automute(struct hda_codec *codec)
11299{
11300 struct alc_spec *spec = codec->spec;
11301 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11302
864f92be 11303 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11304 alc262_hippo_master_update(codec);
0724ea2a 11305}
5b31954e 11306
42171c17
TI
11307static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11308{
11309 if ((res >> 26) != ALC880_HP_EVENT)
11310 return;
11311 alc262_hippo_automute(codec);
11312}
11313
4f5d1706 11314static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11315{
11316 struct alc_spec *spec = codec->spec;
11317
11318 spec->autocfg.hp_pins[0] = 0x15;
11319 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11320}
11321
4f5d1706 11322static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11323{
11324 struct alc_spec *spec = codec->spec;
11325
11326 spec->autocfg.hp_pins[0] = 0x1b;
11327 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11328}
11329
11330
272a527c 11331static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11332 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11333 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11334 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11335 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11336 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11337 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11338 { } /* end */
11339};
11340
83c34218 11341static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11342 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11343 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11344 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11345 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11346 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11347 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11348 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11349 { } /* end */
11350};
272a527c 11351
ba340e82
TV
11352static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11353 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11354 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11355 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11356 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11357 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11358 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11360 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11361 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11362 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11363 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11364 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11365 { } /* end */
11366};
11367
11368static struct hda_verb alc262_tyan_verbs[] = {
11369 /* Headphone automute */
11370 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11371 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11372 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11373
11374 /* P11 AUX_IN, white 4-pin connector */
11375 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11376 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11377 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11378 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11379
11380 {}
11381};
11382
11383/* unsolicited event for HP jack sensing */
4f5d1706 11384static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11385{
a9fd4f3f 11386 struct alc_spec *spec = codec->spec;
ba340e82 11387
a9fd4f3f
TI
11388 spec->autocfg.hp_pins[0] = 0x1b;
11389 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11390}
11391
ba340e82 11392
9c7f852e
TI
11393#define alc262_capture_mixer alc882_capture_mixer
11394#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11395
11396/*
11397 * generic initialization of ADC, input mixers and output mixers
11398 */
11399static struct hda_verb alc262_init_verbs[] = {
11400 /*
11401 * Unmute ADC0-2 and set the default input to mic-in
11402 */
11403 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11404 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11405 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11406 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11407 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11408 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11409
cb53c626 11410 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11411 * mixer widget
f12ab1e0
TI
11412 * Note: PASD motherboards uses the Line In 2 as the input for
11413 * front panel mic (mic 2)
9c7f852e
TI
11414 */
11415 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11416 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11417 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11418 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11419 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11420 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11421
11422 /*
df694daa
KY
11423 * Set up output mixers (0x0c - 0x0e)
11424 */
11425 /* set vol=0 to output mixers */
11426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11427 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11428 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11429 /* set up input amps for analog loopback */
11430 /* Amp Indices: DAC = 0, mixer = 1 */
11431 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11433 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11434 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11435 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11436 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11437
11438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11439 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11440 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11441 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11442 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11443 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11444
11445 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11447 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11448 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11449 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11450
df694daa
KY
11451 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11452 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11453
df694daa
KY
11454 /* FIXME: use matrix-type input source selection */
11455 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11456 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11457 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11458 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11459 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11461 /* Input mixer2 */
11462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11466 /* Input mixer3 */
11467 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11471
11472 { }
11473};
1da177e4 11474
4e555fe5
KY
11475static struct hda_verb alc262_eapd_verbs[] = {
11476 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11477 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11478 { }
11479};
11480
ccc656ce
KY
11481static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11482 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11483 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11484 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11485
11486 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11488 {}
11489};
11490
272a527c
KY
11491static struct hda_verb alc262_sony_unsol_verbs[] = {
11492 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11493 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11494 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11495
11496 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11497 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11498 {}
272a527c
KY
11499};
11500
4e555fe5
KY
11501static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11502 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11503 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11504 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11505 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11506 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11507 { } /* end */
11508};
11509
11510static struct hda_verb alc262_toshiba_s06_verbs[] = {
11511 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11512 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11514 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11515 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11516 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11517 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11518 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11519 {}
11520};
11521
4f5d1706 11522static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11523{
a9fd4f3f
TI
11524 struct alc_spec *spec = codec->spec;
11525
11526 spec->autocfg.hp_pins[0] = 0x15;
11527 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11528 spec->ext_mic.pin = 0x18;
11529 spec->ext_mic.mux_idx = 0;
11530 spec->int_mic.pin = 0x12;
11531 spec->int_mic.mux_idx = 9;
11532 spec->auto_mic = 1;
4e555fe5
KY
11533}
11534
e8f9ae2a
PT
11535/*
11536 * nec model
11537 * 0x15 = headphone
11538 * 0x16 = internal speaker
11539 * 0x18 = external mic
11540 */
11541
11542static struct snd_kcontrol_new alc262_nec_mixer[] = {
11543 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11544 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11545
11546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11547 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11548 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11549
11550 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11551 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11552 { } /* end */
11553};
11554
11555static struct hda_verb alc262_nec_verbs[] = {
11556 /* Unmute Speaker */
11557 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11558
11559 /* Headphone */
11560 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11561 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11562
11563 /* External mic to headphone */
11564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11565 /* External mic to speaker */
11566 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11567 {}
11568};
11569
834be88d
TI
11570/*
11571 * fujitsu model
5d9fab2d
TV
11572 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11573 * 0x1b = port replicator headphone out
834be88d
TI
11574 */
11575
11576#define ALC_HP_EVENT 0x37
11577
11578static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11579 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11580 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11581 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11582 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11583 {}
11584};
11585
0e31daf7
J
11586static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11587 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11588 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11589 {}
11590};
11591
e2595322
DC
11592static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11593 /* Front Mic pin: input vref at 50% */
11594 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11595 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11596 {}
11597};
11598
834be88d 11599static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11600 .num_items = 3,
834be88d
TI
11601 .items = {
11602 { "Mic", 0x0 },
39d3ed38 11603 { "Int Mic", 0x1 },
834be88d
TI
11604 { "CD", 0x4 },
11605 },
11606};
11607
9c7f852e
TI
11608static struct hda_input_mux alc262_HP_capture_source = {
11609 .num_items = 5,
11610 .items = {
11611 { "Mic", 0x0 },
accbe498 11612 { "Front Mic", 0x1 },
9c7f852e
TI
11613 { "Line", 0x2 },
11614 { "CD", 0x4 },
11615 { "AUX IN", 0x6 },
11616 },
11617};
11618
accbe498 11619static struct hda_input_mux alc262_HP_D7000_capture_source = {
11620 .num_items = 4,
11621 .items = {
11622 { "Mic", 0x0 },
11623 { "Front Mic", 0x2 },
11624 { "Line", 0x1 },
11625 { "CD", 0x4 },
11626 },
11627};
11628
ebc7a406 11629/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11630static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11631{
11632 struct alc_spec *spec = codec->spec;
11633 unsigned int mute;
11634
f12ab1e0 11635 if (force || !spec->sense_updated) {
864f92be
WF
11636 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11637 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11638 spec->sense_updated = 1;
11639 }
ebc7a406
TI
11640 /* unmute internal speaker only if both HPs are unplugged and
11641 * master switch is on
11642 */
11643 if (spec->jack_present)
11644 mute = HDA_AMP_MUTE;
11645 else
834be88d 11646 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11647 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11648 HDA_AMP_MUTE, mute);
834be88d
TI
11649}
11650
11651/* unsolicited event for HP jack sensing */
11652static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11653 unsigned int res)
11654{
11655 if ((res >> 26) != ALC_HP_EVENT)
11656 return;
11657 alc262_fujitsu_automute(codec, 1);
11658}
11659
ebc7a406
TI
11660static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11661{
11662 alc262_fujitsu_automute(codec, 1);
11663}
11664
834be88d 11665/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11666static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11667 .ops = &snd_hda_bind_vol,
11668 .values = {
11669 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11670 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11671 0
11672 },
11673};
834be88d 11674
0e31daf7
J
11675/* mute/unmute internal speaker according to the hp jack and mute state */
11676static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11677{
11678 struct alc_spec *spec = codec->spec;
11679 unsigned int mute;
11680
11681 if (force || !spec->sense_updated) {
864f92be 11682 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11683 spec->sense_updated = 1;
11684 }
11685 if (spec->jack_present) {
11686 /* mute internal speaker */
11687 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11688 HDA_AMP_MUTE, HDA_AMP_MUTE);
11689 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11690 HDA_AMP_MUTE, HDA_AMP_MUTE);
11691 } else {
11692 /* unmute internal speaker if necessary */
11693 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11694 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11695 HDA_AMP_MUTE, mute);
11696 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11697 HDA_AMP_MUTE, mute);
11698 }
11699}
11700
11701/* unsolicited event for HP jack sensing */
11702static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11703 unsigned int res)
11704{
11705 if ((res >> 26) != ALC_HP_EVENT)
11706 return;
11707 alc262_lenovo_3000_automute(codec, 1);
11708}
11709
8de56b7d
TI
11710static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11711 int dir, int idx, long *valp)
11712{
11713 int i, change = 0;
11714
11715 for (i = 0; i < 2; i++, valp++)
11716 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11717 HDA_AMP_MUTE,
11718 *valp ? 0 : HDA_AMP_MUTE);
11719 return change;
11720}
11721
834be88d
TI
11722/* bind hp and internal speaker mute (with plug check) */
11723static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11724 struct snd_ctl_elem_value *ucontrol)
11725{
11726 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11727 long *valp = ucontrol->value.integer.value;
11728 int change;
11729
8de56b7d
TI
11730 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11731 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11732 if (change)
11733 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11734 return change;
11735}
11736
11737static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11738 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11739 {
11740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11741 .name = "Master Playback Switch",
5e26dfd0 11742 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11743 .info = snd_hda_mixer_amp_switch_info,
11744 .get = snd_hda_mixer_amp_switch_get,
11745 .put = alc262_fujitsu_master_sw_put,
11746 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11747 },
5b0cb1d8
JK
11748 {
11749 .iface = NID_MAPPING,
11750 .name = "Master Playback Switch",
11751 .private_value = 0x1b,
11752 },
834be88d
TI
11753 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11754 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11755 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11757 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11758 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11759 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11760 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11761 { } /* end */
11762};
11763
0e31daf7
J
11764/* bind hp and internal speaker mute (with plug check) */
11765static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11766 struct snd_ctl_elem_value *ucontrol)
11767{
11768 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11769 long *valp = ucontrol->value.integer.value;
11770 int change;
11771
8de56b7d 11772 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11773 if (change)
11774 alc262_lenovo_3000_automute(codec, 0);
11775 return change;
11776}
11777
11778static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11779 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11780 {
11781 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11782 .name = "Master Playback Switch",
5e26dfd0 11783 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11784 .info = snd_hda_mixer_amp_switch_info,
11785 .get = snd_hda_mixer_amp_switch_get,
11786 .put = alc262_lenovo_3000_master_sw_put,
11787 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11788 },
11789 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11790 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11791 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11793 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11794 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11795 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11796 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11797 { } /* end */
11798};
11799
9f99a638
HM
11800static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11801 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11802 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11805 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11806 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11807 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11808 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11809 { } /* end */
11810};
11811
304dcaac
TI
11812/* additional init verbs for Benq laptops */
11813static struct hda_verb alc262_EAPD_verbs[] = {
11814 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11815 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11816 {}
11817};
11818
83c34218
KY
11819static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11820 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11821 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11822
11823 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11824 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11825 {}
11826};
11827
f651b50b
TD
11828/* Samsung Q1 Ultra Vista model setup */
11829static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11830 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11831 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11834 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11835 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11836 { } /* end */
11837};
11838
11839static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11840 /* output mixer */
11841 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11844 /* speaker */
11845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11847 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11848 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11849 /* HP */
f651b50b 11850 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11852 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11854 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11855 /* internal mic */
11856 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11857 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11858 /* ADC, choose mic */
11859 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11860 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11861 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11862 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11863 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11864 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11865 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11866 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11867 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11868 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11869 {}
11870};
11871
f651b50b
TD
11872/* mute/unmute internal speaker according to the hp jack and mute state */
11873static void alc262_ultra_automute(struct hda_codec *codec)
11874{
11875 struct alc_spec *spec = codec->spec;
11876 unsigned int mute;
f651b50b 11877
bb9f76cd
TI
11878 mute = 0;
11879 /* auto-mute only when HP is used as HP */
11880 if (!spec->cur_mux[0]) {
864f92be 11881 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11882 if (spec->jack_present)
11883 mute = HDA_AMP_MUTE;
f651b50b 11884 }
bb9f76cd
TI
11885 /* mute/unmute internal speaker */
11886 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11887 HDA_AMP_MUTE, mute);
11888 /* mute/unmute HP */
11889 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11890 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11891}
11892
11893/* unsolicited event for HP jack sensing */
11894static void alc262_ultra_unsol_event(struct hda_codec *codec,
11895 unsigned int res)
11896{
11897 if ((res >> 26) != ALC880_HP_EVENT)
11898 return;
11899 alc262_ultra_automute(codec);
11900}
11901
bb9f76cd
TI
11902static struct hda_input_mux alc262_ultra_capture_source = {
11903 .num_items = 2,
11904 .items = {
11905 { "Mic", 0x1 },
11906 { "Headphone", 0x7 },
11907 },
11908};
11909
11910static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11911 struct snd_ctl_elem_value *ucontrol)
11912{
11913 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11914 struct alc_spec *spec = codec->spec;
11915 int ret;
11916
54cbc9ab 11917 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11918 if (!ret)
11919 return 0;
11920 /* reprogram the HP pin as mic or HP according to the input source */
11921 snd_hda_codec_write_cache(codec, 0x15, 0,
11922 AC_VERB_SET_PIN_WIDGET_CONTROL,
11923 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11924 alc262_ultra_automute(codec); /* mute/unmute HP */
11925 return ret;
11926}
11927
11928static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11929 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11930 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11931 {
11932 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11933 .name = "Capture Source",
54cbc9ab
TI
11934 .info = alc_mux_enum_info,
11935 .get = alc_mux_enum_get,
bb9f76cd
TI
11936 .put = alc262_ultra_mux_enum_put,
11937 },
5b0cb1d8
JK
11938 {
11939 .iface = NID_MAPPING,
11940 .name = "Capture Source",
11941 .private_value = 0x15,
11942 },
bb9f76cd
TI
11943 { } /* end */
11944};
11945
c3fc1f50
TI
11946/* We use two mixers depending on the output pin; 0x16 is a mono output
11947 * and thus it's bound with a different mixer.
11948 * This function returns which mixer amp should be used.
11949 */
11950static int alc262_check_volbit(hda_nid_t nid)
11951{
11952 if (!nid)
11953 return 0;
11954 else if (nid == 0x16)
11955 return 2;
11956 else
11957 return 1;
11958}
11959
11960static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 11961 const char *pfx, int *vbits, int idx)
c3fc1f50 11962{
c3fc1f50
TI
11963 unsigned long val;
11964 int vbit;
11965
11966 vbit = alc262_check_volbit(nid);
11967 if (!vbit)
11968 return 0;
11969 if (*vbits & vbit) /* a volume control for this mixer already there */
11970 return 0;
11971 *vbits |= vbit;
c3fc1f50
TI
11972 if (vbit == 2)
11973 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11974 else
11975 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 11976 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
11977}
11978
11979static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 11980 const char *pfx, int idx)
c3fc1f50 11981{
c3fc1f50
TI
11982 unsigned long val;
11983
11984 if (!nid)
11985 return 0;
c3fc1f50
TI
11986 if (nid == 0x16)
11987 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11988 else
11989 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 11990 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
11991}
11992
df694daa 11993/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11994static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11995 const struct auto_pin_cfg *cfg)
df694daa 11996{
c3fc1f50
TI
11997 const char *pfx;
11998 int vbits;
033688a5 11999 int i, err;
df694daa
KY
12000
12001 spec->multiout.num_dacs = 1; /* only use one dac */
12002 spec->multiout.dac_nids = spec->private_dac_nids;
12003 spec->multiout.dac_nids[0] = 2;
12004
c3fc1f50
TI
12005 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
12006 pfx = "Master";
12007 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12008 pfx = "Speaker";
033688a5
TI
12009 else if (cfg->line_out_type == AUTO_PIN_HP_OUT)
12010 pfx = "Headphone";
c3fc1f50
TI
12011 else
12012 pfx = "Front";
033688a5
TI
12013 for (i = 0; i < 2; i++) {
12014 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12015 if (err < 0)
12016 return err;
12017 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12018 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12019 "Speaker", i);
12020 if (err < 0)
12021 return err;
12022 }
12023 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12024 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12025 "Headphone", i);
12026 if (err < 0)
12027 return err;
12028 }
12029 }
df694daa 12030
c3fc1f50
TI
12031 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12032 alc262_check_volbit(cfg->speaker_pins[0]) |
12033 alc262_check_volbit(cfg->hp_pins[0]);
12034 if (vbits == 1 || vbits == 2)
12035 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12036 vbits = 0;
033688a5
TI
12037 for (i = 0; i < 2; i++) {
12038 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12039 &vbits, i);
12040 if (err < 0)
12041 return err;
12042 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12043 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12044 "Speaker", &vbits, i);
12045 if (err < 0)
12046 return err;
12047 }
12048 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12049 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12050 "Headphone", &vbits, i);
12051 if (err < 0)
12052 return err;
12053 }
12054 }
f12ab1e0 12055 return 0;
df694daa
KY
12056}
12057
05f5f477 12058#define alc262_auto_create_input_ctls \
eaa9b3a7 12059 alc882_auto_create_input_ctls
df694daa
KY
12060
12061/*
12062 * generic initialization of ADC, input mixers and output mixers
12063 */
12064static struct hda_verb alc262_volume_init_verbs[] = {
12065 /*
12066 * Unmute ADC0-2 and set the default input to mic-in
12067 */
12068 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12070 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12071 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12072 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12073 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12074
cb53c626 12075 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12076 * mixer widget
f12ab1e0
TI
12077 * Note: PASD motherboards uses the Line In 2 as the input for
12078 * front panel mic (mic 2)
df694daa
KY
12079 */
12080 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12081 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12082 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12083 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12084 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12085 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12086
12087 /*
12088 * Set up output mixers (0x0c - 0x0f)
12089 */
12090 /* set vol=0 to output mixers */
12091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12092 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12093 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12094
df694daa
KY
12095 /* set up input amps for analog loopback */
12096 /* Amp Indices: DAC = 0, mixer = 1 */
12097 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12098 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12099 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12102 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12103
12104 /* FIXME: use matrix-type input source selection */
12105 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12106 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12107 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12108 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12109 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12110 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12111 /* Input mixer2 */
12112 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12113 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12114 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12115 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12116 /* Input mixer3 */
12117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12120 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12121
12122 { }
12123};
12124
9c7f852e
TI
12125static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12126 /*
12127 * Unmute ADC0-2 and set the default input to mic-in
12128 */
12129 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12130 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12131 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12132 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12133 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12134 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12135
cb53c626 12136 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12137 * mixer widget
f12ab1e0
TI
12138 * Note: PASD motherboards uses the Line In 2 as the input for
12139 * front panel mic (mic 2)
9c7f852e
TI
12140 */
12141 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12142 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12143 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12144 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12145 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12146 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12147 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12148 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12149
9c7f852e
TI
12150 /*
12151 * Set up output mixers (0x0c - 0x0e)
12152 */
12153 /* set vol=0 to output mixers */
12154 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12155 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12156 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12157
12158 /* set up input amps for analog loopback */
12159 /* Amp Indices: DAC = 0, mixer = 1 */
12160 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12161 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12162 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12163 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12164 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12165 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12166
ce875f07 12167 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12168 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12169 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12170
12171 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12172 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12173
12174 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12175 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12176
12177 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12178 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12179 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12180 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12181 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12182
0e4835c1 12183 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12184 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12185 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12186 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12187 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12188 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12189
12190
12191 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12192 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12193 /* Input mixer1: only unmute Mic */
9c7f852e 12194 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12195 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12196 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12197 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12200 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12201 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12202 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12203 /* Input mixer2 */
12204 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12205 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12206 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12207 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12208 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12209 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12211 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12213 /* Input mixer3 */
12214 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12217 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12218 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12219 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12220 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12221 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12222 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12223
ce875f07
TI
12224 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12225
9c7f852e
TI
12226 { }
12227};
12228
cd7509a4
KY
12229static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12230 /*
12231 * Unmute ADC0-2 and set the default input to mic-in
12232 */
12233 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12234 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12235 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12236 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12237 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12238 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12239
cb53c626 12240 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12241 * mixer widget
12242 * Note: PASD motherboards uses the Line In 2 as the input for front
12243 * panel mic (mic 2)
12244 */
12245 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12254 /*
12255 * Set up output mixers (0x0c - 0x0e)
12256 */
12257 /* set vol=0 to output mixers */
12258 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12259 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12261
12262 /* set up input amps for analog loopback */
12263 /* Amp Indices: DAC = 0, mixer = 1 */
12264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12265 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12266 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12267 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12268 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12269 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12270
12271
12272 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12273 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12274 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12275 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12276 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12277 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12278 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12279
12280 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12281 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12282
12283 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12285
12286 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12287 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12288 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12289 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12290 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12291 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12292
12293 /* FIXME: use matrix-type input source selection */
12294 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12295 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12296 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12300 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12301 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12303 /* Input mixer2 */
12304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12309 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12310 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12311 /* Input mixer3 */
12312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12317 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12318 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12319
ce875f07
TI
12320 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12321
cd7509a4
KY
12322 { }
12323};
12324
9f99a638
HM
12325static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12326
12327 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12328 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12329 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12330
12331 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12332 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12333 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12334 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12335
12336 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12337 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12338 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12339 {}
12340};
12341
18675e42
TI
12342/*
12343 * Pin config fixes
12344 */
12345enum {
12346 PINFIX_FSC_H270,
12347};
12348
12349static const struct alc_fixup alc262_fixups[] = {
12350 [PINFIX_FSC_H270] = {
12351 .pins = (const struct alc_pincfg[]) {
12352 { 0x14, 0x99130110 }, /* speaker */
12353 { 0x15, 0x0221142f }, /* front HP */
12354 { 0x1b, 0x0121141f }, /* rear HP */
12355 { }
12356 }
12357 },
12358 [PINFIX_PB_M5210] = {
12359 .verbs = (const struct hda_verb[]) {
12360 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
12361 {}
12362 }
12363 },
12364};
12365
12366static struct snd_pci_quirk alc262_fixup_tbl[] = {
12367 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12368 {}
12369};
12370
9f99a638 12371
cb53c626
TI
12372#ifdef CONFIG_SND_HDA_POWER_SAVE
12373#define alc262_loopbacks alc880_loopbacks
12374#endif
12375
def319f9 12376/* pcm configuration: identical with ALC880 */
df694daa
KY
12377#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12378#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12379#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12380#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12381
12382/*
12383 * BIOS auto configuration
12384 */
12385static int alc262_parse_auto_config(struct hda_codec *codec)
12386{
12387 struct alc_spec *spec = codec->spec;
12388 int err;
12389 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12390
f12ab1e0
TI
12391 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12392 alc262_ignore);
12393 if (err < 0)
df694daa 12394 return err;
e64f14f4 12395 if (!spec->autocfg.line_outs) {
0852d7a6 12396 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12397 spec->multiout.max_channels = 2;
12398 spec->no_analog = 1;
12399 goto dig_only;
12400 }
df694daa 12401 return 0; /* can't find valid BIOS pin config */
e64f14f4 12402 }
f12ab1e0
TI
12403 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12404 if (err < 0)
12405 return err;
05f5f477 12406 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12407 if (err < 0)
df694daa
KY
12408 return err;
12409
12410 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12411
e64f14f4 12412 dig_only:
757899ac 12413 alc_auto_parse_digital(codec);
df694daa 12414
603c4019 12415 if (spec->kctls.list)
d88897ea 12416 add_mixer(spec, spec->kctls.list);
df694daa 12417
d88897ea 12418 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12419 spec->num_mux_defs = 1;
61b9b9b1 12420 spec->input_mux = &spec->private_imux[0];
df694daa 12421
776e184e
TI
12422 err = alc_auto_add_mic_boost(codec);
12423 if (err < 0)
12424 return err;
12425
6227cdce 12426 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12427
df694daa
KY
12428 return 1;
12429}
12430
12431#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12432#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12433#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12434#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12435
12436
12437/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12438static void alc262_auto_init(struct hda_codec *codec)
df694daa 12439{
f6c7e546 12440 struct alc_spec *spec = codec->spec;
df694daa
KY
12441 alc262_auto_init_multi_out(codec);
12442 alc262_auto_init_hp_out(codec);
12443 alc262_auto_init_analog_input(codec);
f511b01c 12444 alc262_auto_init_input_src(codec);
757899ac 12445 alc_auto_init_digital(codec);
f6c7e546 12446 if (spec->unsol_event)
7fb0d78f 12447 alc_inithook(codec);
df694daa
KY
12448}
12449
12450/*
12451 * configuration and preset
12452 */
f5fcc13c
TI
12453static const char *alc262_models[ALC262_MODEL_LAST] = {
12454 [ALC262_BASIC] = "basic",
12455 [ALC262_HIPPO] = "hippo",
12456 [ALC262_HIPPO_1] = "hippo_1",
12457 [ALC262_FUJITSU] = "fujitsu",
12458 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12459 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12460 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12461 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12462 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12463 [ALC262_BENQ_T31] = "benq-t31",
12464 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12465 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12466 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12467 [ALC262_ULTRA] = "ultra",
0e31daf7 12468 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12469 [ALC262_NEC] = "nec",
ba340e82 12470 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12471 [ALC262_AUTO] = "auto",
12472};
12473
12474static struct snd_pci_quirk alc262_cfg_tbl[] = {
12475 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12476 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12477 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12478 ALC262_HP_BPC),
12479 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12480 ALC262_HP_BPC),
53eff7e1
TI
12481 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12482 ALC262_HP_BPC),
cd7509a4 12483 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12484 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12485 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12486 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12487 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12488 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12489 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12490 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12491 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12492 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12493 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12494 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12495 ALC262_HP_TC_T5735),
8c427226 12496 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12497 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12498 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12499 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12500 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12501 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12502 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12503 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12504#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12505 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12506 ALC262_SONY_ASSAMD),
c5b5165c 12507#endif
36ca6e13 12508 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12509 ALC262_TOSHIBA_RX1),
80ffe869 12510 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12511 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12512 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12513 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12514 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12515 ALC262_ULTRA),
3e420e78 12516 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12517 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12518 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12519 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12520 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12521 {}
12522};
12523
12524static struct alc_config_preset alc262_presets[] = {
12525 [ALC262_BASIC] = {
12526 .mixers = { alc262_base_mixer },
12527 .init_verbs = { alc262_init_verbs },
12528 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12529 .dac_nids = alc262_dac_nids,
12530 .hp_nid = 0x03,
12531 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12532 .channel_mode = alc262_modes,
a3bcba38 12533 .input_mux = &alc262_capture_source,
df694daa 12534 },
ccc656ce 12535 [ALC262_HIPPO] = {
42171c17 12536 .mixers = { alc262_hippo_mixer },
6732bd0d 12537 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12538 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12539 .dac_nids = alc262_dac_nids,
12540 .hp_nid = 0x03,
12541 .dig_out_nid = ALC262_DIGOUT_NID,
12542 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12543 .channel_mode = alc262_modes,
12544 .input_mux = &alc262_capture_source,
12545 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12546 .setup = alc262_hippo_setup,
12547 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12548 },
12549 [ALC262_HIPPO_1] = {
12550 .mixers = { alc262_hippo1_mixer },
12551 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12552 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12553 .dac_nids = alc262_dac_nids,
12554 .hp_nid = 0x02,
12555 .dig_out_nid = ALC262_DIGOUT_NID,
12556 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12557 .channel_mode = alc262_modes,
12558 .input_mux = &alc262_capture_source,
42171c17 12559 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12560 .setup = alc262_hippo1_setup,
12561 .init_hook = alc262_hippo_automute,
ccc656ce 12562 },
834be88d
TI
12563 [ALC262_FUJITSU] = {
12564 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12565 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12566 alc262_fujitsu_unsol_verbs },
834be88d
TI
12567 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12568 .dac_nids = alc262_dac_nids,
12569 .hp_nid = 0x03,
12570 .dig_out_nid = ALC262_DIGOUT_NID,
12571 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12572 .channel_mode = alc262_modes,
12573 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12574 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12575 .init_hook = alc262_fujitsu_init_hook,
834be88d 12576 },
9c7f852e
TI
12577 [ALC262_HP_BPC] = {
12578 .mixers = { alc262_HP_BPC_mixer },
12579 .init_verbs = { alc262_HP_BPC_init_verbs },
12580 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12581 .dac_nids = alc262_dac_nids,
12582 .hp_nid = 0x03,
12583 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12584 .channel_mode = alc262_modes,
12585 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12586 .unsol_event = alc262_hp_bpc_unsol_event,
12587 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12588 },
cd7509a4
KY
12589 [ALC262_HP_BPC_D7000_WF] = {
12590 .mixers = { alc262_HP_BPC_WildWest_mixer },
12591 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12592 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12593 .dac_nids = alc262_dac_nids,
12594 .hp_nid = 0x03,
12595 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12596 .channel_mode = alc262_modes,
accbe498 12597 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12598 .unsol_event = alc262_hp_wildwest_unsol_event,
12599 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12600 },
cd7509a4
KY
12601 [ALC262_HP_BPC_D7000_WL] = {
12602 .mixers = { alc262_HP_BPC_WildWest_mixer,
12603 alc262_HP_BPC_WildWest_option_mixer },
12604 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12605 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12606 .dac_nids = alc262_dac_nids,
12607 .hp_nid = 0x03,
12608 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12609 .channel_mode = alc262_modes,
accbe498 12610 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12611 .unsol_event = alc262_hp_wildwest_unsol_event,
12612 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12613 },
66d2a9d6
KY
12614 [ALC262_HP_TC_T5735] = {
12615 .mixers = { alc262_hp_t5735_mixer },
12616 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12617 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12618 .dac_nids = alc262_dac_nids,
12619 .hp_nid = 0x03,
12620 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12621 .channel_mode = alc262_modes,
12622 .input_mux = &alc262_capture_source,
dc99be47 12623 .unsol_event = alc_sku_unsol_event,
4f5d1706 12624 .setup = alc262_hp_t5735_setup,
dc99be47 12625 .init_hook = alc_inithook,
8c427226
KY
12626 },
12627 [ALC262_HP_RP5700] = {
12628 .mixers = { alc262_hp_rp5700_mixer },
12629 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12630 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12631 .dac_nids = alc262_dac_nids,
12632 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12633 .channel_mode = alc262_modes,
12634 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12635 },
304dcaac
TI
12636 [ALC262_BENQ_ED8] = {
12637 .mixers = { alc262_base_mixer },
12638 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12639 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12640 .dac_nids = alc262_dac_nids,
12641 .hp_nid = 0x03,
12642 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12643 .channel_mode = alc262_modes,
12644 .input_mux = &alc262_capture_source,
f12ab1e0 12645 },
272a527c
KY
12646 [ALC262_SONY_ASSAMD] = {
12647 .mixers = { alc262_sony_mixer },
12648 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12649 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12650 .dac_nids = alc262_dac_nids,
12651 .hp_nid = 0x02,
12652 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12653 .channel_mode = alc262_modes,
12654 .input_mux = &alc262_capture_source,
12655 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12656 .setup = alc262_hippo_setup,
12657 .init_hook = alc262_hippo_automute,
83c34218
KY
12658 },
12659 [ALC262_BENQ_T31] = {
12660 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12661 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12662 alc_hp15_unsol_verbs },
83c34218
KY
12663 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12664 .dac_nids = alc262_dac_nids,
12665 .hp_nid = 0x03,
12666 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12667 .channel_mode = alc262_modes,
12668 .input_mux = &alc262_capture_source,
12669 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12670 .setup = alc262_hippo_setup,
12671 .init_hook = alc262_hippo_automute,
ea1fb29a 12672 },
f651b50b 12673 [ALC262_ULTRA] = {
f9e336f6
TI
12674 .mixers = { alc262_ultra_mixer },
12675 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12676 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12677 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12678 .dac_nids = alc262_dac_nids,
f651b50b
TD
12679 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12680 .channel_mode = alc262_modes,
12681 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12682 .adc_nids = alc262_adc_nids, /* ADC0 */
12683 .capsrc_nids = alc262_capsrc_nids,
12684 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12685 .unsol_event = alc262_ultra_unsol_event,
12686 .init_hook = alc262_ultra_automute,
12687 },
0e31daf7
J
12688 [ALC262_LENOVO_3000] = {
12689 .mixers = { alc262_lenovo_3000_mixer },
12690 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12691 alc262_lenovo_3000_unsol_verbs,
12692 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12693 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12694 .dac_nids = alc262_dac_nids,
12695 .hp_nid = 0x03,
12696 .dig_out_nid = ALC262_DIGOUT_NID,
12697 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12698 .channel_mode = alc262_modes,
12699 .input_mux = &alc262_fujitsu_capture_source,
12700 .unsol_event = alc262_lenovo_3000_unsol_event,
12701 },
e8f9ae2a
PT
12702 [ALC262_NEC] = {
12703 .mixers = { alc262_nec_mixer },
12704 .init_verbs = { alc262_nec_verbs },
12705 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12706 .dac_nids = alc262_dac_nids,
12707 .hp_nid = 0x03,
12708 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12709 .channel_mode = alc262_modes,
12710 .input_mux = &alc262_capture_source,
12711 },
4e555fe5
KY
12712 [ALC262_TOSHIBA_S06] = {
12713 .mixers = { alc262_toshiba_s06_mixer },
12714 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12715 alc262_eapd_verbs },
12716 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12717 .capsrc_nids = alc262_dmic_capsrc_nids,
12718 .dac_nids = alc262_dac_nids,
12719 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12720 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12721 .dig_out_nid = ALC262_DIGOUT_NID,
12722 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12723 .channel_mode = alc262_modes,
4f5d1706
TI
12724 .unsol_event = alc_sku_unsol_event,
12725 .setup = alc262_toshiba_s06_setup,
12726 .init_hook = alc_inithook,
4e555fe5 12727 },
9f99a638
HM
12728 [ALC262_TOSHIBA_RX1] = {
12729 .mixers = { alc262_toshiba_rx1_mixer },
12730 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12731 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12732 .dac_nids = alc262_dac_nids,
12733 .hp_nid = 0x03,
12734 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12735 .channel_mode = alc262_modes,
12736 .input_mux = &alc262_capture_source,
12737 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12738 .setup = alc262_hippo_setup,
12739 .init_hook = alc262_hippo_automute,
9f99a638 12740 },
ba340e82
TV
12741 [ALC262_TYAN] = {
12742 .mixers = { alc262_tyan_mixer },
12743 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12744 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12745 .dac_nids = alc262_dac_nids,
12746 .hp_nid = 0x02,
12747 .dig_out_nid = ALC262_DIGOUT_NID,
12748 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12749 .channel_mode = alc262_modes,
12750 .input_mux = &alc262_capture_source,
a9fd4f3f 12751 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12752 .setup = alc262_tyan_setup,
12753 .init_hook = alc_automute_amp,
ba340e82 12754 },
df694daa
KY
12755};
12756
12757static int patch_alc262(struct hda_codec *codec)
12758{
12759 struct alc_spec *spec;
12760 int board_config;
12761 int err;
12762
dc041e0b 12763 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12764 if (spec == NULL)
12765 return -ENOMEM;
12766
12767 codec->spec = spec;
12768#if 0
f12ab1e0
TI
12769 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12770 * under-run
12771 */
df694daa
KY
12772 {
12773 int tmp;
12774 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12775 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12776 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12777 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12778 }
12779#endif
da00c244 12780 alc_auto_parse_customize_define(codec);
df694daa 12781
2c3bf9ab
TI
12782 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12783
f5fcc13c
TI
12784 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12785 alc262_models,
12786 alc262_cfg_tbl);
cd7509a4 12787
f5fcc13c 12788 if (board_config < 0) {
9a11f1aa
TI
12789 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12790 codec->chip_name);
df694daa
KY
12791 board_config = ALC262_AUTO;
12792 }
12793
18675e42
TI
12794 if (board_config == ALC262_AUTO)
12795 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1);
12796
df694daa
KY
12797 if (board_config == ALC262_AUTO) {
12798 /* automatic parse from the BIOS config */
12799 err = alc262_parse_auto_config(codec);
12800 if (err < 0) {
12801 alc_free(codec);
12802 return err;
f12ab1e0 12803 } else if (!err) {
9c7f852e
TI
12804 printk(KERN_INFO
12805 "hda_codec: Cannot set up configuration "
12806 "from BIOS. Using base mode...\n");
df694daa
KY
12807 board_config = ALC262_BASIC;
12808 }
12809 }
12810
dc1eae25 12811 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12812 err = snd_hda_attach_beep_device(codec, 0x1);
12813 if (err < 0) {
12814 alc_free(codec);
12815 return err;
12816 }
680cd536
KK
12817 }
12818
df694daa 12819 if (board_config != ALC262_AUTO)
e9c364c0 12820 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12821
df694daa
KY
12822 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12823 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12824
df694daa
KY
12825 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12826 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12827
f12ab1e0 12828 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12829 int i;
12830 /* check whether the digital-mic has to be supported */
12831 for (i = 0; i < spec->input_mux->num_items; i++) {
12832 if (spec->input_mux->items[i].index >= 9)
12833 break;
12834 }
12835 if (i < spec->input_mux->num_items) {
12836 /* use only ADC0 */
12837 spec->adc_nids = alc262_dmic_adc_nids;
12838 spec->num_adc_nids = 1;
12839 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12840 } else {
8c927b4a
TI
12841 /* all analog inputs */
12842 /* check whether NID 0x07 is valid */
12843 unsigned int wcap = get_wcaps(codec, 0x07);
12844
12845 /* get type */
a22d543a 12846 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12847 if (wcap != AC_WID_AUD_IN) {
12848 spec->adc_nids = alc262_adc_nids_alt;
12849 spec->num_adc_nids =
12850 ARRAY_SIZE(alc262_adc_nids_alt);
12851 spec->capsrc_nids = alc262_capsrc_nids_alt;
12852 } else {
12853 spec->adc_nids = alc262_adc_nids;
12854 spec->num_adc_nids =
12855 ARRAY_SIZE(alc262_adc_nids);
12856 spec->capsrc_nids = alc262_capsrc_nids;
12857 }
df694daa
KY
12858 }
12859 }
e64f14f4 12860 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12861 set_capture_mixer(codec);
dc1eae25 12862 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12863 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12864
18675e42
TI
12865 if (board_config == ALC262_AUTO)
12866 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0);
12867
2134ea4f
TI
12868 spec->vmaster_nid = 0x0c;
12869
df694daa
KY
12870 codec->patch_ops = alc_patch_ops;
12871 if (board_config == ALC262_AUTO)
ae6b813a 12872 spec->init_hook = alc262_auto_init;
cb53c626
TI
12873#ifdef CONFIG_SND_HDA_POWER_SAVE
12874 if (!spec->loopback.amplist)
12875 spec->loopback.amplist = alc262_loopbacks;
12876#endif
ea1fb29a 12877
df694daa
KY
12878 return 0;
12879}
12880
a361d84b
KY
12881/*
12882 * ALC268 channel source setting (2 channel)
12883 */
12884#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12885#define alc268_modes alc260_modes
ea1fb29a 12886
a361d84b
KY
12887static hda_nid_t alc268_dac_nids[2] = {
12888 /* front, hp */
12889 0x02, 0x03
12890};
12891
12892static hda_nid_t alc268_adc_nids[2] = {
12893 /* ADC0-1 */
12894 0x08, 0x07
12895};
12896
12897static hda_nid_t alc268_adc_nids_alt[1] = {
12898 /* ADC0 */
12899 0x08
12900};
12901
e1406348
TI
12902static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12903
a361d84b
KY
12904static struct snd_kcontrol_new alc268_base_mixer[] = {
12905 /* output mixer control */
12906 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12907 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12908 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12909 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12910 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12911 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12912 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12913 { }
12914};
12915
42171c17
TI
12916static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12917 /* output mixer control */
12918 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12919 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12920 ALC262_HIPPO_MASTER_SWITCH,
12921 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12922 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12923 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12924 { }
12925};
12926
aef9d318
TI
12927/* bind Beep switches of both NID 0x0f and 0x10 */
12928static struct hda_bind_ctls alc268_bind_beep_sw = {
12929 .ops = &snd_hda_bind_sw,
12930 .values = {
12931 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12932 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12933 0
12934 },
12935};
12936
12937static struct snd_kcontrol_new alc268_beep_mixer[] = {
12938 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12939 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12940 { }
12941};
12942
d1a991a6
KY
12943static struct hda_verb alc268_eapd_verbs[] = {
12944 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12945 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12946 { }
12947};
12948
d273809e 12949/* Toshiba specific */
d273809e
TI
12950static struct hda_verb alc268_toshiba_verbs[] = {
12951 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12952 { } /* end */
12953};
12954
12955/* Acer specific */
889c4395 12956/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12957static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12958 .ops = &snd_hda_bind_vol,
12959 .values = {
12960 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12961 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12962 0
12963 },
12964};
12965
889c4395
TI
12966/* mute/unmute internal speaker according to the hp jack and mute state */
12967static void alc268_acer_automute(struct hda_codec *codec, int force)
12968{
12969 struct alc_spec *spec = codec->spec;
12970 unsigned int mute;
12971
12972 if (force || !spec->sense_updated) {
864f92be 12973 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12974 spec->sense_updated = 1;
12975 }
12976 if (spec->jack_present)
12977 mute = HDA_AMP_MUTE; /* mute internal speaker */
12978 else /* unmute internal speaker if necessary */
12979 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12980 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12981 HDA_AMP_MUTE, mute);
12982}
12983
12984
12985/* bind hp and internal speaker mute (with plug check) */
12986static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12987 struct snd_ctl_elem_value *ucontrol)
12988{
12989 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12990 long *valp = ucontrol->value.integer.value;
12991 int change;
12992
8de56b7d 12993 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12994 if (change)
12995 alc268_acer_automute(codec, 0);
12996 return change;
12997}
d273809e 12998
8ef355da
KY
12999static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13000 /* output mixer control */
13001 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13002 {
13003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13004 .name = "Master Playback Switch",
5e26dfd0 13005 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13006 .info = snd_hda_mixer_amp_switch_info,
13007 .get = snd_hda_mixer_amp_switch_get,
13008 .put = alc268_acer_master_sw_put,
13009 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13010 },
13011 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13012 { }
13013};
13014
d273809e
TI
13015static struct snd_kcontrol_new alc268_acer_mixer[] = {
13016 /* output mixer control */
13017 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13018 {
13019 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13020 .name = "Master Playback Switch",
5e26dfd0 13021 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13022 .info = snd_hda_mixer_amp_switch_info,
13023 .get = snd_hda_mixer_amp_switch_get,
13024 .put = alc268_acer_master_sw_put,
13025 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13026 },
33bf17ab
TI
13027 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13028 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13029 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
13030 { }
13031};
13032
c238b4f4
TI
13033static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13034 /* output mixer control */
13035 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13036 {
13037 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13038 .name = "Master Playback Switch",
5e26dfd0 13039 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13040 .info = snd_hda_mixer_amp_switch_info,
13041 .get = snd_hda_mixer_amp_switch_get,
13042 .put = alc268_acer_master_sw_put,
13043 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13044 },
13045 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13046 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
13047 { }
13048};
13049
8ef355da
KY
13050static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13051 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13052 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13053 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13054 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13055 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13056 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13057 { }
13058};
13059
d273809e 13060static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13061 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13062 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13065 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13066 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13067 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13068 { }
13069};
13070
13071/* unsolicited event for HP jack sensing */
42171c17 13072#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13073#define alc268_toshiba_setup alc262_hippo_setup
13074#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13075
13076static void alc268_acer_unsol_event(struct hda_codec *codec,
13077 unsigned int res)
13078{
889c4395 13079 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13080 return;
13081 alc268_acer_automute(codec, 1);
13082}
13083
889c4395
TI
13084static void alc268_acer_init_hook(struct hda_codec *codec)
13085{
13086 alc268_acer_automute(codec, 1);
13087}
13088
8ef355da
KY
13089/* toggle speaker-output according to the hp-jack state */
13090static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13091{
13092 unsigned int present;
13093 unsigned char bits;
13094
864f92be 13095 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13096 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13097 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13098 HDA_AMP_MUTE, bits);
8ef355da 13099 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13100 HDA_AMP_MUTE, bits);
8ef355da
KY
13101}
13102
8ef355da
KY
13103static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13104 unsigned int res)
13105{
4f5d1706
TI
13106 switch (res >> 26) {
13107 case ALC880_HP_EVENT:
8ef355da 13108 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13109 break;
13110 case ALC880_MIC_EVENT:
13111 alc_mic_automute(codec);
13112 break;
13113 }
13114}
13115
13116static void alc268_acer_lc_setup(struct hda_codec *codec)
13117{
13118 struct alc_spec *spec = codec->spec;
13119 spec->ext_mic.pin = 0x18;
13120 spec->ext_mic.mux_idx = 0;
13121 spec->int_mic.pin = 0x12;
13122 spec->int_mic.mux_idx = 6;
13123 spec->auto_mic = 1;
8ef355da
KY
13124}
13125
13126static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13127{
13128 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13129 alc_mic_automute(codec);
8ef355da
KY
13130}
13131
3866f0b0
TI
13132static struct snd_kcontrol_new alc268_dell_mixer[] = {
13133 /* output mixer control */
13134 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13135 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13136 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13137 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13138 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13139 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13140 { }
13141};
13142
13143static struct hda_verb alc268_dell_verbs[] = {
13144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13145 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13146 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13147 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13148 { }
13149};
13150
13151/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13152static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13153{
a9fd4f3f 13154 struct alc_spec *spec = codec->spec;
3866f0b0 13155
a9fd4f3f
TI
13156 spec->autocfg.hp_pins[0] = 0x15;
13157 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13158 spec->ext_mic.pin = 0x18;
13159 spec->ext_mic.mux_idx = 0;
13160 spec->int_mic.pin = 0x19;
13161 spec->int_mic.mux_idx = 1;
13162 spec->auto_mic = 1;
3866f0b0
TI
13163}
13164
eb5a6621
HRK
13165static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13166 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13167 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13168 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13169 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13170 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13171 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13172 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13173 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13174 { }
13175};
13176
13177static struct hda_verb alc267_quanta_il1_verbs[] = {
13178 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13179 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13180 { }
13181};
13182
4f5d1706 13183static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13184{
a9fd4f3f 13185 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13186 spec->autocfg.hp_pins[0] = 0x15;
13187 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13188 spec->ext_mic.pin = 0x18;
13189 spec->ext_mic.mux_idx = 0;
13190 spec->int_mic.pin = 0x19;
13191 spec->int_mic.mux_idx = 1;
13192 spec->auto_mic = 1;
eb5a6621
HRK
13193}
13194
a361d84b
KY
13195/*
13196 * generic initialization of ADC, input mixers and output mixers
13197 */
13198static struct hda_verb alc268_base_init_verbs[] = {
13199 /* Unmute DAC0-1 and set vol = 0 */
13200 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13201 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13202
13203 /*
13204 * Set up output mixers (0x0c - 0x0e)
13205 */
13206 /* set vol=0 to output mixers */
13207 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13208 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13209
13210 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13211 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13212
13213 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13214 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13215 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13216 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13217 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13218 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13219 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13220 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13221
13222 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13223 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13224 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13225 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13226 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13227
13228 /* set PCBEEP vol = 0, mute connections */
13229 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13230 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13231 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13232
a9b3aa8a 13233 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13234
a9b3aa8a
JZ
13235 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13236 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13237 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13238 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13239
a361d84b
KY
13240 { }
13241};
13242
13243/*
13244 * generic initialization of ADC, input mixers and output mixers
13245 */
13246static struct hda_verb alc268_volume_init_verbs[] = {
13247 /* set output DAC */
4cfb91c6
TI
13248 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13249 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13250
13251 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13252 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13253 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13254 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13255 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13256
a361d84b 13257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13258 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13259 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13260
13261 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13262 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13263
aef9d318
TI
13264 /* set PCBEEP vol = 0, mute connections */
13265 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13267 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13268
13269 { }
13270};
13271
fdbc6626
TI
13272static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13273 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13274 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13275 { } /* end */
13276};
13277
a361d84b
KY
13278static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13279 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13280 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13281 _DEFINE_CAPSRC(1),
a361d84b
KY
13282 { } /* end */
13283};
13284
13285static struct snd_kcontrol_new alc268_capture_mixer[] = {
13286 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13287 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13288 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13289 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13290 _DEFINE_CAPSRC(2),
a361d84b
KY
13291 { } /* end */
13292};
13293
13294static struct hda_input_mux alc268_capture_source = {
13295 .num_items = 4,
13296 .items = {
13297 { "Mic", 0x0 },
13298 { "Front Mic", 0x1 },
13299 { "Line", 0x2 },
13300 { "CD", 0x3 },
13301 },
13302};
13303
0ccb541c 13304static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13305 .num_items = 3,
13306 .items = {
13307 { "Mic", 0x0 },
13308 { "Internal Mic", 0x1 },
13309 { "Line", 0x2 },
13310 },
13311};
13312
13313static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13314 .num_items = 3,
13315 .items = {
13316 { "Mic", 0x0 },
13317 { "Internal Mic", 0x6 },
13318 { "Line", 0x2 },
13319 },
13320};
13321
86c53bd2
JW
13322#ifdef CONFIG_SND_DEBUG
13323static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13324 /* Volume widgets */
13325 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13326 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13327 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13328 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13329 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13330 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13331 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13332 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13333 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13334 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13335 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13336 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13337 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13338 /* The below appears problematic on some hardwares */
13339 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13340 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13341 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13342 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13343 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13344
13345 /* Modes for retasking pin widgets */
13346 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13347 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13348 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13349 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13350
13351 /* Controls for GPIO pins, assuming they are configured as outputs */
13352 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13353 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13354 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13355 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13356
13357 /* Switches to allow the digital SPDIF output pin to be enabled.
13358 * The ALC268 does not have an SPDIF input.
13359 */
13360 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13361
13362 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13363 * this output to turn on an external amplifier.
13364 */
13365 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13366 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13367
13368 { } /* end */
13369};
13370#endif
13371
a361d84b
KY
13372/* create input playback/capture controls for the given pin */
13373static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13374 const char *ctlname, int idx)
13375{
3f3b7c1a 13376 hda_nid_t dac;
a361d84b
KY
13377 int err;
13378
3f3b7c1a
TI
13379 switch (nid) {
13380 case 0x14:
13381 case 0x16:
13382 dac = 0x02;
13383 break;
13384 case 0x15:
b08b1637
TI
13385 case 0x1a: /* ALC259/269 only */
13386 case 0x1b: /* ALC259/269 only */
531d8791 13387 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13388 dac = 0x03;
13389 break;
13390 default:
c7a9434d
TI
13391 snd_printd(KERN_WARNING "hda_codec: "
13392 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13393 return 0;
13394 }
13395 if (spec->multiout.dac_nids[0] != dac &&
13396 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13397 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13398 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13399 HDA_OUTPUT));
13400 if (err < 0)
13401 return err;
3f3b7c1a
TI
13402 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13403 }
13404
3f3b7c1a 13405 if (nid != 0x16)
0afe5f89 13406 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13407 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13408 else /* mono */
0afe5f89 13409 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13410 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13411 if (err < 0)
13412 return err;
13413 return 0;
13414}
13415
13416/* add playback controls from the parsed DAC table */
13417static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13418 const struct auto_pin_cfg *cfg)
13419{
13420 hda_nid_t nid;
13421 int err;
13422
a361d84b 13423 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13424
13425 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13426 if (nid) {
13427 const char *name;
13428 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13429 name = "Speaker";
13430 else
13431 name = "Front";
13432 err = alc268_new_analog_output(spec, nid, name, 0);
13433 if (err < 0)
13434 return err;
13435 }
a361d84b
KY
13436
13437 nid = cfg->speaker_pins[0];
13438 if (nid == 0x1d) {
0afe5f89 13439 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13440 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13441 if (err < 0)
13442 return err;
7bfb9c03 13443 } else if (nid) {
3f3b7c1a
TI
13444 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13445 if (err < 0)
13446 return err;
a361d84b
KY
13447 }
13448 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13449 if (nid) {
13450 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13451 if (err < 0)
13452 return err;
13453 }
a361d84b
KY
13454
13455 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13456 if (nid == 0x16) {
0afe5f89 13457 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13458 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13459 if (err < 0)
13460 return err;
13461 }
ea1fb29a 13462 return 0;
a361d84b
KY
13463}
13464
13465/* create playback/capture controls for input pins */
05f5f477 13466static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13467 const struct auto_pin_cfg *cfg)
13468{
05f5f477 13469 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13470}
13471
e9af4f36
TI
13472static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13473 hda_nid_t nid, int pin_type)
13474{
13475 int idx;
13476
13477 alc_set_pin_output(codec, nid, pin_type);
13478 if (nid == 0x14 || nid == 0x16)
13479 idx = 0;
13480 else
13481 idx = 1;
13482 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13483}
13484
13485static void alc268_auto_init_multi_out(struct hda_codec *codec)
13486{
13487 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13488 int i;
13489
13490 for (i = 0; i < spec->autocfg.line_outs; i++) {
13491 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13492 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13493 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13494 }
13495}
13496
13497static void alc268_auto_init_hp_out(struct hda_codec *codec)
13498{
13499 struct alc_spec *spec = codec->spec;
13500 hda_nid_t pin;
e1ca7b4e 13501 int i;
e9af4f36 13502
e1ca7b4e
TI
13503 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13504 pin = spec->autocfg.hp_pins[i];
e9af4f36 13505 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13506 }
13507 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13508 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13509 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13510 }
13511 if (spec->autocfg.mono_out_pin)
13512 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13513 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13514}
13515
a361d84b
KY
13516static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13517{
13518 struct alc_spec *spec = codec->spec;
13519 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13520 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13521 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13522 unsigned int dac_vol1, dac_vol2;
13523
e9af4f36 13524 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13525 snd_hda_codec_write(codec, speaker_nid, 0,
13526 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13527 /* mute mixer inputs from 0x1d */
a361d84b
KY
13528 snd_hda_codec_write(codec, 0x0f, 0,
13529 AC_VERB_SET_AMP_GAIN_MUTE,
13530 AMP_IN_UNMUTE(1));
13531 snd_hda_codec_write(codec, 0x10, 0,
13532 AC_VERB_SET_AMP_GAIN_MUTE,
13533 AMP_IN_UNMUTE(1));
13534 } else {
e9af4f36 13535 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13536 snd_hda_codec_write(codec, 0x0f, 0,
13537 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13538 snd_hda_codec_write(codec, 0x10, 0,
13539 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13540 }
13541
13542 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13543 if (line_nid == 0x14)
a361d84b
KY
13544 dac_vol2 = AMP_OUT_ZERO;
13545 else if (line_nid == 0x15)
13546 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13547 if (hp_nid == 0x14)
a361d84b
KY
13548 dac_vol2 = AMP_OUT_ZERO;
13549 else if (hp_nid == 0x15)
13550 dac_vol1 = AMP_OUT_ZERO;
13551 if (line_nid != 0x16 || hp_nid != 0x16 ||
13552 spec->autocfg.line_out_pins[1] != 0x16 ||
13553 spec->autocfg.line_out_pins[2] != 0x16)
13554 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13555
13556 snd_hda_codec_write(codec, 0x02, 0,
13557 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13558 snd_hda_codec_write(codec, 0x03, 0,
13559 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13560}
13561
def319f9 13562/* pcm configuration: identical with ALC880 */
a361d84b
KY
13563#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13564#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13565#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13566#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13567
13568/*
13569 * BIOS auto configuration
13570 */
13571static int alc268_parse_auto_config(struct hda_codec *codec)
13572{
13573 struct alc_spec *spec = codec->spec;
13574 int err;
13575 static hda_nid_t alc268_ignore[] = { 0 };
13576
13577 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13578 alc268_ignore);
13579 if (err < 0)
13580 return err;
7e0e44d4
TI
13581 if (!spec->autocfg.line_outs) {
13582 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13583 spec->multiout.max_channels = 2;
13584 spec->no_analog = 1;
13585 goto dig_only;
13586 }
a361d84b 13587 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13588 }
a361d84b
KY
13589 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13590 if (err < 0)
13591 return err;
05f5f477 13592 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13593 if (err < 0)
13594 return err;
13595
13596 spec->multiout.max_channels = 2;
13597
7e0e44d4 13598 dig_only:
a361d84b 13599 /* digital only support output */
757899ac 13600 alc_auto_parse_digital(codec);
603c4019 13601 if (spec->kctls.list)
d88897ea 13602 add_mixer(spec, spec->kctls.list);
a361d84b 13603
892981ff 13604 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13605 add_mixer(spec, alc268_beep_mixer);
aef9d318 13606
d88897ea 13607 add_verb(spec, alc268_volume_init_verbs);
5908589f 13608 spec->num_mux_defs = 2;
61b9b9b1 13609 spec->input_mux = &spec->private_imux[0];
a361d84b 13610
776e184e
TI
13611 err = alc_auto_add_mic_boost(codec);
13612 if (err < 0)
13613 return err;
13614
6227cdce 13615 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13616
a361d84b
KY
13617 return 1;
13618}
13619
a361d84b
KY
13620#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13621
13622/* init callback for auto-configuration model -- overriding the default init */
13623static void alc268_auto_init(struct hda_codec *codec)
13624{
f6c7e546 13625 struct alc_spec *spec = codec->spec;
a361d84b
KY
13626 alc268_auto_init_multi_out(codec);
13627 alc268_auto_init_hp_out(codec);
13628 alc268_auto_init_mono_speaker_out(codec);
13629 alc268_auto_init_analog_input(codec);
757899ac 13630 alc_auto_init_digital(codec);
f6c7e546 13631 if (spec->unsol_event)
7fb0d78f 13632 alc_inithook(codec);
a361d84b
KY
13633}
13634
13635/*
13636 * configuration and preset
13637 */
13638static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13639 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13640 [ALC268_3ST] = "3stack",
983f8ae4 13641 [ALC268_TOSHIBA] = "toshiba",
d273809e 13642 [ALC268_ACER] = "acer",
c238b4f4 13643 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13644 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13645 [ALC268_DELL] = "dell",
f12462c5 13646 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13647#ifdef CONFIG_SND_DEBUG
13648 [ALC268_TEST] = "test",
13649#endif
a361d84b
KY
13650 [ALC268_AUTO] = "auto",
13651};
13652
13653static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13654 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13655 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13656 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13657 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13658 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13659 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13660 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13661 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13662 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13663 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13664 /* almost compatible with toshiba but with optional digital outs;
13665 * auto-probing seems working fine
13666 */
8871e5b9 13667 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13668 ALC268_AUTO),
a361d84b 13669 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13670 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13671 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13672 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13673 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13674 {}
13675};
13676
3abf2f36
TI
13677/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13678static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13679 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13680 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13681 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13682 ALC268_TOSHIBA),
13683 {}
13684};
13685
a361d84b 13686static struct alc_config_preset alc268_presets[] = {
eb5a6621 13687 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13688 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13689 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13690 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13691 alc267_quanta_il1_verbs },
13692 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13693 .dac_nids = alc268_dac_nids,
13694 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13695 .adc_nids = alc268_adc_nids_alt,
13696 .hp_nid = 0x03,
13697 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13698 .channel_mode = alc268_modes,
4f5d1706
TI
13699 .unsol_event = alc_sku_unsol_event,
13700 .setup = alc267_quanta_il1_setup,
13701 .init_hook = alc_inithook,
eb5a6621 13702 },
a361d84b 13703 [ALC268_3ST] = {
aef9d318
TI
13704 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13705 alc268_beep_mixer },
a361d84b
KY
13706 .init_verbs = { alc268_base_init_verbs },
13707 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13708 .dac_nids = alc268_dac_nids,
13709 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13710 .adc_nids = alc268_adc_nids_alt,
e1406348 13711 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13712 .hp_nid = 0x03,
13713 .dig_out_nid = ALC268_DIGOUT_NID,
13714 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13715 .channel_mode = alc268_modes,
13716 .input_mux = &alc268_capture_source,
13717 },
d1a991a6 13718 [ALC268_TOSHIBA] = {
42171c17 13719 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13720 alc268_beep_mixer },
d273809e
TI
13721 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13722 alc268_toshiba_verbs },
d1a991a6
KY
13723 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13724 .dac_nids = alc268_dac_nids,
13725 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13726 .adc_nids = alc268_adc_nids_alt,
e1406348 13727 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13728 .hp_nid = 0x03,
13729 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13730 .channel_mode = alc268_modes,
13731 .input_mux = &alc268_capture_source,
d273809e 13732 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13733 .setup = alc268_toshiba_setup,
13734 .init_hook = alc268_toshiba_automute,
d273809e
TI
13735 },
13736 [ALC268_ACER] = {
432fd133 13737 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13738 alc268_beep_mixer },
d273809e
TI
13739 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13740 alc268_acer_verbs },
13741 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13742 .dac_nids = alc268_dac_nids,
13743 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13744 .adc_nids = alc268_adc_nids_alt,
e1406348 13745 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13746 .hp_nid = 0x02,
13747 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13748 .channel_mode = alc268_modes,
0ccb541c 13749 .input_mux = &alc268_acer_capture_source,
d273809e 13750 .unsol_event = alc268_acer_unsol_event,
889c4395 13751 .init_hook = alc268_acer_init_hook,
d1a991a6 13752 },
c238b4f4
TI
13753 [ALC268_ACER_DMIC] = {
13754 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13755 alc268_beep_mixer },
13756 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13757 alc268_acer_verbs },
13758 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13759 .dac_nids = alc268_dac_nids,
13760 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13761 .adc_nids = alc268_adc_nids_alt,
13762 .capsrc_nids = alc268_capsrc_nids,
13763 .hp_nid = 0x02,
13764 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13765 .channel_mode = alc268_modes,
13766 .input_mux = &alc268_acer_dmic_capture_source,
13767 .unsol_event = alc268_acer_unsol_event,
13768 .init_hook = alc268_acer_init_hook,
13769 },
8ef355da
KY
13770 [ALC268_ACER_ASPIRE_ONE] = {
13771 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13772 alc268_beep_mixer,
fdbc6626 13773 alc268_capture_nosrc_mixer },
8ef355da
KY
13774 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13775 alc268_acer_aspire_one_verbs },
13776 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13777 .dac_nids = alc268_dac_nids,
13778 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13779 .adc_nids = alc268_adc_nids_alt,
13780 .capsrc_nids = alc268_capsrc_nids,
13781 .hp_nid = 0x03,
13782 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13783 .channel_mode = alc268_modes,
8ef355da 13784 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13785 .setup = alc268_acer_lc_setup,
8ef355da
KY
13786 .init_hook = alc268_acer_lc_init_hook,
13787 },
3866f0b0 13788 [ALC268_DELL] = {
fdbc6626
TI
13789 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13790 alc268_capture_nosrc_mixer },
3866f0b0
TI
13791 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13792 alc268_dell_verbs },
13793 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13794 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13795 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13796 .adc_nids = alc268_adc_nids_alt,
13797 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13798 .hp_nid = 0x02,
13799 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13800 .channel_mode = alc268_modes,
a9fd4f3f 13801 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13802 .setup = alc268_dell_setup,
13803 .init_hook = alc_inithook,
3866f0b0 13804 },
f12462c5 13805 [ALC268_ZEPTO] = {
aef9d318
TI
13806 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13807 alc268_beep_mixer },
f12462c5
MT
13808 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13809 alc268_toshiba_verbs },
13810 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13811 .dac_nids = alc268_dac_nids,
13812 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13813 .adc_nids = alc268_adc_nids_alt,
e1406348 13814 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13815 .hp_nid = 0x03,
13816 .dig_out_nid = ALC268_DIGOUT_NID,
13817 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13818 .channel_mode = alc268_modes,
13819 .input_mux = &alc268_capture_source,
4f5d1706
TI
13820 .setup = alc268_toshiba_setup,
13821 .init_hook = alc268_toshiba_automute,
f12462c5 13822 },
86c53bd2
JW
13823#ifdef CONFIG_SND_DEBUG
13824 [ALC268_TEST] = {
13825 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13826 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13827 alc268_volume_init_verbs },
13828 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13829 .dac_nids = alc268_dac_nids,
13830 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13831 .adc_nids = alc268_adc_nids_alt,
e1406348 13832 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13833 .hp_nid = 0x03,
13834 .dig_out_nid = ALC268_DIGOUT_NID,
13835 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13836 .channel_mode = alc268_modes,
13837 .input_mux = &alc268_capture_source,
13838 },
13839#endif
a361d84b
KY
13840};
13841
13842static int patch_alc268(struct hda_codec *codec)
13843{
13844 struct alc_spec *spec;
13845 int board_config;
22971e3a 13846 int i, has_beep, err;
a361d84b 13847
ef86f581 13848 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13849 if (spec == NULL)
13850 return -ENOMEM;
13851
13852 codec->spec = spec;
13853
13854 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13855 alc268_models,
13856 alc268_cfg_tbl);
13857
3abf2f36
TI
13858 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13859 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13860 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13861
a361d84b 13862 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13863 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13864 codec->chip_name);
a361d84b
KY
13865 board_config = ALC268_AUTO;
13866 }
13867
13868 if (board_config == ALC268_AUTO) {
13869 /* automatic parse from the BIOS config */
13870 err = alc268_parse_auto_config(codec);
13871 if (err < 0) {
13872 alc_free(codec);
13873 return err;
13874 } else if (!err) {
13875 printk(KERN_INFO
13876 "hda_codec: Cannot set up configuration "
13877 "from BIOS. Using base mode...\n");
13878 board_config = ALC268_3ST;
13879 }
13880 }
13881
13882 if (board_config != ALC268_AUTO)
e9c364c0 13883 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13884
a361d84b
KY
13885 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13886 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13887 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13888
a361d84b
KY
13889 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13890
22971e3a
TI
13891 has_beep = 0;
13892 for (i = 0; i < spec->num_mixers; i++) {
13893 if (spec->mixers[i] == alc268_beep_mixer) {
13894 has_beep = 1;
13895 break;
13896 }
13897 }
13898
13899 if (has_beep) {
13900 err = snd_hda_attach_beep_device(codec, 0x1);
13901 if (err < 0) {
13902 alc_free(codec);
13903 return err;
13904 }
13905 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13906 /* override the amp caps for beep generator */
13907 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13908 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13909 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13910 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13911 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13912 }
aef9d318 13913
7e0e44d4 13914 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13915 /* check whether NID 0x07 is valid */
13916 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13917 int i;
3866f0b0 13918
defb5ab2 13919 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13920 /* get type */
a22d543a 13921 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13922 if (spec->auto_mic ||
13923 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13924 spec->adc_nids = alc268_adc_nids_alt;
13925 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13926 if (spec->auto_mic)
13927 fixup_automic_adc(codec);
fdbc6626
TI
13928 if (spec->auto_mic || spec->input_mux->num_items == 1)
13929 add_mixer(spec, alc268_capture_nosrc_mixer);
13930 else
13931 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13932 } else {
13933 spec->adc_nids = alc268_adc_nids;
13934 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13935 add_mixer(spec, alc268_capture_mixer);
a361d84b 13936 }
85860c06
TI
13937 /* set default input source */
13938 for (i = 0; i < spec->num_adc_nids; i++)
13939 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13940 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13941 i < spec->num_mux_defs ?
13942 spec->input_mux[i].items[0].index :
85860c06 13943 spec->input_mux->items[0].index);
a361d84b 13944 }
2134ea4f
TI
13945
13946 spec->vmaster_nid = 0x02;
13947
a361d84b
KY
13948 codec->patch_ops = alc_patch_ops;
13949 if (board_config == ALC268_AUTO)
13950 spec->init_hook = alc268_auto_init;
ea1fb29a 13951
a361d84b
KY
13952 return 0;
13953}
13954
f6a92248
KY
13955/*
13956 * ALC269 channel source setting (2 channel)
13957 */
13958#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13959
13960#define alc269_dac_nids alc260_dac_nids
13961
13962static hda_nid_t alc269_adc_nids[1] = {
13963 /* ADC1 */
f53281e6
KY
13964 0x08,
13965};
13966
e01bf509
TI
13967static hda_nid_t alc269_capsrc_nids[1] = {
13968 0x23,
13969};
13970
84898e87
KY
13971static hda_nid_t alc269vb_adc_nids[1] = {
13972 /* ADC1 */
13973 0x09,
13974};
13975
13976static hda_nid_t alc269vb_capsrc_nids[1] = {
13977 0x22,
13978};
13979
6694635d
TI
13980static hda_nid_t alc269_adc_candidates[] = {
13981 0x08, 0x09, 0x07,
13982};
e01bf509 13983
f6a92248
KY
13984#define alc269_modes alc260_modes
13985#define alc269_capture_source alc880_lg_lw_capture_source
13986
13987static struct snd_kcontrol_new alc269_base_mixer[] = {
13988 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13989 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13990 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13991 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13993 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13994 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13995 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13996 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13997 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13998 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13999 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14000 { } /* end */
14001};
14002
60db6b53
KY
14003static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14004 /* output mixer control */
14005 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14006 {
14007 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14008 .name = "Master Playback Switch",
5e26dfd0 14009 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14010 .info = snd_hda_mixer_amp_switch_info,
14011 .get = snd_hda_mixer_amp_switch_get,
14012 .put = alc268_acer_master_sw_put,
14013 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14014 },
14015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14016 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14017 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14018 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14019 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14020 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
14021 { }
14022};
14023
64154835
TV
14024static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14025 /* output mixer control */
14026 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14027 {
14028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14029 .name = "Master Playback Switch",
5e26dfd0 14030 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14031 .info = snd_hda_mixer_amp_switch_info,
14032 .get = snd_hda_mixer_amp_switch_get,
14033 .put = alc268_acer_master_sw_put,
14034 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14035 },
14036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14037 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14038 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14039 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14040 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14041 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
14042 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14043 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14044 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
14045 { }
14046};
14047
84898e87 14048static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14049 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14050 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14051 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14052 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14053 { } /* end */
14054};
14055
84898e87
KY
14056static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14057 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14058 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14060 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14061 { } /* end */
14062};
14063
fe3eb0a7
KY
14064static struct snd_kcontrol_new alc269_asus_mixer[] = {
14065 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14066 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14067 { } /* end */
14068};
14069
f53281e6 14070/* capture mixer elements */
84898e87
KY
14071static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14072 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14073 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14074 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14075 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
14076 { } /* end */
14077};
14078
14079static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14080 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14081 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
14082 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14083 { } /* end */
14084};
14085
84898e87
KY
14086static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14087 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14088 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14089 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14090 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
14091 { } /* end */
14092};
14093
14094static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14095 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14096 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14097 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14098 { } /* end */
14099};
14100
26f5df26 14101/* FSC amilo */
84898e87 14102#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14103
60db6b53
KY
14104static struct hda_verb alc269_quanta_fl1_verbs[] = {
14105 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14106 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14107 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14108 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14109 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14110 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14111 { }
14112};
f6a92248 14113
64154835
TV
14114static struct hda_verb alc269_lifebook_verbs[] = {
14115 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14116 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14117 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14118 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14119 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14120 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14121 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14122 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14123 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14124 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14125 { }
14126};
14127
60db6b53
KY
14128/* toggle speaker-output according to the hp-jack state */
14129static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14130{
14131 unsigned int present;
14132 unsigned char bits;
f6a92248 14133
864f92be 14134 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14135 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14136 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14137 HDA_AMP_MUTE, bits);
60db6b53 14138 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14139 HDA_AMP_MUTE, bits);
f6a92248 14140
60db6b53
KY
14141 snd_hda_codec_write(codec, 0x20, 0,
14142 AC_VERB_SET_COEF_INDEX, 0x0c);
14143 snd_hda_codec_write(codec, 0x20, 0,
14144 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14145
60db6b53
KY
14146 snd_hda_codec_write(codec, 0x20, 0,
14147 AC_VERB_SET_COEF_INDEX, 0x0c);
14148 snd_hda_codec_write(codec, 0x20, 0,
14149 AC_VERB_SET_PROC_COEF, 0x480);
14150}
f6a92248 14151
64154835
TV
14152/* toggle speaker-output according to the hp-jacks state */
14153static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14154{
14155 unsigned int present;
14156 unsigned char bits;
14157
14158 /* Check laptop headphone socket */
864f92be 14159 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14160
14161 /* Check port replicator headphone socket */
864f92be 14162 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14163
5dbd5ec6 14164 bits = present ? HDA_AMP_MUTE : 0;
64154835 14165 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14166 HDA_AMP_MUTE, bits);
64154835 14167 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14168 HDA_AMP_MUTE, bits);
64154835
TV
14169
14170 snd_hda_codec_write(codec, 0x20, 0,
14171 AC_VERB_SET_COEF_INDEX, 0x0c);
14172 snd_hda_codec_write(codec, 0x20, 0,
14173 AC_VERB_SET_PROC_COEF, 0x680);
14174
14175 snd_hda_codec_write(codec, 0x20, 0,
14176 AC_VERB_SET_COEF_INDEX, 0x0c);
14177 snd_hda_codec_write(codec, 0x20, 0,
14178 AC_VERB_SET_PROC_COEF, 0x480);
14179}
14180
64154835
TV
14181static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14182{
14183 unsigned int present_laptop;
14184 unsigned int present_dock;
14185
864f92be
WF
14186 present_laptop = snd_hda_jack_detect(codec, 0x18);
14187 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14188
14189 /* Laptop mic port overrides dock mic port, design decision */
14190 if (present_dock)
14191 snd_hda_codec_write(codec, 0x23, 0,
14192 AC_VERB_SET_CONNECT_SEL, 0x3);
14193 if (present_laptop)
14194 snd_hda_codec_write(codec, 0x23, 0,
14195 AC_VERB_SET_CONNECT_SEL, 0x0);
14196 if (!present_dock && !present_laptop)
14197 snd_hda_codec_write(codec, 0x23, 0,
14198 AC_VERB_SET_CONNECT_SEL, 0x1);
14199}
14200
60db6b53
KY
14201static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14202 unsigned int res)
14203{
4f5d1706
TI
14204 switch (res >> 26) {
14205 case ALC880_HP_EVENT:
60db6b53 14206 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14207 break;
14208 case ALC880_MIC_EVENT:
14209 alc_mic_automute(codec);
14210 break;
14211 }
60db6b53 14212}
f6a92248 14213
64154835
TV
14214static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14215 unsigned int res)
14216{
14217 if ((res >> 26) == ALC880_HP_EVENT)
14218 alc269_lifebook_speaker_automute(codec);
14219 if ((res >> 26) == ALC880_MIC_EVENT)
14220 alc269_lifebook_mic_autoswitch(codec);
14221}
14222
4f5d1706
TI
14223static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14224{
14225 struct alc_spec *spec = codec->spec;
20645d70
TI
14226 spec->autocfg.hp_pins[0] = 0x15;
14227 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14228 spec->ext_mic.pin = 0x18;
14229 spec->ext_mic.mux_idx = 0;
14230 spec->int_mic.pin = 0x19;
14231 spec->int_mic.mux_idx = 1;
14232 spec->auto_mic = 1;
14233}
14234
60db6b53
KY
14235static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14236{
14237 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14238 alc_mic_automute(codec);
60db6b53 14239}
f6a92248 14240
64154835
TV
14241static void alc269_lifebook_init_hook(struct hda_codec *codec)
14242{
14243 alc269_lifebook_speaker_automute(codec);
14244 alc269_lifebook_mic_autoswitch(codec);
14245}
14246
84898e87 14247static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14248 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14249 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14250 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14251 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14252 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14253 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14254 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14255 {}
14256};
14257
84898e87 14258static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14259 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14260 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14261 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14262 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14263 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14264 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14265 {}
14266};
14267
84898e87
KY
14268static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14269 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14270 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14271 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14272 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14273 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14274 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14275 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14276 {}
14277};
14278
14279static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14280 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14281 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14282 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14283 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14284 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14285 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14286 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14287 {}
14288};
14289
fe3eb0a7
KY
14290static struct hda_verb alc271_acer_dmic_verbs[] = {
14291 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14292 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14293 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14295 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14296 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14297 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14298 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14299 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14300 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14301 { }
14302};
14303
f53281e6
KY
14304/* toggle speaker-output according to the hp-jack state */
14305static void alc269_speaker_automute(struct hda_codec *codec)
14306{
ebb83eeb
KY
14307 struct alc_spec *spec = codec->spec;
14308 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14309 unsigned int present;
60db6b53 14310 unsigned char bits;
f53281e6 14311
ebb83eeb 14312 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14313 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14314 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14315 HDA_AMP_MUTE, bits);
f53281e6 14316 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14317 HDA_AMP_MUTE, bits);
f53281e6
KY
14318}
14319
f53281e6 14320/* unsolicited event for HP jack sensing */
84898e87 14321static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14322 unsigned int res)
f53281e6 14323{
4f5d1706
TI
14324 switch (res >> 26) {
14325 case ALC880_HP_EVENT:
f53281e6 14326 alc269_speaker_automute(codec);
4f5d1706
TI
14327 break;
14328 case ALC880_MIC_EVENT:
14329 alc_mic_automute(codec);
14330 break;
14331 }
f53281e6
KY
14332}
14333
226b1ec8 14334static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14335{
4f5d1706 14336 struct alc_spec *spec = codec->spec;
20645d70
TI
14337 spec->autocfg.hp_pins[0] = 0x15;
14338 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14339 spec->ext_mic.pin = 0x18;
14340 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14341 spec->int_mic.pin = 0x19;
14342 spec->int_mic.mux_idx = 1;
4f5d1706 14343 spec->auto_mic = 1;
f53281e6
KY
14344}
14345
226b1ec8 14346static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14347{
14348 struct alc_spec *spec = codec->spec;
20645d70
TI
14349 spec->autocfg.hp_pins[0] = 0x15;
14350 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14351 spec->ext_mic.pin = 0x18;
14352 spec->ext_mic.mux_idx = 0;
14353 spec->int_mic.pin = 0x12;
226b1ec8 14354 spec->int_mic.mux_idx = 5;
84898e87
KY
14355 spec->auto_mic = 1;
14356}
14357
226b1ec8 14358static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14359{
4f5d1706 14360 struct alc_spec *spec = codec->spec;
226b1ec8 14361 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14362 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14363 spec->ext_mic.pin = 0x18;
14364 spec->ext_mic.mux_idx = 0;
14365 spec->int_mic.pin = 0x19;
14366 spec->int_mic.mux_idx = 1;
14367 spec->auto_mic = 1;
f53281e6
KY
14368}
14369
226b1ec8
KY
14370static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14371{
14372 struct alc_spec *spec = codec->spec;
14373 spec->autocfg.hp_pins[0] = 0x21;
14374 spec->autocfg.speaker_pins[0] = 0x14;
14375 spec->ext_mic.pin = 0x18;
14376 spec->ext_mic.mux_idx = 0;
14377 spec->int_mic.pin = 0x12;
14378 spec->int_mic.mux_idx = 6;
14379 spec->auto_mic = 1;
14380}
14381
84898e87 14382static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14383{
14384 alc269_speaker_automute(codec);
4f5d1706 14385 alc_mic_automute(codec);
f53281e6
KY
14386}
14387
60db6b53
KY
14388/*
14389 * generic initialization of ADC, input mixers and output mixers
14390 */
14391static struct hda_verb alc269_init_verbs[] = {
14392 /*
14393 * Unmute ADC0 and set the default input to mic-in
14394 */
84898e87 14395 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14396
14397 /*
84898e87 14398 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14399 */
14400 /* set vol=0 to output mixers */
14401 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14402 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14403
14404 /* set up input amps for analog loopback */
14405 /* Amp Indices: DAC = 0, mixer = 1 */
14406 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14407 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14408 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14409 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14410 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14411 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14412
14413 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14414 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14415 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14416 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14417 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14418 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14419 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14420
14421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14423
84898e87
KY
14424 /* FIXME: use Mux-type input source selection */
14425 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14426 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14427 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14428
84898e87
KY
14429 /* set EAPD */
14430 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14431 { }
14432};
14433
14434static struct hda_verb alc269vb_init_verbs[] = {
14435 /*
14436 * Unmute ADC0 and set the default input to mic-in
14437 */
14438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14439
14440 /*
14441 * Set up output mixers (0x02 - 0x03)
14442 */
14443 /* set vol=0 to output mixers */
14444 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14445 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14446
14447 /* set up input amps for analog loopback */
14448 /* Amp Indices: DAC = 0, mixer = 1 */
14449 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14451 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14452 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14453 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14454 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14455
14456 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14457 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14458 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14459 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14460 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14461 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14462 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14463
14464 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14465 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14466
14467 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14468 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14469 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14470 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14471
14472 /* set EAPD */
14473 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14474 { }
14475};
14476
9d0b71b1
TI
14477#define alc269_auto_create_multi_out_ctls \
14478 alc268_auto_create_multi_out_ctls
05f5f477
TI
14479#define alc269_auto_create_input_ctls \
14480 alc268_auto_create_input_ctls
f6a92248
KY
14481
14482#ifdef CONFIG_SND_HDA_POWER_SAVE
14483#define alc269_loopbacks alc880_loopbacks
14484#endif
14485
def319f9 14486/* pcm configuration: identical with ALC880 */
f6a92248
KY
14487#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14488#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14489#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14490#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14491
f03d3115
TI
14492static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14493 .substreams = 1,
14494 .channels_min = 2,
14495 .channels_max = 8,
14496 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14497 /* NID is set in alc_build_pcms */
14498 .ops = {
14499 .open = alc880_playback_pcm_open,
14500 .prepare = alc880_playback_pcm_prepare,
14501 .cleanup = alc880_playback_pcm_cleanup
14502 },
14503};
14504
14505static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14506 .substreams = 1,
14507 .channels_min = 2,
14508 .channels_max = 2,
14509 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14510 /* NID is set in alc_build_pcms */
14511};
14512
ad35879a
TI
14513#ifdef CONFIG_SND_HDA_POWER_SAVE
14514static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14515{
14516 switch (codec->subsystem_id) {
14517 case 0x103c1586:
14518 return 1;
14519 }
14520 return 0;
14521}
14522
14523static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14524{
14525 /* update mute-LED according to the speaker mute state */
14526 if (nid == 0x01 || nid == 0x14) {
14527 int pinval;
14528 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14529 HDA_AMP_MUTE)
14530 pinval = 0x24;
14531 else
14532 pinval = 0x20;
14533 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14534 snd_hda_codec_update_cache(codec, 0x19, 0,
14535 AC_VERB_SET_PIN_WIDGET_CONTROL,
14536 pinval);
ad35879a
TI
14537 }
14538 return alc_check_power_status(codec, nid);
14539}
14540#endif /* CONFIG_SND_HDA_POWER_SAVE */
14541
840b64c0
TI
14542static int alc275_setup_dual_adc(struct hda_codec *codec)
14543{
14544 struct alc_spec *spec = codec->spec;
14545
14546 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14547 return 0;
14548 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14549 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14550 if (spec->ext_mic.pin <= 0x12) {
14551 spec->private_adc_nids[0] = 0x08;
14552 spec->private_adc_nids[1] = 0x11;
14553 spec->private_capsrc_nids[0] = 0x23;
14554 spec->private_capsrc_nids[1] = 0x22;
14555 } else {
14556 spec->private_adc_nids[0] = 0x11;
14557 spec->private_adc_nids[1] = 0x08;
14558 spec->private_capsrc_nids[0] = 0x22;
14559 spec->private_capsrc_nids[1] = 0x23;
14560 }
14561 spec->adc_nids = spec->private_adc_nids;
14562 spec->capsrc_nids = spec->private_capsrc_nids;
14563 spec->num_adc_nids = 2;
14564 spec->dual_adc_switch = 1;
14565 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14566 spec->adc_nids[0], spec->adc_nids[1]);
14567 return 1;
14568 }
14569 return 0;
14570}
14571
d433a678
TI
14572/* different alc269-variants */
14573enum {
14574 ALC269_TYPE_NORMAL,
14575 ALC269_TYPE_ALC259,
14576 ALC269_TYPE_ALC271X,
14577};
14578
f6a92248
KY
14579/*
14580 * BIOS auto configuration
14581 */
14582static int alc269_parse_auto_config(struct hda_codec *codec)
14583{
14584 struct alc_spec *spec = codec->spec;
cfb9fb55 14585 int err;
f6a92248
KY
14586 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14587
14588 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14589 alc269_ignore);
14590 if (err < 0)
14591 return err;
14592
14593 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14594 if (err < 0)
14595 return err;
05f5f477 14596 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
14597 if (err < 0)
14598 return err;
14599
14600 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14601
757899ac 14602 alc_auto_parse_digital(codec);
f6a92248 14603
603c4019 14604 if (spec->kctls.list)
d88897ea 14605 add_mixer(spec, spec->kctls.list);
f6a92248 14606
d433a678 14607 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14608 add_verb(spec, alc269vb_init_verbs);
6227cdce 14609 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14610 } else {
14611 add_verb(spec, alc269_init_verbs);
6227cdce 14612 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14613 }
14614
f6a92248 14615 spec->num_mux_defs = 1;
61b9b9b1 14616 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14617
14618 if (!alc275_setup_dual_adc(codec))
14619 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14620 sizeof(alc269_adc_candidates));
6694635d 14621
e01bf509 14622 /* set default input source */
840b64c0 14623 if (!spec->dual_adc_switch)
748cce43
TI
14624 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14625 spec->input_mux->items[0].index);
f6a92248
KY
14626
14627 err = alc_auto_add_mic_boost(codec);
14628 if (err < 0)
14629 return err;
14630
7e0e44d4 14631 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14632 set_capture_mixer(codec);
f53281e6 14633
f6a92248
KY
14634 return 1;
14635}
14636
e9af4f36
TI
14637#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14638#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14639#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14640
14641
14642/* init callback for auto-configuration model -- overriding the default init */
14643static void alc269_auto_init(struct hda_codec *codec)
14644{
f6c7e546 14645 struct alc_spec *spec = codec->spec;
f6a92248
KY
14646 alc269_auto_init_multi_out(codec);
14647 alc269_auto_init_hp_out(codec);
14648 alc269_auto_init_analog_input(codec);
757899ac 14649 alc_auto_init_digital(codec);
9ad0e496 14650 alc_init_jacks(codec);
f6c7e546 14651 if (spec->unsol_event)
7fb0d78f 14652 alc_inithook(codec);
f6a92248
KY
14653}
14654
977ddd6b
KY
14655#ifdef CONFIG_SND_HDA_POWER_SAVE
14656static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14657{
14658 struct alc_spec *spec = codec->spec;
14659 int val;
14660
14661 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14662 val = alc_read_coef_idx(codec, 0x04);
14663 /* Power down output pin */
14664 alc_write_coef_idx(codec, 0x04, val & ~(1<<11));
14665 }
14666
14667 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14668 val = alc_read_coef_idx(codec, 0x04);
14669 /* Power down output pin */
14670 alc_write_coef_idx(codec, 0x04, val & ~(1<<11));
14671 msleep(150);
14672 }
14673
14674 alc_shutup(codec);
14675 if (spec && spec->power_hook)
14676 spec->power_hook(codec);
14677 return 0;
14678}
14679#endif
14680#ifdef SND_HDA_NEEDS_RESUME
14681static int alc269_resume(struct hda_codec *codec)
14682{
14683 int val;
14684
14685 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14686 val = alc_read_coef_idx(codec, 0x04);
14687 /* Power down output pin */
14688 alc_write_coef_idx(codec, 0x04, val & ~(1<<11));
14689 msleep(150);
14690 }
14691
14692 codec->patch_ops.init(codec);
14693
14694 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14695 val = alc_read_coef_idx(codec, 0x04);
14696 /* Power up output pin */
14697 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14698 msleep(200);
14699 }
14700
14701 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14702 val = alc_read_coef_idx(codec, 0x04);
14703 /* Power up output pin */
14704 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14705 }
14706
14707 snd_hda_codec_resume_amp(codec);
14708 snd_hda_codec_resume_cache(codec);
14709#ifdef CONFIG_SND_HDA_POWER_SAVE
14710 if (codec->patch_ops.check_power_status)
14711 codec->patch_ops.check_power_status(codec, 0x01);
14712#endif
14713 return 0;
14714}
14715#endif
14716
ff818c24
TI
14717enum {
14718 ALC269_FIXUP_SONY_VAIO,
14719};
14720
ff818c24
TI
14721static const struct alc_fixup alc269_fixups[] = {
14722 [ALC269_FIXUP_SONY_VAIO] = {
73413b12
TI
14723 .verbs = (const struct hda_verb[]) {
14724 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14725 {}
14726 }
ff818c24
TI
14727 },
14728};
14729
14730static struct snd_pci_quirk alc269_fixup_tbl[] = {
14731 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
dbbcbc07 14732 SND_PCI_QUIRK(0x104d, 0x9077, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
ff818c24
TI
14733 {}
14734};
14735
14736
f6a92248
KY
14737/*
14738 * configuration and preset
14739 */
14740static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14741 [ALC269_BASIC] = "basic",
2922c9af 14742 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14743 [ALC269_AMIC] = "laptop-amic",
14744 [ALC269_DMIC] = "laptop-dmic",
64154835 14745 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14746 [ALC269_LIFEBOOK] = "lifebook",
14747 [ALC269_AUTO] = "auto",
f6a92248
KY
14748};
14749
14750static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14751 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14752 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14753 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14754 ALC269_AMIC),
14755 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14756 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14757 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14758 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14759 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14760 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14761 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14762 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14763 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14764 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14765 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14766 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14767 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14768 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14769 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14770 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14771 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14772 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14773 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14774 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14775 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14776 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14777 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14778 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14779 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14780 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14781 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14782 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14783 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14784 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14785 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14786 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14787 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14788 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14789 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14790 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14791 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14792 ALC269_DMIC),
60db6b53 14793 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14794 ALC269_DMIC),
14795 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14796 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14797 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14798 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14799 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14800 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14801 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14802 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14803 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14804 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14805 {}
14806};
14807
14808static struct alc_config_preset alc269_presets[] = {
14809 [ALC269_BASIC] = {
f9e336f6 14810 .mixers = { alc269_base_mixer },
f6a92248
KY
14811 .init_verbs = { alc269_init_verbs },
14812 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14813 .dac_nids = alc269_dac_nids,
14814 .hp_nid = 0x03,
14815 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14816 .channel_mode = alc269_modes,
14817 .input_mux = &alc269_capture_source,
14818 },
60db6b53
KY
14819 [ALC269_QUANTA_FL1] = {
14820 .mixers = { alc269_quanta_fl1_mixer },
14821 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14822 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14823 .dac_nids = alc269_dac_nids,
14824 .hp_nid = 0x03,
14825 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14826 .channel_mode = alc269_modes,
14827 .input_mux = &alc269_capture_source,
14828 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14829 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14830 .init_hook = alc269_quanta_fl1_init_hook,
14831 },
84898e87
KY
14832 [ALC269_AMIC] = {
14833 .mixers = { alc269_laptop_mixer },
14834 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14835 .init_verbs = { alc269_init_verbs,
84898e87 14836 alc269_laptop_amic_init_verbs },
f53281e6
KY
14837 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14838 .dac_nids = alc269_dac_nids,
14839 .hp_nid = 0x03,
14840 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14841 .channel_mode = alc269_modes,
84898e87
KY
14842 .unsol_event = alc269_laptop_unsol_event,
14843 .setup = alc269_laptop_amic_setup,
14844 .init_hook = alc269_laptop_inithook,
f53281e6 14845 },
84898e87
KY
14846 [ALC269_DMIC] = {
14847 .mixers = { alc269_laptop_mixer },
14848 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14849 .init_verbs = { alc269_init_verbs,
84898e87
KY
14850 alc269_laptop_dmic_init_verbs },
14851 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14852 .dac_nids = alc269_dac_nids,
14853 .hp_nid = 0x03,
14854 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14855 .channel_mode = alc269_modes,
14856 .unsol_event = alc269_laptop_unsol_event,
14857 .setup = alc269_laptop_dmic_setup,
14858 .init_hook = alc269_laptop_inithook,
14859 },
14860 [ALC269VB_AMIC] = {
14861 .mixers = { alc269vb_laptop_mixer },
14862 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14863 .init_verbs = { alc269vb_init_verbs,
14864 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14865 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14866 .dac_nids = alc269_dac_nids,
14867 .hp_nid = 0x03,
14868 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14869 .channel_mode = alc269_modes,
84898e87 14870 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 14871 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
14872 .init_hook = alc269_laptop_inithook,
14873 },
14874 [ALC269VB_DMIC] = {
14875 .mixers = { alc269vb_laptop_mixer },
14876 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14877 .init_verbs = { alc269vb_init_verbs,
14878 alc269vb_laptop_dmic_init_verbs },
14879 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14880 .dac_nids = alc269_dac_nids,
14881 .hp_nid = 0x03,
14882 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14883 .channel_mode = alc269_modes,
14884 .unsol_event = alc269_laptop_unsol_event,
14885 .setup = alc269vb_laptop_dmic_setup,
14886 .init_hook = alc269_laptop_inithook,
f53281e6 14887 },
26f5df26 14888 [ALC269_FUJITSU] = {
45bdd1c1 14889 .mixers = { alc269_fujitsu_mixer },
84898e87 14890 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14891 .init_verbs = { alc269_init_verbs,
84898e87 14892 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14893 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14894 .dac_nids = alc269_dac_nids,
14895 .hp_nid = 0x03,
14896 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14897 .channel_mode = alc269_modes,
84898e87
KY
14898 .unsol_event = alc269_laptop_unsol_event,
14899 .setup = alc269_laptop_dmic_setup,
14900 .init_hook = alc269_laptop_inithook,
26f5df26 14901 },
64154835
TV
14902 [ALC269_LIFEBOOK] = {
14903 .mixers = { alc269_lifebook_mixer },
14904 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14905 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14906 .dac_nids = alc269_dac_nids,
14907 .hp_nid = 0x03,
14908 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14909 .channel_mode = alc269_modes,
14910 .input_mux = &alc269_capture_source,
14911 .unsol_event = alc269_lifebook_unsol_event,
14912 .init_hook = alc269_lifebook_init_hook,
14913 },
fe3eb0a7
KY
14914 [ALC271_ACER] = {
14915 .mixers = { alc269_asus_mixer },
14916 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14917 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14918 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14919 .dac_nids = alc269_dac_nids,
14920 .adc_nids = alc262_dmic_adc_nids,
14921 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14922 .capsrc_nids = alc262_dmic_capsrc_nids,
14923 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14924 .channel_mode = alc269_modes,
14925 .input_mux = &alc269_capture_source,
14926 .dig_out_nid = ALC880_DIGOUT_NID,
14927 .unsol_event = alc_sku_unsol_event,
14928 .setup = alc269vb_laptop_dmic_setup,
14929 .init_hook = alc_inithook,
14930 },
f6a92248
KY
14931};
14932
977ddd6b
KY
14933static int alc269_fill_coef(struct hda_codec *codec)
14934{
14935 int val;
14936
14937 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
14938 alc_write_coef_idx(codec, 0xf, 0x960b);
14939 alc_write_coef_idx(codec, 0xe, 0x8817);
14940 }
14941
14942 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
14943 alc_write_coef_idx(codec, 0xf, 0x960b);
14944 alc_write_coef_idx(codec, 0xe, 0x8814);
14945 }
14946
14947 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14948 val = alc_read_coef_idx(codec, 0x04);
14949 /* Power up output pin */
14950 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14951 }
14952
14953 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14954 val = alc_read_coef_idx(codec, 0xd);
14955 if ((val & 0x0c00) >> 10 != 0x1) {
14956 /* Capless ramp up clock control */
14957 alc_write_coef_idx(codec, 0xd, val | 1<<10);
14958 }
14959 val = alc_read_coef_idx(codec, 0x17);
14960 if ((val & 0x01c0) >> 6 != 0x4) {
14961 /* Class D power on reset */
14962 alc_write_coef_idx(codec, 0x17, val | 1<<7);
14963 }
14964 }
14965 return 0;
14966}
14967
f6a92248
KY
14968static int patch_alc269(struct hda_codec *codec)
14969{
14970 struct alc_spec *spec;
14971 int board_config;
14972 int err;
14973
14974 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14975 if (spec == NULL)
14976 return -ENOMEM;
14977
14978 codec->spec = spec;
14979
da00c244
KY
14980 alc_auto_parse_customize_define(codec);
14981
274693f3 14982 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd 14983 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
d433a678 14984 spec->cdefine.platform_type == 1) {
c027ddcd 14985 alc_codec_rename(codec, "ALC271X");
d433a678
TI
14986 spec->codec_variant = ALC269_TYPE_ALC271X;
14987 } else {
c027ddcd 14988 alc_codec_rename(codec, "ALC259");
d433a678
TI
14989 spec->codec_variant = ALC269_TYPE_ALC259;
14990 }
c027ddcd
KY
14991 } else
14992 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 14993
977ddd6b
KY
14994 alc269_fill_coef(codec);
14995
f6a92248
KY
14996 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14997 alc269_models,
14998 alc269_cfg_tbl);
14999
15000 if (board_config < 0) {
9a11f1aa
TI
15001 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15002 codec->chip_name);
f6a92248
KY
15003 board_config = ALC269_AUTO;
15004 }
15005
ff818c24
TI
15006 if (board_config == ALC269_AUTO)
15007 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
15008
f6a92248
KY
15009 if (board_config == ALC269_AUTO) {
15010 /* automatic parse from the BIOS config */
15011 err = alc269_parse_auto_config(codec);
15012 if (err < 0) {
15013 alc_free(codec);
15014 return err;
15015 } else if (!err) {
15016 printk(KERN_INFO
15017 "hda_codec: Cannot set up configuration "
15018 "from BIOS. Using base mode...\n");
15019 board_config = ALC269_BASIC;
15020 }
15021 }
15022
dc1eae25 15023 if (has_cdefine_beep(codec)) {
8af2591d
TI
15024 err = snd_hda_attach_beep_device(codec, 0x1);
15025 if (err < 0) {
15026 alc_free(codec);
15027 return err;
15028 }
680cd536
KK
15029 }
15030
f6a92248 15031 if (board_config != ALC269_AUTO)
e9c364c0 15032 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15033
84898e87 15034 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15035 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15036 * fix the sample rate of analog I/O to 44.1kHz
15037 */
15038 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15039 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15040 } else if (spec->dual_adc_switch) {
15041 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15042 /* switch ADC dynamically */
15043 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15044 } else {
15045 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15046 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15047 }
f6a92248
KY
15048 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15049 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15050
6694635d 15051 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
d433a678 15052 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
6694635d
TI
15053 spec->adc_nids = alc269_adc_nids;
15054 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15055 spec->capsrc_nids = alc269_capsrc_nids;
15056 } else {
15057 spec->adc_nids = alc269vb_adc_nids;
15058 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15059 spec->capsrc_nids = alc269vb_capsrc_nids;
15060 }
84898e87
KY
15061 }
15062
f9e336f6 15063 if (!spec->cap_mixer)
b59bdf3b 15064 set_capture_mixer(codec);
dc1eae25 15065 if (has_cdefine_beep(codec))
da00c244 15066 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15067
ff818c24
TI
15068 if (board_config == ALC269_AUTO)
15069 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
15070
100d5eb3
TI
15071 spec->vmaster_nid = 0x02;
15072
f6a92248 15073 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15074#ifdef CONFIG_SND_HDA_POWER_SAVE
15075 codec->patch_ops.suspend = alc269_suspend;
15076#endif
15077#ifdef SND_HDA_NEEDS_RESUME
15078 codec->patch_ops.resume = alc269_resume;
15079#endif
f6a92248
KY
15080 if (board_config == ALC269_AUTO)
15081 spec->init_hook = alc269_auto_init;
15082#ifdef CONFIG_SND_HDA_POWER_SAVE
15083 if (!spec->loopback.amplist)
15084 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15085 if (alc269_mic2_for_mute_led(codec))
15086 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15087#endif
15088
15089 return 0;
15090}
15091
df694daa
KY
15092/*
15093 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15094 */
15095
15096/*
15097 * set the path ways for 2 channel output
15098 * need to set the codec line out and mic 1 pin widgets to inputs
15099 */
15100static struct hda_verb alc861_threestack_ch2_init[] = {
15101 /* set pin widget 1Ah (line in) for input */
15102 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15103 /* set pin widget 18h (mic1/2) for input, for mic also enable
15104 * the vref
15105 */
df694daa
KY
15106 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15107
9c7f852e
TI
15108 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15109#if 0
15110 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15111 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15112#endif
df694daa
KY
15113 { } /* end */
15114};
15115/*
15116 * 6ch mode
15117 * need to set the codec line out and mic 1 pin widgets to outputs
15118 */
15119static struct hda_verb alc861_threestack_ch6_init[] = {
15120 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15121 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15122 /* set pin widget 18h (mic1) for output (CLFE)*/
15123 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15124
15125 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15126 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15127
9c7f852e
TI
15128 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15129#if 0
15130 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15131 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15132#endif
df694daa
KY
15133 { } /* end */
15134};
15135
15136static struct hda_channel_mode alc861_threestack_modes[2] = {
15137 { 2, alc861_threestack_ch2_init },
15138 { 6, alc861_threestack_ch6_init },
15139};
22309c3e
TI
15140/* Set mic1 as input and unmute the mixer */
15141static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15142 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15143 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15144 { } /* end */
15145};
15146/* Set mic1 as output and mute mixer */
15147static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15148 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15149 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15150 { } /* end */
15151};
15152
15153static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15154 { 2, alc861_uniwill_m31_ch2_init },
15155 { 4, alc861_uniwill_m31_ch4_init },
15156};
df694daa 15157
7cdbff94
MD
15158/* Set mic1 and line-in as input and unmute the mixer */
15159static struct hda_verb alc861_asus_ch2_init[] = {
15160 /* set pin widget 1Ah (line in) for input */
15161 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15162 /* set pin widget 18h (mic1/2) for input, for mic also enable
15163 * the vref
15164 */
7cdbff94
MD
15165 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15166
15167 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15168#if 0
15169 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15170 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15171#endif
15172 { } /* end */
15173};
15174/* Set mic1 nad line-in as output and mute mixer */
15175static struct hda_verb alc861_asus_ch6_init[] = {
15176 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15177 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15178 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15179 /* set pin widget 18h (mic1) for output (CLFE)*/
15180 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15181 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15182 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15183 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15184
15185 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15186#if 0
15187 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15188 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15189#endif
15190 { } /* end */
15191};
15192
15193static struct hda_channel_mode alc861_asus_modes[2] = {
15194 { 2, alc861_asus_ch2_init },
15195 { 6, alc861_asus_ch6_init },
15196};
15197
df694daa
KY
15198/* patch-ALC861 */
15199
15200static struct snd_kcontrol_new alc861_base_mixer[] = {
15201 /* output mixer control */
15202 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15203 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15204 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15205 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15206 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15207
15208 /*Input mixer control */
15209 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15210 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15211 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15212 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15213 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15214 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15215 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15216 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15217 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15218 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15219
df694daa
KY
15220 { } /* end */
15221};
15222
15223static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15224 /* output mixer control */
15225 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15226 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15227 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15228 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15229 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15230
15231 /* Input mixer control */
15232 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15233 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15234 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15235 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15236 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15237 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15238 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15239 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15240 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15241 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15242
df694daa
KY
15243 {
15244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15245 .name = "Channel Mode",
15246 .info = alc_ch_mode_info,
15247 .get = alc_ch_mode_get,
15248 .put = alc_ch_mode_put,
15249 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15250 },
15251 { } /* end */
a53d1aec
TD
15252};
15253
d1d985f0 15254static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15255 /* output mixer control */
15256 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15258 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15259
a53d1aec 15260 { } /* end */
f12ab1e0 15261};
a53d1aec 15262
22309c3e
TI
15263static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15264 /* output mixer control */
15265 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15266 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15267 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15268 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15269 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15270
15271 /* Input mixer control */
15272 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15273 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15274 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15275 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15276 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15277 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15278 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15279 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15280 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15281 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15282
22309c3e
TI
15283 {
15284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15285 .name = "Channel Mode",
15286 .info = alc_ch_mode_info,
15287 .get = alc_ch_mode_get,
15288 .put = alc_ch_mode_put,
15289 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15290 },
15291 { } /* end */
f12ab1e0 15292};
7cdbff94
MD
15293
15294static struct snd_kcontrol_new alc861_asus_mixer[] = {
15295 /* output mixer control */
15296 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15297 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15298 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15299 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15300 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15301
15302 /* Input mixer control */
15303 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15304 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15305 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15306 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15307 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15308 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15309 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15310 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15311 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15312 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15313
7cdbff94
MD
15314 {
15315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15316 .name = "Channel Mode",
15317 .info = alc_ch_mode_info,
15318 .get = alc_ch_mode_get,
15319 .put = alc_ch_mode_put,
15320 .private_value = ARRAY_SIZE(alc861_asus_modes),
15321 },
15322 { }
56bb0cab
TI
15323};
15324
15325/* additional mixer */
d1d985f0 15326static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15327 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15328 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15329 { }
15330};
7cdbff94 15331
df694daa
KY
15332/*
15333 * generic initialization of ADC, input mixers and output mixers
15334 */
15335static struct hda_verb alc861_base_init_verbs[] = {
15336 /*
15337 * Unmute ADC0 and set the default input to mic-in
15338 */
15339 /* port-A for surround (rear panel) */
15340 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15341 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15342 /* port-B for mic-in (rear panel) with vref */
15343 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15344 /* port-C for line-in (rear panel) */
15345 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15346 /* port-D for Front */
15347 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15348 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15349 /* port-E for HP out (front panel) */
15350 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15351 /* route front PCM to HP */
9dece1d7 15352 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15353 /* port-F for mic-in (front panel) with vref */
15354 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15355 /* port-G for CLFE (rear panel) */
15356 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15357 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15358 /* port-H for side (rear panel) */
15359 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15360 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15361 /* CD-in */
15362 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15363 /* route front mic to ADC1*/
15364 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15365 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15366
df694daa
KY
15367 /* Unmute DAC0~3 & spdif out*/
15368 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15369 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15370 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15371 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15372 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15373
df694daa
KY
15374 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15375 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15376 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15377 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15378 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15379
df694daa
KY
15380 /* Unmute Stereo Mixer 15 */
15381 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15382 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15383 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15384 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15385
15386 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15387 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15388 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15389 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15390 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15391 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15392 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15393 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15394 /* hp used DAC 3 (Front) */
15395 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15396 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15397
15398 { }
15399};
15400
15401static struct hda_verb alc861_threestack_init_verbs[] = {
15402 /*
15403 * Unmute ADC0 and set the default input to mic-in
15404 */
15405 /* port-A for surround (rear panel) */
15406 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15407 /* port-B for mic-in (rear panel) with vref */
15408 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15409 /* port-C for line-in (rear panel) */
15410 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15411 /* port-D for Front */
15412 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15413 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15414 /* port-E for HP out (front panel) */
15415 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15416 /* route front PCM to HP */
9dece1d7 15417 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15418 /* port-F for mic-in (front panel) with vref */
15419 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15420 /* port-G for CLFE (rear panel) */
15421 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15422 /* port-H for side (rear panel) */
15423 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15424 /* CD-in */
15425 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15426 /* route front mic to ADC1*/
15427 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15428 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15429 /* Unmute DAC0~3 & spdif out*/
15430 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15431 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15432 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15433 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15434 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15435
df694daa
KY
15436 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15437 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15438 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15439 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15440 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15441
df694daa
KY
15442 /* Unmute Stereo Mixer 15 */
15443 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15444 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15445 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15447
15448 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15449 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15450 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15451 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15453 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15454 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15455 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15456 /* hp used DAC 3 (Front) */
15457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15458 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15459 { }
15460};
22309c3e
TI
15461
15462static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15463 /*
15464 * Unmute ADC0 and set the default input to mic-in
15465 */
15466 /* port-A for surround (rear panel) */
15467 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15468 /* port-B for mic-in (rear panel) with vref */
15469 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15470 /* port-C for line-in (rear panel) */
15471 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15472 /* port-D for Front */
15473 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15474 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15475 /* port-E for HP out (front panel) */
f12ab1e0
TI
15476 /* this has to be set to VREF80 */
15477 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15478 /* route front PCM to HP */
9dece1d7 15479 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15480 /* port-F for mic-in (front panel) with vref */
15481 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15482 /* port-G for CLFE (rear panel) */
15483 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15484 /* port-H for side (rear panel) */
15485 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15486 /* CD-in */
15487 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15488 /* route front mic to ADC1*/
15489 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15490 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15491 /* Unmute DAC0~3 & spdif out*/
15492 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15493 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15494 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15495 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15496 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15497
22309c3e
TI
15498 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15499 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15500 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15501 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15502 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15503
22309c3e
TI
15504 /* Unmute Stereo Mixer 15 */
15505 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15506 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15507 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15508 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15509
15510 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15511 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15512 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15513 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15514 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15515 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15516 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15517 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15518 /* hp used DAC 3 (Front) */
15519 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15520 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15521 { }
15522};
15523
7cdbff94
MD
15524static struct hda_verb alc861_asus_init_verbs[] = {
15525 /*
15526 * Unmute ADC0 and set the default input to mic-in
15527 */
f12ab1e0
TI
15528 /* port-A for surround (rear panel)
15529 * according to codec#0 this is the HP jack
15530 */
7cdbff94
MD
15531 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15532 /* route front PCM to HP */
15533 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15534 /* port-B for mic-in (rear panel) with vref */
15535 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15536 /* port-C for line-in (rear panel) */
15537 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15538 /* port-D for Front */
15539 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15540 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15541 /* port-E for HP out (front panel) */
f12ab1e0
TI
15542 /* this has to be set to VREF80 */
15543 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15544 /* route front PCM to HP */
9dece1d7 15545 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15546 /* port-F for mic-in (front panel) with vref */
15547 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15548 /* port-G for CLFE (rear panel) */
15549 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15550 /* port-H for side (rear panel) */
15551 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15552 /* CD-in */
15553 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15554 /* route front mic to ADC1*/
15555 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15557 /* Unmute DAC0~3 & spdif out*/
15558 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15559 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15560 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15561 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15562 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15563 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15564 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15565 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15566 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15567 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15568
7cdbff94
MD
15569 /* Unmute Stereo Mixer 15 */
15570 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15571 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15572 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15573 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15574
15575 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15576 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15578 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15579 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15580 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15581 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15582 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15583 /* hp used DAC 3 (Front) */
15584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15585 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15586 { }
15587};
15588
56bb0cab
TI
15589/* additional init verbs for ASUS laptops */
15590static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15591 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15592 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15593 { }
15594};
7cdbff94 15595
df694daa
KY
15596/*
15597 * generic initialization of ADC, input mixers and output mixers
15598 */
15599static struct hda_verb alc861_auto_init_verbs[] = {
15600 /*
15601 * Unmute ADC0 and set the default input to mic-in
15602 */
f12ab1e0 15603 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15604 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15605
df694daa
KY
15606 /* Unmute DAC0~3 & spdif out*/
15607 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15608 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15609 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15610 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15611 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15612
df694daa
KY
15613 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15614 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15615 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15616 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15617 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15618
df694daa
KY
15619 /* Unmute Stereo Mixer 15 */
15620 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15621 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15622 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15624
1c20930a
TI
15625 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15626 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15627 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15628 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15629 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15630 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15631 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15632 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15633
15634 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15635 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15636 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15638 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15639 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15640 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15641 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15642
f12ab1e0 15643 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15644
15645 { }
15646};
15647
a53d1aec
TD
15648static struct hda_verb alc861_toshiba_init_verbs[] = {
15649 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15650
a53d1aec
TD
15651 { }
15652};
15653
15654/* toggle speaker-output according to the hp-jack state */
15655static void alc861_toshiba_automute(struct hda_codec *codec)
15656{
864f92be 15657 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15658
47fd830a
TI
15659 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15660 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15661 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15662 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15663}
15664
15665static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15666 unsigned int res)
15667{
a53d1aec
TD
15668 if ((res >> 26) == ALC880_HP_EVENT)
15669 alc861_toshiba_automute(codec);
15670}
15671
def319f9 15672/* pcm configuration: identical with ALC880 */
df694daa
KY
15673#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15674#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15675#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15676#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15677
15678
15679#define ALC861_DIGOUT_NID 0x07
15680
15681static struct hda_channel_mode alc861_8ch_modes[1] = {
15682 { 8, NULL }
15683};
15684
15685static hda_nid_t alc861_dac_nids[4] = {
15686 /* front, surround, clfe, side */
15687 0x03, 0x06, 0x05, 0x04
15688};
15689
9c7f852e
TI
15690static hda_nid_t alc660_dac_nids[3] = {
15691 /* front, clfe, surround */
15692 0x03, 0x05, 0x06
15693};
15694
df694daa
KY
15695static hda_nid_t alc861_adc_nids[1] = {
15696 /* ADC0-2 */
15697 0x08,
15698};
15699
15700static struct hda_input_mux alc861_capture_source = {
15701 .num_items = 5,
15702 .items = {
15703 { "Mic", 0x0 },
15704 { "Front Mic", 0x3 },
15705 { "Line", 0x1 },
15706 { "CD", 0x4 },
15707 { "Mixer", 0x5 },
15708 },
15709};
15710
1c20930a
TI
15711static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15712{
15713 struct alc_spec *spec = codec->spec;
15714 hda_nid_t mix, srcs[5];
15715 int i, j, num;
15716
15717 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15718 return 0;
15719 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15720 if (num < 0)
15721 return 0;
15722 for (i = 0; i < num; i++) {
15723 unsigned int type;
a22d543a 15724 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15725 if (type != AC_WID_AUD_OUT)
15726 continue;
15727 for (j = 0; j < spec->multiout.num_dacs; j++)
15728 if (spec->multiout.dac_nids[j] == srcs[i])
15729 break;
15730 if (j >= spec->multiout.num_dacs)
15731 return srcs[i];
15732 }
15733 return 0;
15734}
15735
df694daa 15736/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15737static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15738 const struct auto_pin_cfg *cfg)
df694daa 15739{
1c20930a 15740 struct alc_spec *spec = codec->spec;
df694daa 15741 int i;
1c20930a 15742 hda_nid_t nid, dac;
df694daa
KY
15743
15744 spec->multiout.dac_nids = spec->private_dac_nids;
15745 for (i = 0; i < cfg->line_outs; i++) {
15746 nid = cfg->line_out_pins[i];
1c20930a
TI
15747 dac = alc861_look_for_dac(codec, nid);
15748 if (!dac)
15749 continue;
15750 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15751 }
df694daa
KY
15752 return 0;
15753}
15754
1c20930a
TI
15755static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15756 hda_nid_t nid, unsigned int chs)
15757{
0afe5f89 15758 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15759 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15760}
15761
df694daa 15762/* add playback controls from the parsed DAC table */
1c20930a 15763static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15764 const struct auto_pin_cfg *cfg)
15765{
1c20930a 15766 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15767 static const char *chname[4] = {
15768 "Front", "Surround", NULL /*CLFE*/, "Side"
15769 };
df694daa 15770 hda_nid_t nid;
1c20930a
TI
15771 int i, err;
15772
15773 if (cfg->line_outs == 1) {
15774 const char *pfx = NULL;
15775 if (!cfg->hp_outs)
15776 pfx = "Master";
15777 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15778 pfx = "Speaker";
15779 if (pfx) {
15780 nid = spec->multiout.dac_nids[0];
15781 return alc861_create_out_sw(codec, pfx, nid, 3);
15782 }
15783 }
df694daa
KY
15784
15785 for (i = 0; i < cfg->line_outs; i++) {
15786 nid = spec->multiout.dac_nids[i];
f12ab1e0 15787 if (!nid)
df694daa 15788 continue;
1c20930a 15789 if (i == 2) {
df694daa 15790 /* Center/LFE */
1c20930a 15791 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15792 if (err < 0)
df694daa 15793 return err;
1c20930a 15794 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15795 if (err < 0)
df694daa
KY
15796 return err;
15797 } else {
1c20930a 15798 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15799 if (err < 0)
df694daa
KY
15800 return err;
15801 }
15802 }
15803 return 0;
15804}
15805
1c20930a 15806static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15807{
1c20930a 15808 struct alc_spec *spec = codec->spec;
df694daa
KY
15809 int err;
15810 hda_nid_t nid;
15811
f12ab1e0 15812 if (!pin)
df694daa
KY
15813 return 0;
15814
15815 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15816 nid = alc861_look_for_dac(codec, pin);
15817 if (nid) {
15818 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15819 if (err < 0)
15820 return err;
15821 spec->multiout.hp_nid = nid;
15822 }
df694daa
KY
15823 }
15824 return 0;
15825}
15826
15827/* create playback/capture controls for input pins */
05f5f477 15828static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15829 const struct auto_pin_cfg *cfg)
df694daa 15830{
05f5f477 15831 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15832}
15833
f12ab1e0
TI
15834static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15835 hda_nid_t nid,
1c20930a 15836 int pin_type, hda_nid_t dac)
df694daa 15837{
1c20930a
TI
15838 hda_nid_t mix, srcs[5];
15839 int i, num;
15840
564c5bea
JL
15841 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15842 pin_type);
1c20930a 15843 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15844 AMP_OUT_UNMUTE);
1c20930a
TI
15845 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15846 return;
15847 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15848 if (num < 0)
15849 return;
15850 for (i = 0; i < num; i++) {
15851 unsigned int mute;
15852 if (srcs[i] == dac || srcs[i] == 0x15)
15853 mute = AMP_IN_UNMUTE(i);
15854 else
15855 mute = AMP_IN_MUTE(i);
15856 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15857 mute);
15858 }
df694daa
KY
15859}
15860
15861static void alc861_auto_init_multi_out(struct hda_codec *codec)
15862{
15863 struct alc_spec *spec = codec->spec;
15864 int i;
15865
15866 for (i = 0; i < spec->autocfg.line_outs; i++) {
15867 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15868 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15869 if (nid)
baba8ee9 15870 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15871 spec->multiout.dac_nids[i]);
df694daa
KY
15872 }
15873}
15874
15875static void alc861_auto_init_hp_out(struct hda_codec *codec)
15876{
15877 struct alc_spec *spec = codec->spec;
df694daa 15878
15870f05
TI
15879 if (spec->autocfg.hp_outs)
15880 alc861_auto_set_output_and_unmute(codec,
15881 spec->autocfg.hp_pins[0],
15882 PIN_HP,
1c20930a 15883 spec->multiout.hp_nid);
15870f05
TI
15884 if (spec->autocfg.speaker_outs)
15885 alc861_auto_set_output_and_unmute(codec,
15886 spec->autocfg.speaker_pins[0],
15887 PIN_OUT,
1c20930a 15888 spec->multiout.dac_nids[0]);
df694daa
KY
15889}
15890
15891static void alc861_auto_init_analog_input(struct hda_codec *codec)
15892{
15893 struct alc_spec *spec = codec->spec;
66ceeb6b 15894 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
15895 int i;
15896
66ceeb6b
TI
15897 for (i = 0; i < cfg->num_inputs; i++) {
15898 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 15899 if (nid >= 0x0c && nid <= 0x11)
30ea098f 15900 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
15901 }
15902}
15903
15904/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15905/* return 1 if successful, 0 if the proper config is not found,
15906 * or a negative error code
15907 */
df694daa
KY
15908static int alc861_parse_auto_config(struct hda_codec *codec)
15909{
15910 struct alc_spec *spec = codec->spec;
15911 int err;
15912 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15913
f12ab1e0
TI
15914 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15915 alc861_ignore);
15916 if (err < 0)
df694daa 15917 return err;
f12ab1e0 15918 if (!spec->autocfg.line_outs)
df694daa
KY
15919 return 0; /* can't find valid BIOS pin config */
15920
1c20930a 15921 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15922 if (err < 0)
15923 return err;
1c20930a 15924 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15925 if (err < 0)
15926 return err;
1c20930a 15927 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15928 if (err < 0)
15929 return err;
05f5f477 15930 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15931 if (err < 0)
df694daa
KY
15932 return err;
15933
15934 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15935
757899ac 15936 alc_auto_parse_digital(codec);
df694daa 15937
603c4019 15938 if (spec->kctls.list)
d88897ea 15939 add_mixer(spec, spec->kctls.list);
df694daa 15940
d88897ea 15941 add_verb(spec, alc861_auto_init_verbs);
df694daa 15942
a1e8d2da 15943 spec->num_mux_defs = 1;
61b9b9b1 15944 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15945
15946 spec->adc_nids = alc861_adc_nids;
15947 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15948 set_capture_mixer(codec);
df694daa 15949
6227cdce 15950 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15951
df694daa
KY
15952 return 1;
15953}
15954
ae6b813a
TI
15955/* additional initialization for auto-configuration model */
15956static void alc861_auto_init(struct hda_codec *codec)
df694daa 15957{
f6c7e546 15958 struct alc_spec *spec = codec->spec;
df694daa
KY
15959 alc861_auto_init_multi_out(codec);
15960 alc861_auto_init_hp_out(codec);
15961 alc861_auto_init_analog_input(codec);
757899ac 15962 alc_auto_init_digital(codec);
f6c7e546 15963 if (spec->unsol_event)
7fb0d78f 15964 alc_inithook(codec);
df694daa
KY
15965}
15966
cb53c626
TI
15967#ifdef CONFIG_SND_HDA_POWER_SAVE
15968static struct hda_amp_list alc861_loopbacks[] = {
15969 { 0x15, HDA_INPUT, 0 },
15970 { 0x15, HDA_INPUT, 1 },
15971 { 0x15, HDA_INPUT, 2 },
15972 { 0x15, HDA_INPUT, 3 },
15973 { } /* end */
15974};
15975#endif
15976
df694daa
KY
15977
15978/*
15979 * configuration and preset
15980 */
f5fcc13c
TI
15981static const char *alc861_models[ALC861_MODEL_LAST] = {
15982 [ALC861_3ST] = "3stack",
15983 [ALC660_3ST] = "3stack-660",
15984 [ALC861_3ST_DIG] = "3stack-dig",
15985 [ALC861_6ST_DIG] = "6stack-dig",
15986 [ALC861_UNIWILL_M31] = "uniwill-m31",
15987 [ALC861_TOSHIBA] = "toshiba",
15988 [ALC861_ASUS] = "asus",
15989 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15990 [ALC861_AUTO] = "auto",
15991};
15992
15993static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15994 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15995 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15996 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15997 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15998 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15999 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16000 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16001 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16002 * Any other models that need this preset?
16003 */
16004 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16005 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16006 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16007 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16008 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16009 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16010 /* FIXME: the below seems conflict */
16011 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16012 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16013 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16014 {}
16015};
16016
16017static struct alc_config_preset alc861_presets[] = {
16018 [ALC861_3ST] = {
16019 .mixers = { alc861_3ST_mixer },
16020 .init_verbs = { alc861_threestack_init_verbs },
16021 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16022 .dac_nids = alc861_dac_nids,
16023 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16024 .channel_mode = alc861_threestack_modes,
4e195a7b 16025 .need_dac_fix = 1,
df694daa
KY
16026 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16027 .adc_nids = alc861_adc_nids,
16028 .input_mux = &alc861_capture_source,
16029 },
16030 [ALC861_3ST_DIG] = {
16031 .mixers = { alc861_base_mixer },
16032 .init_verbs = { alc861_threestack_init_verbs },
16033 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16034 .dac_nids = alc861_dac_nids,
16035 .dig_out_nid = ALC861_DIGOUT_NID,
16036 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16037 .channel_mode = alc861_threestack_modes,
4e195a7b 16038 .need_dac_fix = 1,
df694daa
KY
16039 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16040 .adc_nids = alc861_adc_nids,
16041 .input_mux = &alc861_capture_source,
16042 },
16043 [ALC861_6ST_DIG] = {
16044 .mixers = { alc861_base_mixer },
16045 .init_verbs = { alc861_base_init_verbs },
16046 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16047 .dac_nids = alc861_dac_nids,
16048 .dig_out_nid = ALC861_DIGOUT_NID,
16049 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16050 .channel_mode = alc861_8ch_modes,
16051 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16052 .adc_nids = alc861_adc_nids,
16053 .input_mux = &alc861_capture_source,
16054 },
9c7f852e
TI
16055 [ALC660_3ST] = {
16056 .mixers = { alc861_3ST_mixer },
16057 .init_verbs = { alc861_threestack_init_verbs },
16058 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16059 .dac_nids = alc660_dac_nids,
16060 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16061 .channel_mode = alc861_threestack_modes,
4e195a7b 16062 .need_dac_fix = 1,
9c7f852e
TI
16063 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16064 .adc_nids = alc861_adc_nids,
16065 .input_mux = &alc861_capture_source,
16066 },
22309c3e
TI
16067 [ALC861_UNIWILL_M31] = {
16068 .mixers = { alc861_uniwill_m31_mixer },
16069 .init_verbs = { alc861_uniwill_m31_init_verbs },
16070 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16071 .dac_nids = alc861_dac_nids,
16072 .dig_out_nid = ALC861_DIGOUT_NID,
16073 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16074 .channel_mode = alc861_uniwill_m31_modes,
16075 .need_dac_fix = 1,
16076 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16077 .adc_nids = alc861_adc_nids,
16078 .input_mux = &alc861_capture_source,
16079 },
a53d1aec
TD
16080 [ALC861_TOSHIBA] = {
16081 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16082 .init_verbs = { alc861_base_init_verbs,
16083 alc861_toshiba_init_verbs },
a53d1aec
TD
16084 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16085 .dac_nids = alc861_dac_nids,
16086 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16087 .channel_mode = alc883_3ST_2ch_modes,
16088 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16089 .adc_nids = alc861_adc_nids,
16090 .input_mux = &alc861_capture_source,
16091 .unsol_event = alc861_toshiba_unsol_event,
16092 .init_hook = alc861_toshiba_automute,
16093 },
7cdbff94
MD
16094 [ALC861_ASUS] = {
16095 .mixers = { alc861_asus_mixer },
16096 .init_verbs = { alc861_asus_init_verbs },
16097 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16098 .dac_nids = alc861_dac_nids,
16099 .dig_out_nid = ALC861_DIGOUT_NID,
16100 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16101 .channel_mode = alc861_asus_modes,
16102 .need_dac_fix = 1,
16103 .hp_nid = 0x06,
16104 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16105 .adc_nids = alc861_adc_nids,
16106 .input_mux = &alc861_capture_source,
16107 },
56bb0cab
TI
16108 [ALC861_ASUS_LAPTOP] = {
16109 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16110 .init_verbs = { alc861_asus_init_verbs,
16111 alc861_asus_laptop_init_verbs },
16112 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16113 .dac_nids = alc861_dac_nids,
16114 .dig_out_nid = ALC861_DIGOUT_NID,
16115 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16116 .channel_mode = alc883_3ST_2ch_modes,
16117 .need_dac_fix = 1,
16118 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16119 .adc_nids = alc861_adc_nids,
16120 .input_mux = &alc861_capture_source,
16121 },
16122};
df694daa 16123
cfc9b06f
TI
16124/* Pin config fixes */
16125enum {
16126 PINFIX_FSC_AMILO_PI1505,
16127};
16128
cfc9b06f
TI
16129static const struct alc_fixup alc861_fixups[] = {
16130 [PINFIX_FSC_AMILO_PI1505] = {
73413b12
TI
16131 .pins = (const struct alc_pincfg[]) {
16132 { 0x0b, 0x0221101f }, /* HP */
16133 { 0x0f, 0x90170310 }, /* speaker */
16134 { }
16135 }
cfc9b06f
TI
16136 },
16137};
16138
16139static struct snd_pci_quirk alc861_fixup_tbl[] = {
16140 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16141 {}
16142};
df694daa
KY
16143
16144static int patch_alc861(struct hda_codec *codec)
16145{
16146 struct alc_spec *spec;
16147 int board_config;
16148 int err;
16149
dc041e0b 16150 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16151 if (spec == NULL)
16152 return -ENOMEM;
16153
f12ab1e0 16154 codec->spec = spec;
df694daa 16155
f5fcc13c
TI
16156 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16157 alc861_models,
16158 alc861_cfg_tbl);
9c7f852e 16159
f5fcc13c 16160 if (board_config < 0) {
9a11f1aa
TI
16161 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16162 codec->chip_name);
df694daa
KY
16163 board_config = ALC861_AUTO;
16164 }
16165
7fa90e87
TI
16166 if (board_config == ALC861_AUTO)
16167 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 16168
df694daa
KY
16169 if (board_config == ALC861_AUTO) {
16170 /* automatic parse from the BIOS config */
16171 err = alc861_parse_auto_config(codec);
16172 if (err < 0) {
16173 alc_free(codec);
16174 return err;
f12ab1e0 16175 } else if (!err) {
9c7f852e
TI
16176 printk(KERN_INFO
16177 "hda_codec: Cannot set up configuration "
16178 "from BIOS. Using base mode...\n");
df694daa
KY
16179 board_config = ALC861_3ST_DIG;
16180 }
16181 }
16182
680cd536
KK
16183 err = snd_hda_attach_beep_device(codec, 0x23);
16184 if (err < 0) {
16185 alc_free(codec);
16186 return err;
16187 }
16188
df694daa 16189 if (board_config != ALC861_AUTO)
e9c364c0 16190 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16191
df694daa
KY
16192 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16193 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16194
df694daa
KY
16195 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16196 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16197
c7a8eb10
TI
16198 if (!spec->cap_mixer)
16199 set_capture_mixer(codec);
45bdd1c1
TI
16200 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16201
2134ea4f
TI
16202 spec->vmaster_nid = 0x03;
16203
7fa90e87
TI
16204 if (board_config == ALC861_AUTO)
16205 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
16206
df694daa 16207 codec->patch_ops = alc_patch_ops;
c97259df 16208 if (board_config == ALC861_AUTO) {
ae6b813a 16209 spec->init_hook = alc861_auto_init;
c97259df
DC
16210#ifdef CONFIG_SND_HDA_POWER_SAVE
16211 spec->power_hook = alc_power_eapd;
16212#endif
16213 }
cb53c626
TI
16214#ifdef CONFIG_SND_HDA_POWER_SAVE
16215 if (!spec->loopback.amplist)
16216 spec->loopback.amplist = alc861_loopbacks;
16217#endif
ea1fb29a 16218
1da177e4
LT
16219 return 0;
16220}
16221
f32610ed
JS
16222/*
16223 * ALC861-VD support
16224 *
16225 * Based on ALC882
16226 *
16227 * In addition, an independent DAC
16228 */
16229#define ALC861VD_DIGOUT_NID 0x06
16230
16231static hda_nid_t alc861vd_dac_nids[4] = {
16232 /* front, surr, clfe, side surr */
16233 0x02, 0x03, 0x04, 0x05
16234};
16235
16236/* dac_nids for ALC660vd are in a different order - according to
16237 * Realtek's driver.
def319f9 16238 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16239 * of ALC660vd codecs, but for now there is only 3stack mixer
16240 * - and it is the same as in 861vd.
16241 * adc_nids in ALC660vd are (is) the same as in 861vd
16242 */
16243static hda_nid_t alc660vd_dac_nids[3] = {
16244 /* front, rear, clfe, rear_surr */
16245 0x02, 0x04, 0x03
16246};
16247
16248static hda_nid_t alc861vd_adc_nids[1] = {
16249 /* ADC0 */
16250 0x09,
16251};
16252
e1406348
TI
16253static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16254
f32610ed
JS
16255/* input MUX */
16256/* FIXME: should be a matrix-type input source selection */
16257static struct hda_input_mux alc861vd_capture_source = {
16258 .num_items = 4,
16259 .items = {
16260 { "Mic", 0x0 },
16261 { "Front Mic", 0x1 },
16262 { "Line", 0x2 },
16263 { "CD", 0x4 },
16264 },
16265};
16266
272a527c 16267static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16268 .num_items = 2,
272a527c 16269 .items = {
b419f346
TD
16270 { "Ext Mic", 0x0 },
16271 { "Int Mic", 0x1 },
272a527c
KY
16272 },
16273};
16274
d1a991a6
KY
16275static struct hda_input_mux alc861vd_hp_capture_source = {
16276 .num_items = 2,
16277 .items = {
16278 { "Front Mic", 0x0 },
16279 { "ATAPI Mic", 0x1 },
16280 },
16281};
16282
f32610ed
JS
16283/*
16284 * 2ch mode
16285 */
16286static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16287 { 2, NULL }
16288};
16289
16290/*
16291 * 6ch mode
16292 */
16293static struct hda_verb alc861vd_6stack_ch6_init[] = {
16294 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16295 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16296 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16297 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16298 { } /* end */
16299};
16300
16301/*
16302 * 8ch mode
16303 */
16304static struct hda_verb alc861vd_6stack_ch8_init[] = {
16305 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16306 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16307 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16308 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16309 { } /* end */
16310};
16311
16312static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16313 { 6, alc861vd_6stack_ch6_init },
16314 { 8, alc861vd_6stack_ch8_init },
16315};
16316
16317static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16318 {
16319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16320 .name = "Channel Mode",
16321 .info = alc_ch_mode_info,
16322 .get = alc_ch_mode_get,
16323 .put = alc_ch_mode_put,
16324 },
16325 { } /* end */
16326};
16327
f32610ed
JS
16328/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16329 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16330 */
16331static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16332 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16333 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16334
16335 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16336 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16337
16338 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16339 HDA_OUTPUT),
16340 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16341 HDA_OUTPUT),
16342 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16343 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16344
16345 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16346 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16347
16348 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16349
16350 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16353
16354 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16355 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16356 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16357
16358 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16359 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16360
16361 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16362 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16363
f32610ed
JS
16364 { } /* end */
16365};
16366
16367static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16368 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16369 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16370
16371 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16372
16373 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16374 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16375 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16376
16377 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16378 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16379 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16380
16381 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16382 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16383
16384 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16385 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16386
f32610ed
JS
16387 { } /* end */
16388};
16389
bdd148a3
KY
16390static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16391 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16392 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16393 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16394
16395 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16396
16397 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16398 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16399 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16400
16401 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16402 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16403 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16404
16405 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16406 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16407
16408 { } /* end */
16409};
16410
b419f346
TD
16411/* Pin assignment: Speaker=0x14, HP = 0x15,
16412 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16413 */
16414static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16415 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16416 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16417 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16418 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
16419 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16420 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16421 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16422 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16423 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16424 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16425 { } /* end */
16426};
16427
d1a991a6
KY
16428/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16429 * Front Mic=0x18, ATAPI Mic = 0x19,
16430 */
16431static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16432 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16433 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16434 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16435 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16436 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16437 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16438 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16439 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16440
d1a991a6
KY
16441 { } /* end */
16442};
16443
f32610ed
JS
16444/*
16445 * generic initialization of ADC, input mixers and output mixers
16446 */
16447static struct hda_verb alc861vd_volume_init_verbs[] = {
16448 /*
16449 * Unmute ADC0 and set the default input to mic-in
16450 */
16451 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16452 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16453
16454 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16455 * the analog-loopback mixer widget
16456 */
16457 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16458 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16459 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16460 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16461 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16462 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16463
16464 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16466 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16467 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16469
16470 /*
16471 * Set up output mixers (0x02 - 0x05)
16472 */
16473 /* set vol=0 to output mixers */
16474 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16475 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16476 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16477 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16478
16479 /* set up input amps for analog loopback */
16480 /* Amp Indices: DAC = 0, mixer = 1 */
16481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16482 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16483 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16484 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16485 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16486 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16487 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16488 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16489
16490 { }
16491};
16492
16493/*
16494 * 3-stack pin configuration:
16495 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16496 */
16497static struct hda_verb alc861vd_3stack_init_verbs[] = {
16498 /*
16499 * Set pin mode and muting
16500 */
16501 /* set front pin widgets 0x14 for output */
16502 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16503 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16504 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16505
16506 /* Mic (rear) pin: input vref at 80% */
16507 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16509 /* Front Mic pin: input vref at 80% */
16510 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16511 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16512 /* Line In pin: input */
16513 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16514 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16515 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16517 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16518 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16519 /* CD pin widget for input */
16520 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16521
16522 { }
16523};
16524
16525/*
16526 * 6-stack pin configuration:
16527 */
16528static struct hda_verb alc861vd_6stack_init_verbs[] = {
16529 /*
16530 * Set pin mode and muting
16531 */
16532 /* set front pin widgets 0x14 for output */
16533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16534 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16535 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16536
16537 /* Rear Pin: output 1 (0x0d) */
16538 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16540 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16541 /* CLFE Pin: output 2 (0x0e) */
16542 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16543 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16544 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16545 /* Side Pin: output 3 (0x0f) */
16546 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16547 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16548 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16549
16550 /* Mic (rear) pin: input vref at 80% */
16551 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16552 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16553 /* Front Mic pin: input vref at 80% */
16554 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16556 /* Line In pin: input */
16557 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16558 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16559 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16560 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16561 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16562 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16563 /* CD pin widget for input */
16564 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16565
16566 { }
16567};
16568
bdd148a3
KY
16569static struct hda_verb alc861vd_eapd_verbs[] = {
16570 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16571 { }
16572};
16573
f9423e7a
KY
16574static struct hda_verb alc660vd_eapd_verbs[] = {
16575 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16576 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16577 { }
16578};
16579
bdd148a3
KY
16580static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16584 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16585 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16586 {}
16587};
16588
bdd148a3
KY
16589static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16590{
16591 unsigned int present;
16592 unsigned char bits;
16593
864f92be 16594 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 16595 bits = present ? HDA_AMP_MUTE : 0;
864f92be 16596
47fd830a
TI
16597 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16598 HDA_AMP_MUTE, bits);
bdd148a3
KY
16599}
16600
4f5d1706 16601static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16602{
a9fd4f3f 16603 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16604 spec->autocfg.hp_pins[0] = 0x1b;
16605 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16606}
16607
16608static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16609{
a9fd4f3f 16610 alc_automute_amp(codec);
bdd148a3
KY
16611 alc861vd_lenovo_mic_automute(codec);
16612}
16613
16614static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16615 unsigned int res)
16616{
16617 switch (res >> 26) {
bdd148a3
KY
16618 case ALC880_MIC_EVENT:
16619 alc861vd_lenovo_mic_automute(codec);
16620 break;
a9fd4f3f
TI
16621 default:
16622 alc_automute_amp_unsol_event(codec, res);
16623 break;
bdd148a3
KY
16624 }
16625}
16626
272a527c
KY
16627static struct hda_verb alc861vd_dallas_verbs[] = {
16628 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16629 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16630 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16631 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16632
16633 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16635 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16636 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16637 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16638 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16639 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16640 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16641
272a527c
KY
16642 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16643 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16644 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16645 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16646 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16647 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16648 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16649 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16650
16651 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16652 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16655 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16656 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16657 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16658 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16659
16660 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16661 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16662 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16664
16665 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16666 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16667 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16668
16669 { } /* end */
16670};
16671
16672/* toggle speaker-output according to the hp-jack state */
4f5d1706 16673static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16674{
a9fd4f3f 16675 struct alc_spec *spec = codec->spec;
272a527c 16676
a9fd4f3f
TI
16677 spec->autocfg.hp_pins[0] = 0x15;
16678 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16679}
16680
cb53c626
TI
16681#ifdef CONFIG_SND_HDA_POWER_SAVE
16682#define alc861vd_loopbacks alc880_loopbacks
16683#endif
16684
def319f9 16685/* pcm configuration: identical with ALC880 */
f32610ed
JS
16686#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16687#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16688#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16689#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16690
16691/*
16692 * configuration and preset
16693 */
16694static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16695 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16696 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16697 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16698 [ALC861VD_3ST] = "3stack",
16699 [ALC861VD_3ST_DIG] = "3stack-digout",
16700 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16701 [ALC861VD_LENOVO] = "lenovo",
272a527c 16702 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16703 [ALC861VD_HP] = "hp",
f32610ed
JS
16704 [ALC861VD_AUTO] = "auto",
16705};
16706
16707static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16708 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16709 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16710 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16711 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16712 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16713 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16714 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16715 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16716 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16717 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16718 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16719 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16720 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16721 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16722 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16723 {}
16724};
16725
16726static struct alc_config_preset alc861vd_presets[] = {
16727 [ALC660VD_3ST] = {
16728 .mixers = { alc861vd_3st_mixer },
16729 .init_verbs = { alc861vd_volume_init_verbs,
16730 alc861vd_3stack_init_verbs },
16731 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16732 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16733 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16734 .channel_mode = alc861vd_3stack_2ch_modes,
16735 .input_mux = &alc861vd_capture_source,
16736 },
6963f84c
MC
16737 [ALC660VD_3ST_DIG] = {
16738 .mixers = { alc861vd_3st_mixer },
16739 .init_verbs = { alc861vd_volume_init_verbs,
16740 alc861vd_3stack_init_verbs },
16741 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16742 .dac_nids = alc660vd_dac_nids,
16743 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16744 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16745 .channel_mode = alc861vd_3stack_2ch_modes,
16746 .input_mux = &alc861vd_capture_source,
16747 },
f32610ed
JS
16748 [ALC861VD_3ST] = {
16749 .mixers = { alc861vd_3st_mixer },
16750 .init_verbs = { alc861vd_volume_init_verbs,
16751 alc861vd_3stack_init_verbs },
16752 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16753 .dac_nids = alc861vd_dac_nids,
16754 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16755 .channel_mode = alc861vd_3stack_2ch_modes,
16756 .input_mux = &alc861vd_capture_source,
16757 },
16758 [ALC861VD_3ST_DIG] = {
16759 .mixers = { alc861vd_3st_mixer },
16760 .init_verbs = { alc861vd_volume_init_verbs,
16761 alc861vd_3stack_init_verbs },
16762 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16763 .dac_nids = alc861vd_dac_nids,
16764 .dig_out_nid = ALC861VD_DIGOUT_NID,
16765 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16766 .channel_mode = alc861vd_3stack_2ch_modes,
16767 .input_mux = &alc861vd_capture_source,
16768 },
16769 [ALC861VD_6ST_DIG] = {
16770 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16771 .init_verbs = { alc861vd_volume_init_verbs,
16772 alc861vd_6stack_init_verbs },
16773 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16774 .dac_nids = alc861vd_dac_nids,
16775 .dig_out_nid = ALC861VD_DIGOUT_NID,
16776 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16777 .channel_mode = alc861vd_6stack_modes,
16778 .input_mux = &alc861vd_capture_source,
16779 },
bdd148a3
KY
16780 [ALC861VD_LENOVO] = {
16781 .mixers = { alc861vd_lenovo_mixer },
16782 .init_verbs = { alc861vd_volume_init_verbs,
16783 alc861vd_3stack_init_verbs,
16784 alc861vd_eapd_verbs,
16785 alc861vd_lenovo_unsol_verbs },
16786 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16787 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16788 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16789 .channel_mode = alc861vd_3stack_2ch_modes,
16790 .input_mux = &alc861vd_capture_source,
16791 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16792 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16793 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16794 },
272a527c
KY
16795 [ALC861VD_DALLAS] = {
16796 .mixers = { alc861vd_dallas_mixer },
16797 .init_verbs = { alc861vd_dallas_verbs },
16798 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16799 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16800 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16801 .channel_mode = alc861vd_3stack_2ch_modes,
16802 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16803 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16804 .setup = alc861vd_dallas_setup,
16805 .init_hook = alc_automute_amp,
d1a991a6
KY
16806 },
16807 [ALC861VD_HP] = {
16808 .mixers = { alc861vd_hp_mixer },
16809 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16810 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16811 .dac_nids = alc861vd_dac_nids,
d1a991a6 16812 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16813 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16814 .channel_mode = alc861vd_3stack_2ch_modes,
16815 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16816 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16817 .setup = alc861vd_dallas_setup,
16818 .init_hook = alc_automute_amp,
ea1fb29a 16819 },
13c94744
TI
16820 [ALC660VD_ASUS_V1S] = {
16821 .mixers = { alc861vd_lenovo_mixer },
16822 .init_verbs = { alc861vd_volume_init_verbs,
16823 alc861vd_3stack_init_verbs,
16824 alc861vd_eapd_verbs,
16825 alc861vd_lenovo_unsol_verbs },
16826 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16827 .dac_nids = alc660vd_dac_nids,
16828 .dig_out_nid = ALC861VD_DIGOUT_NID,
16829 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16830 .channel_mode = alc861vd_3stack_2ch_modes,
16831 .input_mux = &alc861vd_capture_source,
16832 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16833 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16834 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16835 },
f32610ed
JS
16836};
16837
16838/*
16839 * BIOS auto configuration
16840 */
05f5f477
TI
16841static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16842 const struct auto_pin_cfg *cfg)
16843{
6227cdce 16844 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16845}
16846
16847
f32610ed
JS
16848static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16849 hda_nid_t nid, int pin_type, int dac_idx)
16850{
f6c7e546 16851 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16852}
16853
16854static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16855{
16856 struct alc_spec *spec = codec->spec;
16857 int i;
16858
16859 for (i = 0; i <= HDA_SIDE; i++) {
16860 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16861 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16862 if (nid)
16863 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16864 pin_type, i);
f32610ed
JS
16865 }
16866}
16867
16868
16869static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16870{
16871 struct alc_spec *spec = codec->spec;
16872 hda_nid_t pin;
16873
16874 pin = spec->autocfg.hp_pins[0];
def319f9 16875 if (pin) /* connect to front and use dac 0 */
f32610ed 16876 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16877 pin = spec->autocfg.speaker_pins[0];
16878 if (pin)
16879 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16880}
16881
f32610ed
JS
16882#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16883
16884static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16885{
16886 struct alc_spec *spec = codec->spec;
66ceeb6b 16887 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
16888 int i;
16889
66ceeb6b
TI
16890 for (i = 0; i < cfg->num_inputs; i++) {
16891 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 16892 if (alc_is_input_pin(codec, nid)) {
30ea098f 16893 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
16894 if (nid != ALC861VD_PIN_CD_NID &&
16895 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16896 snd_hda_codec_write(codec, nid, 0,
16897 AC_VERB_SET_AMP_GAIN_MUTE,
16898 AMP_OUT_MUTE);
16899 }
16900 }
16901}
16902
f511b01c
TI
16903#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16904
f32610ed
JS
16905#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16906#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16907
16908/* add playback controls from the parsed DAC table */
16909/* Based on ALC880 version. But ALC861VD has separate,
16910 * different NIDs for mute/unmute switch and volume control */
16911static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16912 const struct auto_pin_cfg *cfg)
16913{
f32610ed
JS
16914 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16915 hda_nid_t nid_v, nid_s;
16916 int i, err;
16917
16918 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16919 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16920 continue;
16921 nid_v = alc861vd_idx_to_mixer_vol(
16922 alc880_dac_to_idx(
16923 spec->multiout.dac_nids[i]));
16924 nid_s = alc861vd_idx_to_mixer_switch(
16925 alc880_dac_to_idx(
16926 spec->multiout.dac_nids[i]));
16927
16928 if (i == 2) {
16929 /* Center/LFE */
0afe5f89
TI
16930 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16931 "Center",
f12ab1e0
TI
16932 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16933 HDA_OUTPUT));
16934 if (err < 0)
f32610ed 16935 return err;
0afe5f89
TI
16936 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16937 "LFE",
f12ab1e0
TI
16938 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16939 HDA_OUTPUT));
16940 if (err < 0)
f32610ed 16941 return err;
0afe5f89
TI
16942 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16943 "Center",
f12ab1e0
TI
16944 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16945 HDA_INPUT));
16946 if (err < 0)
f32610ed 16947 return err;
0afe5f89
TI
16948 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16949 "LFE",
f12ab1e0
TI
16950 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16951 HDA_INPUT));
16952 if (err < 0)
f32610ed
JS
16953 return err;
16954 } else {
a4fcd491
TI
16955 const char *pfx;
16956 if (cfg->line_outs == 1 &&
16957 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16958 if (!cfg->hp_pins)
16959 pfx = "Speaker";
16960 else
16961 pfx = "PCM";
16962 } else
16963 pfx = chname[i];
0afe5f89 16964 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16965 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16966 HDA_OUTPUT));
16967 if (err < 0)
f32610ed 16968 return err;
a4fcd491
TI
16969 if (cfg->line_outs == 1 &&
16970 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16971 pfx = "Speaker";
0afe5f89 16972 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16973 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16974 HDA_INPUT));
16975 if (err < 0)
f32610ed
JS
16976 return err;
16977 }
16978 }
16979 return 0;
16980}
16981
16982/* add playback controls for speaker and HP outputs */
16983/* Based on ALC880 version. But ALC861VD has separate,
16984 * different NIDs for mute/unmute switch and volume control */
16985static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16986 hda_nid_t pin, const char *pfx)
16987{
16988 hda_nid_t nid_v, nid_s;
16989 int err;
f32610ed 16990
f12ab1e0 16991 if (!pin)
f32610ed
JS
16992 return 0;
16993
16994 if (alc880_is_fixed_pin(pin)) {
16995 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16996 /* specify the DAC as the extra output */
f12ab1e0 16997 if (!spec->multiout.hp_nid)
f32610ed
JS
16998 spec->multiout.hp_nid = nid_v;
16999 else
17000 spec->multiout.extra_out_nid[0] = nid_v;
17001 /* control HP volume/switch on the output mixer amp */
17002 nid_v = alc861vd_idx_to_mixer_vol(
17003 alc880_fixed_pin_idx(pin));
17004 nid_s = alc861vd_idx_to_mixer_switch(
17005 alc880_fixed_pin_idx(pin));
17006
0afe5f89 17007 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17008 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17009 if (err < 0)
f32610ed 17010 return err;
0afe5f89 17011 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17012 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17013 if (err < 0)
f32610ed
JS
17014 return err;
17015 } else if (alc880_is_multi_pin(pin)) {
17016 /* set manual connection */
17017 /* we have only a switch on HP-out PIN */
0afe5f89 17018 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17019 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17020 if (err < 0)
f32610ed
JS
17021 return err;
17022 }
17023 return 0;
17024}
17025
17026/* parse the BIOS configuration and set up the alc_spec
17027 * return 1 if successful, 0 if the proper config is not found,
17028 * or a negative error code
17029 * Based on ALC880 version - had to change it to override
17030 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17031static int alc861vd_parse_auto_config(struct hda_codec *codec)
17032{
17033 struct alc_spec *spec = codec->spec;
17034 int err;
17035 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17036
f12ab1e0
TI
17037 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17038 alc861vd_ignore);
17039 if (err < 0)
f32610ed 17040 return err;
f12ab1e0 17041 if (!spec->autocfg.line_outs)
f32610ed
JS
17042 return 0; /* can't find valid BIOS pin config */
17043
f12ab1e0
TI
17044 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17045 if (err < 0)
17046 return err;
17047 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17048 if (err < 0)
17049 return err;
17050 err = alc861vd_auto_create_extra_out(spec,
17051 spec->autocfg.speaker_pins[0],
17052 "Speaker");
17053 if (err < 0)
17054 return err;
17055 err = alc861vd_auto_create_extra_out(spec,
17056 spec->autocfg.hp_pins[0],
17057 "Headphone");
17058 if (err < 0)
17059 return err;
05f5f477 17060 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17061 if (err < 0)
f32610ed
JS
17062 return err;
17063
17064 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17065
757899ac 17066 alc_auto_parse_digital(codec);
f32610ed 17067
603c4019 17068 if (spec->kctls.list)
d88897ea 17069 add_mixer(spec, spec->kctls.list);
f32610ed 17070
d88897ea 17071 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17072
17073 spec->num_mux_defs = 1;
61b9b9b1 17074 spec->input_mux = &spec->private_imux[0];
f32610ed 17075
776e184e
TI
17076 err = alc_auto_add_mic_boost(codec);
17077 if (err < 0)
17078 return err;
17079
6227cdce 17080 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17081
f32610ed
JS
17082 return 1;
17083}
17084
17085/* additional initialization for auto-configuration model */
17086static void alc861vd_auto_init(struct hda_codec *codec)
17087{
f6c7e546 17088 struct alc_spec *spec = codec->spec;
f32610ed
JS
17089 alc861vd_auto_init_multi_out(codec);
17090 alc861vd_auto_init_hp_out(codec);
17091 alc861vd_auto_init_analog_input(codec);
f511b01c 17092 alc861vd_auto_init_input_src(codec);
757899ac 17093 alc_auto_init_digital(codec);
f6c7e546 17094 if (spec->unsol_event)
7fb0d78f 17095 alc_inithook(codec);
f32610ed
JS
17096}
17097
f8f25ba3
TI
17098enum {
17099 ALC660VD_FIX_ASUS_GPIO1
17100};
17101
17102/* reset GPIO1 */
f8f25ba3
TI
17103static const struct alc_fixup alc861vd_fixups[] = {
17104 [ALC660VD_FIX_ASUS_GPIO1] = {
73413b12
TI
17105 .verbs = (const struct hda_verb[]) {
17106 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17107 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17108 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17109 { }
17110 }
f8f25ba3
TI
17111 },
17112};
17113
17114static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17115 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17116 {}
17117};
17118
f32610ed
JS
17119static int patch_alc861vd(struct hda_codec *codec)
17120{
17121 struct alc_spec *spec;
17122 int err, board_config;
17123
17124 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17125 if (spec == NULL)
17126 return -ENOMEM;
17127
17128 codec->spec = spec;
17129
17130 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17131 alc861vd_models,
17132 alc861vd_cfg_tbl);
17133
17134 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17135 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17136 codec->chip_name);
f32610ed
JS
17137 board_config = ALC861VD_AUTO;
17138 }
17139
7fa90e87
TI
17140 if (board_config == ALC861VD_AUTO)
17141 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 17142
f32610ed
JS
17143 if (board_config == ALC861VD_AUTO) {
17144 /* automatic parse from the BIOS config */
17145 err = alc861vd_parse_auto_config(codec);
17146 if (err < 0) {
17147 alc_free(codec);
17148 return err;
f12ab1e0 17149 } else if (!err) {
f32610ed
JS
17150 printk(KERN_INFO
17151 "hda_codec: Cannot set up configuration "
17152 "from BIOS. Using base mode...\n");
17153 board_config = ALC861VD_3ST;
17154 }
17155 }
17156
680cd536
KK
17157 err = snd_hda_attach_beep_device(codec, 0x23);
17158 if (err < 0) {
17159 alc_free(codec);
17160 return err;
17161 }
17162
f32610ed 17163 if (board_config != ALC861VD_AUTO)
e9c364c0 17164 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17165
2f893286 17166 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17167 /* always turn on EAPD */
d88897ea 17168 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17169 }
17170
f32610ed
JS
17171 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17172 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17173
f32610ed
JS
17174 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17175 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17176
dd704698
TI
17177 if (!spec->adc_nids) {
17178 spec->adc_nids = alc861vd_adc_nids;
17179 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17180 }
17181 if (!spec->capsrc_nids)
17182 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17183
b59bdf3b 17184 set_capture_mixer(codec);
45bdd1c1 17185 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17186
2134ea4f
TI
17187 spec->vmaster_nid = 0x02;
17188
7fa90e87
TI
17189 if (board_config == ALC861VD_AUTO)
17190 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
17191
f32610ed
JS
17192 codec->patch_ops = alc_patch_ops;
17193
17194 if (board_config == ALC861VD_AUTO)
17195 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17196#ifdef CONFIG_SND_HDA_POWER_SAVE
17197 if (!spec->loopback.amplist)
17198 spec->loopback.amplist = alc861vd_loopbacks;
17199#endif
f32610ed
JS
17200
17201 return 0;
17202}
17203
bc9f98a9
KY
17204/*
17205 * ALC662 support
17206 *
17207 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17208 * configuration. Each pin widget can choose any input DACs and a mixer.
17209 * Each ADC is connected from a mixer of all inputs. This makes possible
17210 * 6-channel independent captures.
17211 *
17212 * In addition, an independent DAC for the multi-playback (not used in this
17213 * driver yet).
17214 */
17215#define ALC662_DIGOUT_NID 0x06
17216#define ALC662_DIGIN_NID 0x0a
17217
17218static hda_nid_t alc662_dac_nids[4] = {
17219 /* front, rear, clfe, rear_surr */
17220 0x02, 0x03, 0x04
17221};
17222
622e84cd
KY
17223static hda_nid_t alc272_dac_nids[2] = {
17224 0x02, 0x03
17225};
17226
b59bdf3b 17227static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17228 /* ADC1-2 */
b59bdf3b 17229 0x09, 0x08
bc9f98a9 17230};
e1406348 17231
622e84cd
KY
17232static hda_nid_t alc272_adc_nids[1] = {
17233 /* ADC1-2 */
17234 0x08,
17235};
17236
b59bdf3b 17237static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17238static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17239
e1406348 17240
bc9f98a9
KY
17241/* input MUX */
17242/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17243static struct hda_input_mux alc662_capture_source = {
17244 .num_items = 4,
17245 .items = {
17246 { "Mic", 0x0 },
17247 { "Front Mic", 0x1 },
17248 { "Line", 0x2 },
17249 { "CD", 0x4 },
17250 },
17251};
17252
17253static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17254 .num_items = 2,
17255 .items = {
17256 { "Mic", 0x1 },
17257 { "Line", 0x2 },
17258 },
17259};
291702f0 17260
6dda9f4a
KY
17261static struct hda_input_mux alc663_capture_source = {
17262 .num_items = 3,
17263 .items = {
17264 { "Mic", 0x0 },
17265 { "Front Mic", 0x1 },
17266 { "Line", 0x2 },
17267 },
17268};
17269
4f5d1706 17270#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17271static struct hda_input_mux alc272_nc10_capture_source = {
17272 .num_items = 16,
17273 .items = {
17274 { "Autoselect Mic", 0x0 },
17275 { "Internal Mic", 0x1 },
17276 { "In-0x02", 0x2 },
17277 { "In-0x03", 0x3 },
17278 { "In-0x04", 0x4 },
17279 { "In-0x05", 0x5 },
17280 { "In-0x06", 0x6 },
17281 { "In-0x07", 0x7 },
17282 { "In-0x08", 0x8 },
17283 { "In-0x09", 0x9 },
17284 { "In-0x0a", 0x0a },
17285 { "In-0x0b", 0x0b },
17286 { "In-0x0c", 0x0c },
17287 { "In-0x0d", 0x0d },
17288 { "In-0x0e", 0x0e },
17289 { "In-0x0f", 0x0f },
17290 },
17291};
17292#endif
17293
bc9f98a9
KY
17294/*
17295 * 2ch mode
17296 */
17297static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17298 { 2, NULL }
17299};
17300
17301/*
17302 * 2ch mode
17303 */
17304static struct hda_verb alc662_3ST_ch2_init[] = {
17305 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17306 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17307 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17308 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17309 { } /* end */
17310};
17311
17312/*
17313 * 6ch mode
17314 */
17315static struct hda_verb alc662_3ST_ch6_init[] = {
17316 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17317 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17318 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17319 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17320 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17321 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17322 { } /* end */
17323};
17324
17325static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17326 { 2, alc662_3ST_ch2_init },
17327 { 6, alc662_3ST_ch6_init },
17328};
17329
17330/*
17331 * 2ch mode
17332 */
17333static struct hda_verb alc662_sixstack_ch6_init[] = {
17334 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17335 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17336 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17337 { } /* end */
17338};
17339
17340/*
17341 * 6ch mode
17342 */
17343static struct hda_verb alc662_sixstack_ch8_init[] = {
17344 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17345 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17346 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17347 { } /* end */
17348};
17349
17350static struct hda_channel_mode alc662_5stack_modes[2] = {
17351 { 2, alc662_sixstack_ch6_init },
17352 { 6, alc662_sixstack_ch8_init },
17353};
17354
17355/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17356 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17357 */
17358
17359static struct snd_kcontrol_new alc662_base_mixer[] = {
17360 /* output mixer control */
17361 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17362 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17363 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17364 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17365 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17366 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17367 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17368 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17369 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17370
17371 /*Input mixer control */
17372 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17373 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17374 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17375 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17376 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17377 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17378 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17379 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17380 { } /* end */
17381};
17382
17383static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17384 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17385 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17386 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17387 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17388 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17389 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17390 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17391 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17392 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17393 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17394 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17395 { } /* end */
17396};
17397
17398static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17399 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17400 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17401 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17402 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17403 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17404 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17405 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17406 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17407 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17408 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17409 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17410 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17411 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17413 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17414 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17415 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17416 { } /* end */
17417};
17418
17419static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17420 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17421 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17422 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17423 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17424 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17425 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17426 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17428 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17429 { } /* end */
17430};
17431
291702f0 17432static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17433 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17434 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
17435
17436 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17437 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17438 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17439
17440 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17441 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17442 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17443 { } /* end */
17444};
17445
8c427226 17446static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17447 ALC262_HIPPO_MASTER_SWITCH,
17448 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17449 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17450 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17451 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17452 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17453 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17454 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17455 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17456 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17457 { } /* end */
17458};
17459
f1d4e28b
KY
17460static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17461 .ops = &snd_hda_bind_vol,
17462 .values = {
17463 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17464 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17465 0
17466 },
17467};
17468
17469static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17470 .ops = &snd_hda_bind_sw,
17471 .values = {
17472 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17473 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17474 0
17475 },
17476};
17477
6dda9f4a 17478static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17479 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17480 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17481 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17482 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17483 { } /* end */
17484};
17485
17486static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17487 .ops = &snd_hda_bind_sw,
17488 .values = {
17489 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17490 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17491 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17492 0
17493 },
17494};
17495
17496static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17497 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17498 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17500 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17501 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17502 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17503
17504 { } /* end */
17505};
17506
17507static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17508 .ops = &snd_hda_bind_sw,
17509 .values = {
17510 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17511 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17512 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17513 0
17514 },
17515};
17516
17517static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17518 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17519 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17520 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17521 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17522 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17523 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17524 { } /* end */
17525};
17526
17527static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17528 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17529 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17530 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17531 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17532 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17533 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17534 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17535 { } /* end */
17536};
17537
17538static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17539 .ops = &snd_hda_bind_vol,
17540 .values = {
17541 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17542 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17543 0
17544 },
17545};
17546
17547static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17548 .ops = &snd_hda_bind_sw,
17549 .values = {
17550 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17551 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17552 0
17553 },
17554};
17555
17556static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17557 HDA_BIND_VOL("Master Playback Volume",
17558 &alc663_asus_two_bind_master_vol),
17559 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17560 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17561 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17562 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17563 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17564 { } /* end */
17565};
17566
17567static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17568 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17569 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17570 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17571 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17572 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17574 { } /* end */
17575};
17576
17577static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17578 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17579 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17580 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17581 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17582 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17583
17584 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17585 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17586 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17587 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17588 { } /* end */
17589};
17590
17591static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17592 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17593 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17594 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17595
17596 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17597 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17598 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17599 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17600 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17601 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17602 { } /* end */
17603};
17604
ebb83eeb
KY
17605static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17606 .ops = &snd_hda_bind_sw,
17607 .values = {
17608 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17609 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17610 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17611 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17612 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17613 0
17614 },
17615};
17616
17617static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17618 .ops = &snd_hda_bind_sw,
17619 .values = {
17620 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17621 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17622 0
17623 },
17624};
17625
17626static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17627 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17628 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17629 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17630 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17631 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17632 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17633 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17636 { } /* end */
17637};
17638
17639static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17640 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17641 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17642 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17643 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17644 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17645 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17646 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17647 { } /* end */
17648};
17649
17650
bc9f98a9
KY
17651static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17652 {
17653 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17654 .name = "Channel Mode",
17655 .info = alc_ch_mode_info,
17656 .get = alc_ch_mode_get,
17657 .put = alc_ch_mode_put,
17658 },
17659 { } /* end */
17660};
17661
17662static struct hda_verb alc662_init_verbs[] = {
17663 /* ADC: mute amp left and right */
17664 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17665 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17666
b60dd394
KY
17667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17668 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17669 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17670 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17671 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17672 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17673
17674 /* Front Pin: output 0 (0x0c) */
17675 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17676 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17677
17678 /* Rear Pin: output 1 (0x0d) */
17679 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17680 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17681
17682 /* CLFE Pin: output 2 (0x0e) */
17683 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17684 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17685
17686 /* Mic (rear) pin: input vref at 80% */
17687 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17688 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17689 /* Front Mic pin: input vref at 80% */
17690 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17691 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17692 /* Line In pin: input */
17693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17695 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17696 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17697 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17698 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17699 /* CD pin widget for input */
17700 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17701
17702 /* FIXME: use matrix-type input source selection */
17703 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17704 /* Input mixer */
17705 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17706 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17707
17708 /* always trun on EAPD */
17709 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17710 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17711
bc9f98a9
KY
17712 { }
17713};
17714
cec27c89
KY
17715static struct hda_verb alc663_init_verbs[] = {
17716 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17717 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17718 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17719 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17720 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17721 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17722 { }
17723};
17724
17725static struct hda_verb alc272_init_verbs[] = {
17726 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17727 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17728 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17729 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17730 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17731 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17732 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17733 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17734 { }
17735};
17736
bc9f98a9
KY
17737static struct hda_verb alc662_sue_init_verbs[] = {
17738 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17739 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17740 {}
17741};
17742
17743static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17744 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17745 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17746 {}
bc9f98a9
KY
17747};
17748
8c427226
KY
17749/* Set Unsolicited Event*/
17750static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17751 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17752 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17753 {}
17754};
17755
6dda9f4a 17756static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17757 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17758 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17759 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17760 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17761 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17762 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17763 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17764 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17765 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17766 {}
17767};
17768
17769static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17770 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17771 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17772 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17774 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17775 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17776 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17777 {}
17778};
17779
17780static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17781 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17782 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17783 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17784 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17785 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17786 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17787 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17788 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17789 {}
17790};
6dda9f4a 17791
f1d4e28b
KY
17792static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17793 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17794 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17795 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17796 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17797 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17798 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17799 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17800 {}
17801};
6dda9f4a 17802
f1d4e28b
KY
17803static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17804 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17805 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17806 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17807 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17808 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17809 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17810 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17811 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17812 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17813 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17814 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17815 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17816 {}
17817};
17818
17819static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17820 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17821 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17822 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17823 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17824 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17826 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17828 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17829 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17830 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17831 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17832 {}
17833};
17834
17835static struct hda_verb alc663_g71v_init_verbs[] = {
17836 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17837 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17838 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17839
17840 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17841 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17842 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17843
17844 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17845 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17846 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17847 {}
17848};
17849
17850static struct hda_verb alc663_g50v_init_verbs[] = {
17851 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17852 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17853 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17854
17855 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17856 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17857 {}
17858};
17859
f1d4e28b
KY
17860static struct hda_verb alc662_ecs_init_verbs[] = {
17861 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17862 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17863 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17864 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17865 {}
17866};
17867
622e84cd
KY
17868static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17869 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17870 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17872 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17873 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17874 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17875 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17876 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17877 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17878 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17879 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17880 {}
17881};
17882
17883static struct hda_verb alc272_dell_init_verbs[] = {
17884 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17885 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17886 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17887 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17888 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17889 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17890 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17891 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17892 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17893 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17894 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17895 {}
17896};
17897
ebb83eeb
KY
17898static struct hda_verb alc663_mode7_init_verbs[] = {
17899 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17900 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17901 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17902 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17903 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17904 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17905 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17906 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17907 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17908 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17909 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17911 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17912 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17913 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17914 {}
17915};
17916
17917static struct hda_verb alc663_mode8_init_verbs[] = {
17918 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17919 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17920 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17921 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17922 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17923 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17924 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17925 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17926 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17927 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17928 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17931 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17932 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17933 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17934 {}
17935};
17936
f1d4e28b
KY
17937static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17938 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17939 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17940 { } /* end */
17941};
17942
622e84cd
KY
17943static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17944 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17945 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17946 { } /* end */
17947};
17948
bc9f98a9
KY
17949static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17950{
17951 unsigned int present;
f12ab1e0 17952 unsigned char bits;
bc9f98a9 17953
864f92be 17954 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17955 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17956
47fd830a
TI
17957 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17958 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17959}
17960
17961static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17962{
17963 unsigned int present;
f12ab1e0 17964 unsigned char bits;
bc9f98a9 17965
864f92be 17966 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17967 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17968
47fd830a
TI
17969 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17970 HDA_AMP_MUTE, bits);
17971 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17972 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17973}
17974
17975static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17976 unsigned int res)
17977{
17978 if ((res >> 26) == ALC880_HP_EVENT)
17979 alc662_lenovo_101e_all_automute(codec);
17980 if ((res >> 26) == ALC880_FRONT_EVENT)
17981 alc662_lenovo_101e_ispeaker_automute(codec);
17982}
17983
291702f0
KY
17984/* unsolicited event for HP jack sensing */
17985static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17986 unsigned int res)
17987{
291702f0 17988 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17989 alc_mic_automute(codec);
42171c17
TI
17990 else
17991 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17992}
17993
4f5d1706
TI
17994static void alc662_eeepc_setup(struct hda_codec *codec)
17995{
17996 struct alc_spec *spec = codec->spec;
17997
17998 alc262_hippo1_setup(codec);
17999 spec->ext_mic.pin = 0x18;
18000 spec->ext_mic.mux_idx = 0;
18001 spec->int_mic.pin = 0x19;
18002 spec->int_mic.mux_idx = 1;
18003 spec->auto_mic = 1;
18004}
18005
291702f0
KY
18006static void alc662_eeepc_inithook(struct hda_codec *codec)
18007{
4f5d1706
TI
18008 alc262_hippo_automute(codec);
18009 alc_mic_automute(codec);
291702f0
KY
18010}
18011
4f5d1706 18012static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18013{
42171c17
TI
18014 struct alc_spec *spec = codec->spec;
18015
18016 spec->autocfg.hp_pins[0] = 0x14;
18017 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18018}
18019
4f5d1706
TI
18020#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18021
6dda9f4a
KY
18022static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18023{
18024 unsigned int present;
18025 unsigned char bits;
18026
864f92be 18027 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18028 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18029 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18030 HDA_AMP_MUTE, bits);
f1d4e28b 18031 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18032 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18033}
18034
18035static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18036{
18037 unsigned int present;
18038 unsigned char bits;
18039
864f92be 18040 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18041 bits = present ? HDA_AMP_MUTE : 0;
18042 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18043 HDA_AMP_MUTE, bits);
f1d4e28b 18044 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18045 HDA_AMP_MUTE, bits);
f1d4e28b 18046 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18047 HDA_AMP_MUTE, bits);
f1d4e28b 18048 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18049 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18050}
18051
18052static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18053{
18054 unsigned int present;
18055 unsigned char bits;
18056
864f92be 18057 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18058 bits = present ? HDA_AMP_MUTE : 0;
18059 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18060 HDA_AMP_MUTE, bits);
f1d4e28b 18061 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18062 HDA_AMP_MUTE, bits);
f1d4e28b 18063 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18064 HDA_AMP_MUTE, bits);
f1d4e28b 18065 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18066 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18067}
18068
18069static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18070{
18071 unsigned int present;
18072 unsigned char bits;
18073
864f92be 18074 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18075 bits = present ? 0 : PIN_OUT;
18076 snd_hda_codec_write(codec, 0x14, 0,
18077 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18078}
18079
18080static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18081{
18082 unsigned int present1, present2;
18083
864f92be
WF
18084 present1 = snd_hda_jack_detect(codec, 0x21);
18085 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18086
18087 if (present1 || present2) {
18088 snd_hda_codec_write_cache(codec, 0x14, 0,
18089 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18090 } else {
18091 snd_hda_codec_write_cache(codec, 0x14, 0,
18092 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18093 }
18094}
18095
18096static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18097{
18098 unsigned int present1, present2;
18099
864f92be
WF
18100 present1 = snd_hda_jack_detect(codec, 0x1b);
18101 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18102
18103 if (present1 || present2) {
18104 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18105 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18106 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18107 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18108 } else {
18109 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18110 HDA_AMP_MUTE, 0);
f1d4e28b 18111 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18112 HDA_AMP_MUTE, 0);
f1d4e28b 18113 }
6dda9f4a
KY
18114}
18115
ebb83eeb
KY
18116static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18117{
18118 unsigned int present1, present2;
18119
18120 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18121 AC_VERB_GET_PIN_SENSE, 0)
18122 & AC_PINSENSE_PRESENCE;
18123 present2 = snd_hda_codec_read(codec, 0x21, 0,
18124 AC_VERB_GET_PIN_SENSE, 0)
18125 & AC_PINSENSE_PRESENCE;
18126
18127 if (present1 || present2) {
18128 snd_hda_codec_write_cache(codec, 0x14, 0,
18129 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18130 snd_hda_codec_write_cache(codec, 0x17, 0,
18131 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18132 } else {
18133 snd_hda_codec_write_cache(codec, 0x14, 0,
18134 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18135 snd_hda_codec_write_cache(codec, 0x17, 0,
18136 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18137 }
18138}
18139
18140static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18141{
18142 unsigned int present1, present2;
18143
18144 present1 = snd_hda_codec_read(codec, 0x21, 0,
18145 AC_VERB_GET_PIN_SENSE, 0)
18146 & AC_PINSENSE_PRESENCE;
18147 present2 = snd_hda_codec_read(codec, 0x15, 0,
18148 AC_VERB_GET_PIN_SENSE, 0)
18149 & AC_PINSENSE_PRESENCE;
18150
18151 if (present1 || present2) {
18152 snd_hda_codec_write_cache(codec, 0x14, 0,
18153 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18154 snd_hda_codec_write_cache(codec, 0x17, 0,
18155 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18156 } else {
18157 snd_hda_codec_write_cache(codec, 0x14, 0,
18158 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18159 snd_hda_codec_write_cache(codec, 0x17, 0,
18160 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18161 }
18162}
18163
6dda9f4a
KY
18164static void alc663_m51va_unsol_event(struct hda_codec *codec,
18165 unsigned int res)
18166{
18167 switch (res >> 26) {
18168 case ALC880_HP_EVENT:
18169 alc663_m51va_speaker_automute(codec);
18170 break;
18171 case ALC880_MIC_EVENT:
4f5d1706 18172 alc_mic_automute(codec);
6dda9f4a
KY
18173 break;
18174 }
18175}
18176
4f5d1706
TI
18177static void alc663_m51va_setup(struct hda_codec *codec)
18178{
18179 struct alc_spec *spec = codec->spec;
18180 spec->ext_mic.pin = 0x18;
18181 spec->ext_mic.mux_idx = 0;
18182 spec->int_mic.pin = 0x12;
ebb83eeb 18183 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18184 spec->auto_mic = 1;
18185}
18186
6dda9f4a
KY
18187static void alc663_m51va_inithook(struct hda_codec *codec)
18188{
18189 alc663_m51va_speaker_automute(codec);
4f5d1706 18190 alc_mic_automute(codec);
6dda9f4a
KY
18191}
18192
f1d4e28b 18193/* ***************** Mode1 ******************************/
4f5d1706 18194#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18195
18196static void alc663_mode1_setup(struct hda_codec *codec)
18197{
18198 struct alc_spec *spec = codec->spec;
18199 spec->ext_mic.pin = 0x18;
18200 spec->ext_mic.mux_idx = 0;
18201 spec->int_mic.pin = 0x19;
18202 spec->int_mic.mux_idx = 1;
18203 spec->auto_mic = 1;
18204}
18205
4f5d1706 18206#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18207
f1d4e28b
KY
18208/* ***************** Mode2 ******************************/
18209static void alc662_mode2_unsol_event(struct hda_codec *codec,
18210 unsigned int res)
18211{
18212 switch (res >> 26) {
18213 case ALC880_HP_EVENT:
18214 alc662_f5z_speaker_automute(codec);
18215 break;
18216 case ALC880_MIC_EVENT:
4f5d1706 18217 alc_mic_automute(codec);
f1d4e28b
KY
18218 break;
18219 }
18220}
18221
ebb83eeb 18222#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18223
f1d4e28b
KY
18224static void alc662_mode2_inithook(struct hda_codec *codec)
18225{
18226 alc662_f5z_speaker_automute(codec);
4f5d1706 18227 alc_mic_automute(codec);
f1d4e28b
KY
18228}
18229/* ***************** Mode3 ******************************/
18230static void alc663_mode3_unsol_event(struct hda_codec *codec,
18231 unsigned int res)
18232{
18233 switch (res >> 26) {
18234 case ALC880_HP_EVENT:
18235 alc663_two_hp_m1_speaker_automute(codec);
18236 break;
18237 case ALC880_MIC_EVENT:
4f5d1706 18238 alc_mic_automute(codec);
f1d4e28b
KY
18239 break;
18240 }
18241}
18242
ebb83eeb 18243#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18244
f1d4e28b
KY
18245static void alc663_mode3_inithook(struct hda_codec *codec)
18246{
18247 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18248 alc_mic_automute(codec);
f1d4e28b
KY
18249}
18250/* ***************** Mode4 ******************************/
18251static void alc663_mode4_unsol_event(struct hda_codec *codec,
18252 unsigned int res)
18253{
18254 switch (res >> 26) {
18255 case ALC880_HP_EVENT:
18256 alc663_21jd_two_speaker_automute(codec);
18257 break;
18258 case ALC880_MIC_EVENT:
4f5d1706 18259 alc_mic_automute(codec);
f1d4e28b
KY
18260 break;
18261 }
18262}
18263
ebb83eeb 18264#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18265
f1d4e28b
KY
18266static void alc663_mode4_inithook(struct hda_codec *codec)
18267{
18268 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18269 alc_mic_automute(codec);
f1d4e28b
KY
18270}
18271/* ***************** Mode5 ******************************/
18272static void alc663_mode5_unsol_event(struct hda_codec *codec,
18273 unsigned int res)
18274{
18275 switch (res >> 26) {
18276 case ALC880_HP_EVENT:
18277 alc663_15jd_two_speaker_automute(codec);
18278 break;
18279 case ALC880_MIC_EVENT:
4f5d1706 18280 alc_mic_automute(codec);
f1d4e28b
KY
18281 break;
18282 }
18283}
18284
ebb83eeb 18285#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18286
f1d4e28b
KY
18287static void alc663_mode5_inithook(struct hda_codec *codec)
18288{
18289 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18290 alc_mic_automute(codec);
f1d4e28b
KY
18291}
18292/* ***************** Mode6 ******************************/
18293static void alc663_mode6_unsol_event(struct hda_codec *codec,
18294 unsigned int res)
18295{
18296 switch (res >> 26) {
18297 case ALC880_HP_EVENT:
18298 alc663_two_hp_m2_speaker_automute(codec);
18299 break;
18300 case ALC880_MIC_EVENT:
4f5d1706 18301 alc_mic_automute(codec);
f1d4e28b
KY
18302 break;
18303 }
18304}
18305
ebb83eeb 18306#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18307
f1d4e28b
KY
18308static void alc663_mode6_inithook(struct hda_codec *codec)
18309{
18310 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18311 alc_mic_automute(codec);
f1d4e28b
KY
18312}
18313
ebb83eeb
KY
18314/* ***************** Mode7 ******************************/
18315static void alc663_mode7_unsol_event(struct hda_codec *codec,
18316 unsigned int res)
18317{
18318 switch (res >> 26) {
18319 case ALC880_HP_EVENT:
18320 alc663_two_hp_m7_speaker_automute(codec);
18321 break;
18322 case ALC880_MIC_EVENT:
18323 alc_mic_automute(codec);
18324 break;
18325 }
18326}
18327
18328#define alc663_mode7_setup alc663_mode1_setup
18329
18330static void alc663_mode7_inithook(struct hda_codec *codec)
18331{
18332 alc663_two_hp_m7_speaker_automute(codec);
18333 alc_mic_automute(codec);
18334}
18335
18336/* ***************** Mode8 ******************************/
18337static void alc663_mode8_unsol_event(struct hda_codec *codec,
18338 unsigned int res)
18339{
18340 switch (res >> 26) {
18341 case ALC880_HP_EVENT:
18342 alc663_two_hp_m8_speaker_automute(codec);
18343 break;
18344 case ALC880_MIC_EVENT:
18345 alc_mic_automute(codec);
18346 break;
18347 }
18348}
18349
18350#define alc663_mode8_setup alc663_m51va_setup
18351
18352static void alc663_mode8_inithook(struct hda_codec *codec)
18353{
18354 alc663_two_hp_m8_speaker_automute(codec);
18355 alc_mic_automute(codec);
18356}
18357
6dda9f4a
KY
18358static void alc663_g71v_hp_automute(struct hda_codec *codec)
18359{
18360 unsigned int present;
18361 unsigned char bits;
18362
864f92be 18363 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18364 bits = present ? HDA_AMP_MUTE : 0;
18365 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18366 HDA_AMP_MUTE, bits);
18367 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18368 HDA_AMP_MUTE, bits);
18369}
18370
18371static void alc663_g71v_front_automute(struct hda_codec *codec)
18372{
18373 unsigned int present;
18374 unsigned char bits;
18375
864f92be 18376 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18377 bits = present ? HDA_AMP_MUTE : 0;
18378 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18379 HDA_AMP_MUTE, bits);
18380}
18381
18382static void alc663_g71v_unsol_event(struct hda_codec *codec,
18383 unsigned int res)
18384{
18385 switch (res >> 26) {
18386 case ALC880_HP_EVENT:
18387 alc663_g71v_hp_automute(codec);
18388 break;
18389 case ALC880_FRONT_EVENT:
18390 alc663_g71v_front_automute(codec);
18391 break;
18392 case ALC880_MIC_EVENT:
4f5d1706 18393 alc_mic_automute(codec);
6dda9f4a
KY
18394 break;
18395 }
18396}
18397
4f5d1706
TI
18398#define alc663_g71v_setup alc663_m51va_setup
18399
6dda9f4a
KY
18400static void alc663_g71v_inithook(struct hda_codec *codec)
18401{
18402 alc663_g71v_front_automute(codec);
18403 alc663_g71v_hp_automute(codec);
4f5d1706 18404 alc_mic_automute(codec);
6dda9f4a
KY
18405}
18406
18407static void alc663_g50v_unsol_event(struct hda_codec *codec,
18408 unsigned int res)
18409{
18410 switch (res >> 26) {
18411 case ALC880_HP_EVENT:
18412 alc663_m51va_speaker_automute(codec);
18413 break;
18414 case ALC880_MIC_EVENT:
4f5d1706 18415 alc_mic_automute(codec);
6dda9f4a
KY
18416 break;
18417 }
18418}
18419
4f5d1706
TI
18420#define alc663_g50v_setup alc663_m51va_setup
18421
6dda9f4a
KY
18422static void alc663_g50v_inithook(struct hda_codec *codec)
18423{
18424 alc663_m51va_speaker_automute(codec);
4f5d1706 18425 alc_mic_automute(codec);
6dda9f4a
KY
18426}
18427
f1d4e28b
KY
18428static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18429 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18430 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
18431
18432 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18433 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18434 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18435
18436 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18437 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18438 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18439 { } /* end */
18440};
18441
9541ba1d
CP
18442static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18443 /* Master Playback automatically created from Speaker and Headphone */
18444 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18445 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18446 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18447 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18448
18449 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18450 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18451 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18452
18453 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18454 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18455 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18456 { } /* end */
18457};
18458
cb53c626
TI
18459#ifdef CONFIG_SND_HDA_POWER_SAVE
18460#define alc662_loopbacks alc880_loopbacks
18461#endif
18462
bc9f98a9 18463
def319f9 18464/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18465#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18466#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18467#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18468#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18469
18470/*
18471 * configuration and preset
18472 */
18473static const char *alc662_models[ALC662_MODEL_LAST] = {
18474 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18475 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18476 [ALC662_3ST_6ch] = "3stack-6ch",
18477 [ALC662_5ST_DIG] = "6stack-dig",
18478 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18479 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18480 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18481 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18482 [ALC663_ASUS_M51VA] = "m51va",
18483 [ALC663_ASUS_G71V] = "g71v",
18484 [ALC663_ASUS_H13] = "h13",
18485 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18486 [ALC663_ASUS_MODE1] = "asus-mode1",
18487 [ALC662_ASUS_MODE2] = "asus-mode2",
18488 [ALC663_ASUS_MODE3] = "asus-mode3",
18489 [ALC663_ASUS_MODE4] = "asus-mode4",
18490 [ALC663_ASUS_MODE5] = "asus-mode5",
18491 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18492 [ALC663_ASUS_MODE7] = "asus-mode7",
18493 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18494 [ALC272_DELL] = "dell",
18495 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18496 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18497 [ALC662_AUTO] = "auto",
18498};
18499
18500static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18501 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18502 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18503 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18504 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18505 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18506 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18507 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18508 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18509 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18510 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18511 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18512 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18513 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18514 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18515 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18516 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18517 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18518 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18519 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18520 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18521 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18522 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18523 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18524 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18525 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18526 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18527 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18528 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18529 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18530 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18531 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18532 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18533 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18534 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18535 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18536 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18537 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18538 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18539 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18540 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18541 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18542 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18543 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18544 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18545 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18546 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18547 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18548 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18549 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18550 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18551 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18552 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18553 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18554 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18555 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18556 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18557 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18558 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18559 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18560 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18561 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18562 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18563 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18564 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18565 ALC662_3ST_6ch_DIG),
4dee8baa 18566 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18567 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18568 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18569 ALC662_3ST_6ch_DIG),
6227cdce 18570 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18571 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18572 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18573 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18574 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18575 ALC662_3ST_6ch_DIG),
dea0a509
TI
18576 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18577 ALC663_ASUS_H13),
bc9f98a9
KY
18578 {}
18579};
18580
18581static struct alc_config_preset alc662_presets[] = {
18582 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18583 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18584 .init_verbs = { alc662_init_verbs },
18585 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18586 .dac_nids = alc662_dac_nids,
18587 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18588 .dig_in_nid = ALC662_DIGIN_NID,
18589 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18590 .channel_mode = alc662_3ST_2ch_modes,
18591 .input_mux = &alc662_capture_source,
18592 },
18593 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18594 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18595 .init_verbs = { alc662_init_verbs },
18596 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18597 .dac_nids = alc662_dac_nids,
18598 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18599 .dig_in_nid = ALC662_DIGIN_NID,
18600 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18601 .channel_mode = alc662_3ST_6ch_modes,
18602 .need_dac_fix = 1,
18603 .input_mux = &alc662_capture_source,
f12ab1e0 18604 },
bc9f98a9 18605 [ALC662_3ST_6ch] = {
f9e336f6 18606 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18607 .init_verbs = { alc662_init_verbs },
18608 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18609 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18610 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18611 .channel_mode = alc662_3ST_6ch_modes,
18612 .need_dac_fix = 1,
18613 .input_mux = &alc662_capture_source,
f12ab1e0 18614 },
bc9f98a9 18615 [ALC662_5ST_DIG] = {
f9e336f6 18616 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18617 .init_verbs = { alc662_init_verbs },
18618 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18619 .dac_nids = alc662_dac_nids,
18620 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18621 .dig_in_nid = ALC662_DIGIN_NID,
18622 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18623 .channel_mode = alc662_5stack_modes,
18624 .input_mux = &alc662_capture_source,
18625 },
18626 [ALC662_LENOVO_101E] = {
f9e336f6 18627 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18628 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18629 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18630 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18631 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18632 .channel_mode = alc662_3ST_2ch_modes,
18633 .input_mux = &alc662_lenovo_101e_capture_source,
18634 .unsol_event = alc662_lenovo_101e_unsol_event,
18635 .init_hook = alc662_lenovo_101e_all_automute,
18636 },
291702f0 18637 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18638 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18639 .init_verbs = { alc662_init_verbs,
18640 alc662_eeepc_sue_init_verbs },
18641 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18642 .dac_nids = alc662_dac_nids,
291702f0
KY
18643 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18644 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18645 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18646 .setup = alc662_eeepc_setup,
291702f0
KY
18647 .init_hook = alc662_eeepc_inithook,
18648 },
8c427226 18649 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18650 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18651 alc662_chmode_mixer },
18652 .init_verbs = { alc662_init_verbs,
18653 alc662_eeepc_ep20_sue_init_verbs },
18654 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18655 .dac_nids = alc662_dac_nids,
8c427226
KY
18656 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18657 .channel_mode = alc662_3ST_6ch_modes,
18658 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18659 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18660 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18661 .init_hook = alc662_eeepc_ep20_inithook,
18662 },
f1d4e28b 18663 [ALC662_ECS] = {
f9e336f6 18664 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18665 .init_verbs = { alc662_init_verbs,
18666 alc662_ecs_init_verbs },
18667 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18668 .dac_nids = alc662_dac_nids,
18669 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18670 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18671 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18672 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18673 .init_hook = alc662_eeepc_inithook,
18674 },
6dda9f4a 18675 [ALC663_ASUS_M51VA] = {
f9e336f6 18676 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18677 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18678 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18679 .dac_nids = alc662_dac_nids,
18680 .dig_out_nid = ALC662_DIGOUT_NID,
18681 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18682 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18683 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18684 .setup = alc663_m51va_setup,
6dda9f4a
KY
18685 .init_hook = alc663_m51va_inithook,
18686 },
18687 [ALC663_ASUS_G71V] = {
f9e336f6 18688 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18689 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18690 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18691 .dac_nids = alc662_dac_nids,
18692 .dig_out_nid = ALC662_DIGOUT_NID,
18693 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18694 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18695 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18696 .setup = alc663_g71v_setup,
6dda9f4a
KY
18697 .init_hook = alc663_g71v_inithook,
18698 },
18699 [ALC663_ASUS_H13] = {
f9e336f6 18700 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18701 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18702 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18703 .dac_nids = alc662_dac_nids,
18704 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18705 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18706 .unsol_event = alc663_m51va_unsol_event,
18707 .init_hook = alc663_m51va_inithook,
18708 },
18709 [ALC663_ASUS_G50V] = {
f9e336f6 18710 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18711 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18712 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18713 .dac_nids = alc662_dac_nids,
18714 .dig_out_nid = ALC662_DIGOUT_NID,
18715 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18716 .channel_mode = alc662_3ST_6ch_modes,
18717 .input_mux = &alc663_capture_source,
18718 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18719 .setup = alc663_g50v_setup,
6dda9f4a
KY
18720 .init_hook = alc663_g50v_inithook,
18721 },
f1d4e28b 18722 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18723 .mixers = { alc663_m51va_mixer },
18724 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18725 .init_verbs = { alc662_init_verbs,
18726 alc663_21jd_amic_init_verbs },
18727 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18728 .hp_nid = 0x03,
18729 .dac_nids = alc662_dac_nids,
18730 .dig_out_nid = ALC662_DIGOUT_NID,
18731 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18732 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18733 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18734 .setup = alc663_mode1_setup,
f1d4e28b
KY
18735 .init_hook = alc663_mode1_inithook,
18736 },
18737 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18738 .mixers = { alc662_1bjd_mixer },
18739 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18740 .init_verbs = { alc662_init_verbs,
18741 alc662_1bjd_amic_init_verbs },
18742 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18743 .dac_nids = alc662_dac_nids,
18744 .dig_out_nid = ALC662_DIGOUT_NID,
18745 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18746 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18747 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18748 .setup = alc662_mode2_setup,
f1d4e28b
KY
18749 .init_hook = alc662_mode2_inithook,
18750 },
18751 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18752 .mixers = { alc663_two_hp_m1_mixer },
18753 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18754 .init_verbs = { alc662_init_verbs,
18755 alc663_two_hp_amic_m1_init_verbs },
18756 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18757 .hp_nid = 0x03,
18758 .dac_nids = alc662_dac_nids,
18759 .dig_out_nid = ALC662_DIGOUT_NID,
18760 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18761 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18762 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18763 .setup = alc663_mode3_setup,
f1d4e28b
KY
18764 .init_hook = alc663_mode3_inithook,
18765 },
18766 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18767 .mixers = { alc663_asus_21jd_clfe_mixer },
18768 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18769 .init_verbs = { alc662_init_verbs,
18770 alc663_21jd_amic_init_verbs},
18771 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18772 .hp_nid = 0x03,
18773 .dac_nids = alc662_dac_nids,
18774 .dig_out_nid = ALC662_DIGOUT_NID,
18775 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18776 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18777 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18778 .setup = alc663_mode4_setup,
f1d4e28b
KY
18779 .init_hook = alc663_mode4_inithook,
18780 },
18781 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18782 .mixers = { alc663_asus_15jd_clfe_mixer },
18783 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18784 .init_verbs = { alc662_init_verbs,
18785 alc663_15jd_amic_init_verbs },
18786 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18787 .hp_nid = 0x03,
18788 .dac_nids = alc662_dac_nids,
18789 .dig_out_nid = ALC662_DIGOUT_NID,
18790 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18791 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18792 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18793 .setup = alc663_mode5_setup,
f1d4e28b
KY
18794 .init_hook = alc663_mode5_inithook,
18795 },
18796 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18797 .mixers = { alc663_two_hp_m2_mixer },
18798 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18799 .init_verbs = { alc662_init_verbs,
18800 alc663_two_hp_amic_m2_init_verbs },
18801 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18802 .hp_nid = 0x03,
18803 .dac_nids = alc662_dac_nids,
18804 .dig_out_nid = ALC662_DIGOUT_NID,
18805 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18806 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18807 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18808 .setup = alc663_mode6_setup,
f1d4e28b
KY
18809 .init_hook = alc663_mode6_inithook,
18810 },
ebb83eeb
KY
18811 [ALC663_ASUS_MODE7] = {
18812 .mixers = { alc663_mode7_mixer },
18813 .cap_mixer = alc662_auto_capture_mixer,
18814 .init_verbs = { alc662_init_verbs,
18815 alc663_mode7_init_verbs },
18816 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18817 .hp_nid = 0x03,
18818 .dac_nids = alc662_dac_nids,
18819 .dig_out_nid = ALC662_DIGOUT_NID,
18820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18821 .channel_mode = alc662_3ST_2ch_modes,
18822 .unsol_event = alc663_mode7_unsol_event,
18823 .setup = alc663_mode7_setup,
18824 .init_hook = alc663_mode7_inithook,
18825 },
18826 [ALC663_ASUS_MODE8] = {
18827 .mixers = { alc663_mode8_mixer },
18828 .cap_mixer = alc662_auto_capture_mixer,
18829 .init_verbs = { alc662_init_verbs,
18830 alc663_mode8_init_verbs },
18831 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18832 .hp_nid = 0x03,
18833 .dac_nids = alc662_dac_nids,
18834 .dig_out_nid = ALC662_DIGOUT_NID,
18835 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18836 .channel_mode = alc662_3ST_2ch_modes,
18837 .unsol_event = alc663_mode8_unsol_event,
18838 .setup = alc663_mode8_setup,
18839 .init_hook = alc663_mode8_inithook,
18840 },
622e84cd
KY
18841 [ALC272_DELL] = {
18842 .mixers = { alc663_m51va_mixer },
18843 .cap_mixer = alc272_auto_capture_mixer,
18844 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18845 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18846 .dac_nids = alc662_dac_nids,
18847 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18848 .adc_nids = alc272_adc_nids,
18849 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18850 .capsrc_nids = alc272_capsrc_nids,
18851 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18852 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18853 .setup = alc663_m51va_setup,
622e84cd
KY
18854 .init_hook = alc663_m51va_inithook,
18855 },
18856 [ALC272_DELL_ZM1] = {
18857 .mixers = { alc663_m51va_mixer },
18858 .cap_mixer = alc662_auto_capture_mixer,
18859 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18860 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18861 .dac_nids = alc662_dac_nids,
18862 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18863 .adc_nids = alc662_adc_nids,
b59bdf3b 18864 .num_adc_nids = 1,
622e84cd
KY
18865 .capsrc_nids = alc662_capsrc_nids,
18866 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18867 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18868 .setup = alc663_m51va_setup,
622e84cd
KY
18869 .init_hook = alc663_m51va_inithook,
18870 },
9541ba1d
CP
18871 [ALC272_SAMSUNG_NC10] = {
18872 .mixers = { alc272_nc10_mixer },
18873 .init_verbs = { alc662_init_verbs,
18874 alc663_21jd_amic_init_verbs },
18875 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18876 .dac_nids = alc272_dac_nids,
18877 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18878 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18879 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18880 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18881 .setup = alc663_mode4_setup,
9541ba1d
CP
18882 .init_hook = alc663_mode4_inithook,
18883 },
bc9f98a9
KY
18884};
18885
18886
18887/*
18888 * BIOS auto configuration
18889 */
18890
7085ec12
TI
18891/* convert from MIX nid to DAC */
18892static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18893{
18894 if (nid == 0x0f)
18895 return 0x02;
18896 else if (nid >= 0x0c && nid <= 0x0e)
18897 return nid - 0x0c + 0x02;
18898 else
18899 return 0;
18900}
18901
18902/* get MIX nid connected to the given pin targeted to DAC */
18903static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18904 hda_nid_t dac)
18905{
18906 hda_nid_t mix[4];
18907 int i, num;
18908
18909 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18910 for (i = 0; i < num; i++) {
18911 if (alc662_mix_to_dac(mix[i]) == dac)
18912 return mix[i];
18913 }
18914 return 0;
18915}
18916
18917/* look for an empty DAC slot */
18918static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18919{
18920 struct alc_spec *spec = codec->spec;
18921 hda_nid_t srcs[5];
18922 int i, j, num;
18923
18924 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18925 if (num < 0)
18926 return 0;
18927 for (i = 0; i < num; i++) {
18928 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18929 if (!nid)
18930 continue;
18931 for (j = 0; j < spec->multiout.num_dacs; j++)
18932 if (spec->multiout.dac_nids[j] == nid)
18933 break;
18934 if (j >= spec->multiout.num_dacs)
18935 return nid;
18936 }
18937 return 0;
18938}
18939
18940/* fill in the dac_nids table from the parsed pin configuration */
18941static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18942 const struct auto_pin_cfg *cfg)
18943{
18944 struct alc_spec *spec = codec->spec;
18945 int i;
18946 hda_nid_t dac;
18947
18948 spec->multiout.dac_nids = spec->private_dac_nids;
18949 for (i = 0; i < cfg->line_outs; i++) {
18950 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18951 if (!dac)
18952 continue;
18953 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18954 }
18955 return 0;
18956}
18957
0afe5f89 18958static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18959 hda_nid_t nid, unsigned int chs)
18960{
0afe5f89 18961 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18962 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18963}
18964
0afe5f89 18965static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18966 hda_nid_t nid, unsigned int chs)
18967{
0afe5f89 18968 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18969 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18970}
18971
18972#define alc662_add_stereo_vol(spec, pfx, nid) \
18973 alc662_add_vol_ctl(spec, pfx, nid, 3)
18974#define alc662_add_stereo_sw(spec, pfx, nid) \
18975 alc662_add_sw_ctl(spec, pfx, nid, 3)
18976
bc9f98a9 18977/* add playback controls from the parsed DAC table */
7085ec12 18978static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18979 const struct auto_pin_cfg *cfg)
18980{
7085ec12 18981 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18982 static const char *chname[4] = {
18983 "Front", "Surround", NULL /*CLFE*/, "Side"
18984 };
7085ec12 18985 hda_nid_t nid, mix;
bc9f98a9
KY
18986 int i, err;
18987
18988 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18989 nid = spec->multiout.dac_nids[i];
18990 if (!nid)
18991 continue;
18992 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18993 if (!mix)
bc9f98a9 18994 continue;
bc9f98a9
KY
18995 if (i == 2) {
18996 /* Center/LFE */
7085ec12 18997 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18998 if (err < 0)
18999 return err;
7085ec12 19000 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19001 if (err < 0)
19002 return err;
7085ec12 19003 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19004 if (err < 0)
19005 return err;
7085ec12 19006 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19007 if (err < 0)
19008 return err;
19009 } else {
0d884cb9
TI
19010 const char *pfx;
19011 if (cfg->line_outs == 1 &&
19012 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 19013 if (cfg->hp_outs)
0d884cb9
TI
19014 pfx = "Speaker";
19015 else
19016 pfx = "PCM";
19017 } else
19018 pfx = chname[i];
7085ec12 19019 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
19020 if (err < 0)
19021 return err;
0d884cb9
TI
19022 if (cfg->line_outs == 1 &&
19023 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19024 pfx = "Speaker";
7085ec12 19025 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
19026 if (err < 0)
19027 return err;
19028 }
19029 }
19030 return 0;
19031}
19032
19033/* add playback controls for speaker and HP outputs */
7085ec12
TI
19034/* return DAC nid if any new DAC is assigned */
19035static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19036 const char *pfx)
19037{
7085ec12
TI
19038 struct alc_spec *spec = codec->spec;
19039 hda_nid_t nid, mix;
bc9f98a9 19040 int err;
bc9f98a9
KY
19041
19042 if (!pin)
19043 return 0;
7085ec12
TI
19044 nid = alc662_look_for_dac(codec, pin);
19045 if (!nid) {
7085ec12
TI
19046 /* the corresponding DAC is already occupied */
19047 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19048 return 0; /* no way */
19049 /* create a switch only */
0afe5f89 19050 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19051 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19052 }
19053
7085ec12
TI
19054 mix = alc662_dac_to_mix(codec, pin, nid);
19055 if (!mix)
19056 return 0;
19057 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19058 if (err < 0)
19059 return err;
19060 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19061 if (err < 0)
19062 return err;
19063 return nid;
bc9f98a9
KY
19064}
19065
19066/* create playback/capture controls for input pins */
05f5f477 19067#define alc662_auto_create_input_ctls \
4b7348a1 19068 alc882_auto_create_input_ctls
bc9f98a9
KY
19069
19070static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19071 hda_nid_t nid, int pin_type,
7085ec12 19072 hda_nid_t dac)
bc9f98a9 19073{
7085ec12 19074 int i, num;
ce503f38 19075 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19076
f6c7e546 19077 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19078 /* need the manual connection? */
7085ec12
TI
19079 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19080 if (num <= 1)
19081 return;
19082 for (i = 0; i < num; i++) {
19083 if (alc662_mix_to_dac(srcs[i]) != dac)
19084 continue;
19085 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19086 return;
bc9f98a9
KY
19087 }
19088}
19089
19090static void alc662_auto_init_multi_out(struct hda_codec *codec)
19091{
19092 struct alc_spec *spec = codec->spec;
7085ec12 19093 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19094 int i;
19095
19096 for (i = 0; i <= HDA_SIDE; i++) {
19097 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19098 if (nid)
baba8ee9 19099 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19100 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19101 }
19102}
19103
19104static void alc662_auto_init_hp_out(struct hda_codec *codec)
19105{
19106 struct alc_spec *spec = codec->spec;
19107 hda_nid_t pin;
19108
19109 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19110 if (pin)
19111 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19112 spec->multiout.hp_nid);
f6c7e546
TI
19113 pin = spec->autocfg.speaker_pins[0];
19114 if (pin)
7085ec12
TI
19115 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19116 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19117}
19118
bc9f98a9
KY
19119#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19120
19121static void alc662_auto_init_analog_input(struct hda_codec *codec)
19122{
19123 struct alc_spec *spec = codec->spec;
66ceeb6b 19124 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19125 int i;
19126
66ceeb6b
TI
19127 for (i = 0; i < cfg->num_inputs; i++) {
19128 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19129 if (alc_is_input_pin(codec, nid)) {
30ea098f 19130 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19131 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19132 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19133 snd_hda_codec_write(codec, nid, 0,
19134 AC_VERB_SET_AMP_GAIN_MUTE,
19135 AMP_OUT_MUTE);
19136 }
19137 }
19138}
19139
f511b01c
TI
19140#define alc662_auto_init_input_src alc882_auto_init_input_src
19141
bc9f98a9
KY
19142static int alc662_parse_auto_config(struct hda_codec *codec)
19143{
19144 struct alc_spec *spec = codec->spec;
19145 int err;
19146 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19147
19148 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19149 alc662_ignore);
19150 if (err < 0)
19151 return err;
19152 if (!spec->autocfg.line_outs)
19153 return 0; /* can't find valid BIOS pin config */
19154
7085ec12 19155 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19156 if (err < 0)
19157 return err;
7085ec12 19158 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19159 if (err < 0)
19160 return err;
7085ec12 19161 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19162 spec->autocfg.speaker_pins[0],
19163 "Speaker");
19164 if (err < 0)
19165 return err;
7085ec12
TI
19166 if (err)
19167 spec->multiout.extra_out_nid[0] = err;
19168 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19169 "Headphone");
19170 if (err < 0)
19171 return err;
7085ec12
TI
19172 if (err)
19173 spec->multiout.hp_nid = err;
05f5f477 19174 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19175 if (err < 0)
bc9f98a9
KY
19176 return err;
19177
19178 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19179
757899ac 19180 alc_auto_parse_digital(codec);
bc9f98a9 19181
603c4019 19182 if (spec->kctls.list)
d88897ea 19183 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19184
19185 spec->num_mux_defs = 1;
61b9b9b1 19186 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19187
cec27c89
KY
19188 add_verb(spec, alc662_init_verbs);
19189 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19190 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19191 add_verb(spec, alc663_init_verbs);
19192
19193 if (codec->vendor_id == 0x10ec0272)
19194 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19195
19196 err = alc_auto_add_mic_boost(codec);
19197 if (err < 0)
19198 return err;
19199
6227cdce
KY
19200 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19201 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19202 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19203 else
19204 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19205
8c87286f 19206 return 1;
bc9f98a9
KY
19207}
19208
19209/* additional initialization for auto-configuration model */
19210static void alc662_auto_init(struct hda_codec *codec)
19211{
f6c7e546 19212 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19213 alc662_auto_init_multi_out(codec);
19214 alc662_auto_init_hp_out(codec);
19215 alc662_auto_init_analog_input(codec);
f511b01c 19216 alc662_auto_init_input_src(codec);
757899ac 19217 alc_auto_init_digital(codec);
f6c7e546 19218 if (spec->unsol_event)
7fb0d78f 19219 alc_inithook(codec);
bc9f98a9
KY
19220}
19221
6cb3b707
DH
19222enum {
19223 ALC662_FIXUP_IDEAPAD,
19224};
19225
19226static const struct alc_fixup alc662_fixups[] = {
19227 [ALC662_FIXUP_IDEAPAD] = {
19228 .pins = (const struct alc_pincfg[]) {
19229 { 0x17, 0x99130112 }, /* subwoofer */
19230 { }
19231 }
19232 },
19233};
19234
19235static struct snd_pci_quirk alc662_fixup_tbl[] = {
19236 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19237 {}
19238};
19239
19240
19241
bc9f98a9
KY
19242static int patch_alc662(struct hda_codec *codec)
19243{
19244 struct alc_spec *spec;
19245 int err, board_config;
19246
19247 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19248 if (!spec)
19249 return -ENOMEM;
19250
19251 codec->spec = spec;
19252
da00c244
KY
19253 alc_auto_parse_customize_define(codec);
19254
2c3bf9ab
TI
19255 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19256
c027ddcd
KY
19257 if (alc_read_coef_idx(codec, 0) == 0x8020)
19258 alc_codec_rename(codec, "ALC661");
19259 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
19260 codec->bus->pci->subsystem_vendor == 0x1025 &&
19261 spec->cdefine.platform_type == 1)
19262 alc_codec_rename(codec, "ALC272X");
274693f3 19263
bc9f98a9
KY
19264 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19265 alc662_models,
19266 alc662_cfg_tbl);
19267 if (board_config < 0) {
9a11f1aa
TI
19268 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19269 codec->chip_name);
bc9f98a9
KY
19270 board_config = ALC662_AUTO;
19271 }
19272
19273 if (board_config == ALC662_AUTO) {
6cb3b707 19274 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1);
bc9f98a9
KY
19275 /* automatic parse from the BIOS config */
19276 err = alc662_parse_auto_config(codec);
19277 if (err < 0) {
19278 alc_free(codec);
19279 return err;
8c87286f 19280 } else if (!err) {
bc9f98a9
KY
19281 printk(KERN_INFO
19282 "hda_codec: Cannot set up configuration "
19283 "from BIOS. Using base mode...\n");
19284 board_config = ALC662_3ST_2ch_DIG;
19285 }
19286 }
19287
dc1eae25 19288 if (has_cdefine_beep(codec)) {
8af2591d
TI
19289 err = snd_hda_attach_beep_device(codec, 0x1);
19290 if (err < 0) {
19291 alc_free(codec);
19292 return err;
19293 }
680cd536
KK
19294 }
19295
bc9f98a9 19296 if (board_config != ALC662_AUTO)
e9c364c0 19297 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19298
bc9f98a9
KY
19299 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19300 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19301
bc9f98a9
KY
19302 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19303 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19304
dd704698
TI
19305 if (!spec->adc_nids) {
19306 spec->adc_nids = alc662_adc_nids;
19307 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19308 }
19309 if (!spec->capsrc_nids)
19310 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19311
f9e336f6 19312 if (!spec->cap_mixer)
b59bdf3b 19313 set_capture_mixer(codec);
cec27c89 19314
dc1eae25 19315 if (has_cdefine_beep(codec)) {
da00c244
KY
19316 switch (codec->vendor_id) {
19317 case 0x10ec0662:
19318 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19319 break;
19320 case 0x10ec0272:
19321 case 0x10ec0663:
19322 case 0x10ec0665:
19323 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19324 break;
19325 case 0x10ec0273:
19326 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19327 break;
19328 }
cec27c89 19329 }
2134ea4f
TI
19330 spec->vmaster_nid = 0x02;
19331
bc9f98a9 19332 codec->patch_ops = alc_patch_ops;
6cb3b707 19333 if (board_config == ALC662_AUTO) {
bc9f98a9 19334 spec->init_hook = alc662_auto_init;
6cb3b707
DH
19335 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0);
19336 }
19337
cb53c626
TI
19338#ifdef CONFIG_SND_HDA_POWER_SAVE
19339 if (!spec->loopback.amplist)
19340 spec->loopback.amplist = alc662_loopbacks;
19341#endif
bc9f98a9
KY
19342
19343 return 0;
19344}
19345
274693f3
KY
19346static int patch_alc888(struct hda_codec *codec)
19347{
19348 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19349 kfree(codec->chip_name);
19350 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19351 if (!codec->chip_name) {
19352 alc_free(codec);
274693f3 19353 return -ENOMEM;
ac2c92e0
TI
19354 }
19355 return patch_alc662(codec);
274693f3 19356 }
ac2c92e0 19357 return patch_alc882(codec);
274693f3
KY
19358}
19359
d1eb57f4
KY
19360/*
19361 * ALC680 support
19362 */
c69aefab 19363#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19364#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19365#define alc680_modes alc260_modes
19366
19367static hda_nid_t alc680_dac_nids[3] = {
19368 /* Lout1, Lout2, hp */
19369 0x02, 0x03, 0x04
19370};
19371
19372static hda_nid_t alc680_adc_nids[3] = {
19373 /* ADC0-2 */
19374 /* DMIC, MIC, Line-in*/
19375 0x07, 0x08, 0x09
19376};
19377
c69aefab
KY
19378/*
19379 * Analog capture ADC cgange
19380 */
66ceeb6b
TI
19381static void alc680_rec_autoswitch(struct hda_codec *codec)
19382{
19383 struct alc_spec *spec = codec->spec;
19384 struct auto_pin_cfg *cfg = &spec->autocfg;
19385 int pin_found = 0;
19386 int type_found = AUTO_PIN_LAST;
19387 hda_nid_t nid;
19388 int i;
19389
19390 for (i = 0; i < cfg->num_inputs; i++) {
19391 nid = cfg->inputs[i].pin;
19392 if (!(snd_hda_query_pin_caps(codec, nid) &
19393 AC_PINCAP_PRES_DETECT))
19394 continue;
19395 if (snd_hda_jack_detect(codec, nid)) {
19396 if (cfg->inputs[i].type < type_found) {
19397 type_found = cfg->inputs[i].type;
19398 pin_found = nid;
19399 }
19400 }
19401 }
19402
19403 nid = 0x07;
19404 if (pin_found)
19405 snd_hda_get_connections(codec, pin_found, &nid, 1);
19406
19407 if (nid != spec->cur_adc)
19408 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19409 spec->cur_adc = nid;
19410 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19411 spec->cur_adc_format);
19412}
19413
c69aefab
KY
19414static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19415 struct hda_codec *codec,
19416 unsigned int stream_tag,
19417 unsigned int format,
19418 struct snd_pcm_substream *substream)
19419{
19420 struct alc_spec *spec = codec->spec;
c69aefab 19421
66ceeb6b 19422 spec->cur_adc = 0x07;
c69aefab
KY
19423 spec->cur_adc_stream_tag = stream_tag;
19424 spec->cur_adc_format = format;
19425
66ceeb6b 19426 alc680_rec_autoswitch(codec);
c69aefab
KY
19427 return 0;
19428}
19429
19430static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19431 struct hda_codec *codec,
19432 struct snd_pcm_substream *substream)
19433{
19434 snd_hda_codec_cleanup_stream(codec, 0x07);
19435 snd_hda_codec_cleanup_stream(codec, 0x08);
19436 snd_hda_codec_cleanup_stream(codec, 0x09);
19437 return 0;
19438}
19439
19440static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19441 .substreams = 1, /* can be overridden */
19442 .channels_min = 2,
19443 .channels_max = 2,
19444 /* NID is set in alc_build_pcms */
19445 .ops = {
19446 .prepare = alc680_capture_pcm_prepare,
19447 .cleanup = alc680_capture_pcm_cleanup
19448 },
19449};
19450
d1eb57f4
KY
19451static struct snd_kcontrol_new alc680_base_mixer[] = {
19452 /* output mixer control */
19453 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19454 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19455 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19456 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
c69aefab 19457 HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT),
d1eb57f4 19458 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c69aefab 19459 HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19460 { }
19461};
19462
c69aefab
KY
19463static struct hda_bind_ctls alc680_bind_cap_vol = {
19464 .ops = &snd_hda_bind_vol,
19465 .values = {
19466 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19467 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19468 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19469 0
19470 },
19471};
19472
19473static struct hda_bind_ctls alc680_bind_cap_switch = {
19474 .ops = &snd_hda_bind_sw,
19475 .values = {
19476 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19477 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19478 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19479 0
19480 },
19481};
19482
19483static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19484 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19485 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19486 { } /* end */
19487};
19488
19489/*
19490 * generic initialization of ADC, input mixers and output mixers
19491 */
19492static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19493 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19494 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19495 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19496
c69aefab
KY
19497 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19498 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19499 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19500 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19501 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19502 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19503
19504 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19505 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19506 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19507 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19508 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19509
19510 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19511 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19512 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19513
d1eb57f4
KY
19514 { }
19515};
19516
c69aefab
KY
19517/* toggle speaker-output according to the hp-jack state */
19518static void alc680_base_setup(struct hda_codec *codec)
19519{
19520 struct alc_spec *spec = codec->spec;
19521
19522 spec->autocfg.hp_pins[0] = 0x16;
19523 spec->autocfg.speaker_pins[0] = 0x14;
19524 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19525 spec->autocfg.num_inputs = 2;
19526 spec->autocfg.inputs[0].pin = 0x18;
19527 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19528 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19529 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19530}
19531
19532static void alc680_unsol_event(struct hda_codec *codec,
19533 unsigned int res)
19534{
19535 if ((res >> 26) == ALC880_HP_EVENT)
19536 alc_automute_amp(codec);
19537 if ((res >> 26) == ALC880_MIC_EVENT)
19538 alc680_rec_autoswitch(codec);
19539}
19540
19541static void alc680_inithook(struct hda_codec *codec)
19542{
19543 alc_automute_amp(codec);
19544 alc680_rec_autoswitch(codec);
19545}
19546
d1eb57f4
KY
19547/* create input playback/capture controls for the given pin */
19548static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19549 const char *ctlname, int idx)
19550{
19551 hda_nid_t dac;
19552 int err;
19553
19554 switch (nid) {
19555 case 0x14:
19556 dac = 0x02;
19557 break;
19558 case 0x15:
19559 dac = 0x03;
19560 break;
19561 case 0x16:
19562 dac = 0x04;
19563 break;
19564 default:
19565 return 0;
19566 }
19567 if (spec->multiout.dac_nids[0] != dac &&
19568 spec->multiout.dac_nids[1] != dac) {
19569 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19570 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19571 HDA_OUTPUT));
19572 if (err < 0)
19573 return err;
19574
19575 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19576 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19577
19578 if (err < 0)
19579 return err;
19580 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19581 }
19582
19583 return 0;
19584}
19585
19586/* add playback controls from the parsed DAC table */
19587static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19588 const struct auto_pin_cfg *cfg)
19589{
19590 hda_nid_t nid;
19591 int err;
19592
19593 spec->multiout.dac_nids = spec->private_dac_nids;
19594
19595 nid = cfg->line_out_pins[0];
19596 if (nid) {
19597 const char *name;
19598 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19599 name = "Speaker";
19600 else
19601 name = "Front";
19602 err = alc680_new_analog_output(spec, nid, name, 0);
19603 if (err < 0)
19604 return err;
19605 }
19606
19607 nid = cfg->speaker_pins[0];
19608 if (nid) {
19609 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19610 if (err < 0)
19611 return err;
19612 }
19613 nid = cfg->hp_pins[0];
19614 if (nid) {
19615 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19616 if (err < 0)
19617 return err;
19618 }
19619
19620 return 0;
19621}
19622
19623static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19624 hda_nid_t nid, int pin_type)
19625{
19626 alc_set_pin_output(codec, nid, pin_type);
19627}
19628
19629static void alc680_auto_init_multi_out(struct hda_codec *codec)
19630{
19631 struct alc_spec *spec = codec->spec;
19632 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19633 if (nid) {
19634 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19635 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19636 }
19637}
19638
19639static void alc680_auto_init_hp_out(struct hda_codec *codec)
19640{
19641 struct alc_spec *spec = codec->spec;
19642 hda_nid_t pin;
19643
19644 pin = spec->autocfg.hp_pins[0];
19645 if (pin)
19646 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19647 pin = spec->autocfg.speaker_pins[0];
19648 if (pin)
19649 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19650}
19651
19652/* pcm configuration: identical with ALC880 */
19653#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19654#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19655#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19656#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19657#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19658
19659/*
19660 * BIOS auto configuration
19661 */
19662static int alc680_parse_auto_config(struct hda_codec *codec)
19663{
19664 struct alc_spec *spec = codec->spec;
19665 int err;
19666 static hda_nid_t alc680_ignore[] = { 0 };
19667
19668 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19669 alc680_ignore);
19670 if (err < 0)
19671 return err;
c69aefab 19672
d1eb57f4
KY
19673 if (!spec->autocfg.line_outs) {
19674 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19675 spec->multiout.max_channels = 2;
19676 spec->no_analog = 1;
19677 goto dig_only;
19678 }
19679 return 0; /* can't find valid BIOS pin config */
19680 }
19681 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19682 if (err < 0)
19683 return err;
19684
19685 spec->multiout.max_channels = 2;
19686
19687 dig_only:
19688 /* digital only support output */
757899ac 19689 alc_auto_parse_digital(codec);
d1eb57f4
KY
19690 if (spec->kctls.list)
19691 add_mixer(spec, spec->kctls.list);
19692
19693 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19694
19695 err = alc_auto_add_mic_boost(codec);
19696 if (err < 0)
19697 return err;
19698
19699 return 1;
19700}
19701
19702#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19703
19704/* init callback for auto-configuration model -- overriding the default init */
19705static void alc680_auto_init(struct hda_codec *codec)
19706{
19707 struct alc_spec *spec = codec->spec;
19708 alc680_auto_init_multi_out(codec);
19709 alc680_auto_init_hp_out(codec);
19710 alc680_auto_init_analog_input(codec);
757899ac 19711 alc_auto_init_digital(codec);
d1eb57f4
KY
19712 if (spec->unsol_event)
19713 alc_inithook(codec);
19714}
19715
19716/*
19717 * configuration and preset
19718 */
19719static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19720 [ALC680_BASE] = "base",
19721 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19722};
19723
19724static struct snd_pci_quirk alc680_cfg_tbl[] = {
19725 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19726 {}
19727};
19728
19729static struct alc_config_preset alc680_presets[] = {
19730 [ALC680_BASE] = {
19731 .mixers = { alc680_base_mixer },
c69aefab 19732 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19733 .init_verbs = { alc680_init_verbs },
19734 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19735 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19736 .dig_out_nid = ALC680_DIGOUT_NID,
19737 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19738 .channel_mode = alc680_modes,
c69aefab
KY
19739 .unsol_event = alc680_unsol_event,
19740 .setup = alc680_base_setup,
19741 .init_hook = alc680_inithook,
19742
d1eb57f4
KY
19743 },
19744};
19745
19746static int patch_alc680(struct hda_codec *codec)
19747{
19748 struct alc_spec *spec;
19749 int board_config;
19750 int err;
19751
19752 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19753 if (spec == NULL)
19754 return -ENOMEM;
19755
19756 codec->spec = spec;
19757
19758 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19759 alc680_models,
19760 alc680_cfg_tbl);
19761
19762 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19763 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19764 codec->chip_name);
19765 board_config = ALC680_AUTO;
19766 }
19767
19768 if (board_config == ALC680_AUTO) {
19769 /* automatic parse from the BIOS config */
19770 err = alc680_parse_auto_config(codec);
19771 if (err < 0) {
19772 alc_free(codec);
19773 return err;
19774 } else if (!err) {
19775 printk(KERN_INFO
19776 "hda_codec: Cannot set up configuration "
19777 "from BIOS. Using base mode...\n");
19778 board_config = ALC680_BASE;
19779 }
19780 }
19781
19782 if (board_config != ALC680_AUTO)
19783 setup_preset(codec, &alc680_presets[board_config]);
19784
19785 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19786 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19787 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19788 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19789
19790 if (!spec->adc_nids) {
19791 spec->adc_nids = alc680_adc_nids;
19792 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19793 }
19794
19795 if (!spec->cap_mixer)
19796 set_capture_mixer(codec);
19797
19798 spec->vmaster_nid = 0x02;
19799
19800 codec->patch_ops = alc_patch_ops;
19801 if (board_config == ALC680_AUTO)
19802 spec->init_hook = alc680_auto_init;
19803
19804 return 0;
19805}
19806
1da177e4
LT
19807/*
19808 * patch entries
19809 */
1289e9e8 19810static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19811 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19812 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19813 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19814 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19815 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19816 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19817 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19818 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19819 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19820 .patch = patch_alc861 },
f32610ed
JS
19821 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19822 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19823 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19824 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19825 .patch = patch_alc882 },
bc9f98a9
KY
19826 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19827 .patch = patch_alc662 },
6dda9f4a 19828 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19829 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19830 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19831 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19832 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19833 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19834 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19835 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19836 .patch = patch_alc882 },
cb308f97 19837 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19838 .patch = patch_alc882 },
df694daa 19839 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 19840 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 19841 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19842 .patch = patch_alc882 },
274693f3 19843 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19844 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19845 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
19846 {} /* terminator */
19847};
1289e9e8
TI
19848
19849MODULE_ALIAS("snd-hda-codec-id:10ec*");
19850
19851MODULE_LICENSE("GPL");
19852MODULE_DESCRIPTION("Realtek HD-audio codec");
19853
19854static struct hda_codec_preset_list realtek_list = {
19855 .preset = snd_hda_preset_realtek,
19856 .owner = THIS_MODULE,
19857};
19858
19859static int __init patch_realtek_init(void)
19860{
19861 return snd_hda_add_codec_preset(&realtek_list);
19862}
19863
19864static void __exit patch_realtek_exit(void)
19865{
19866 snd_hda_delete_codec_preset(&realtek_list);
19867}
19868
19869module_init(patch_realtek_init)
19870module_exit(patch_realtek_exit)