ALSA: HDA: Add position_fix=3 module option, and refactor related code
[GitHub/mt8127/android_kernel_alcatel_ttab.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
265a0247
TI
1090 if (hp_nid) {
1091 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE);
1092 if (err < 0)
1093 return err;
1094 alc_report_jack(codec, hp_nid);
1095 }
9ad0e496 1096
265a0247
TI
1097 if (mic_nid) {
1098 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE);
1099 if (err < 0)
1100 return err;
1101 alc_report_jack(codec, mic_nid);
1102 }
9ad0e496
KY
1103
1104 return 0;
1105}
1106#else
1107static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1108{
1109}
1110
1111static inline int alc_init_jacks(struct hda_codec *codec)
1112{
1113 return 0;
1114}
1115#endif
1116
bb35febd 1117static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
c9b58006
KY
1118{
1119 struct alc_spec *spec = codec->spec;
bb35febd
TI
1120 unsigned int mute;
1121 hda_nid_t nid;
a9fd4f3f 1122 int i;
c9b58006 1123
bb35febd
TI
1124 spec->jack_present = 0;
1125 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1126 nid = spec->autocfg.hp_pins[i];
1127 if (!nid)
1128 break;
1129 if (snd_hda_jack_detect(codec, nid)) {
1130 spec->jack_present = 1;
1131 break;
1132 }
9ad0e496 1133 alc_report_jack(codec, spec->autocfg.hp_pins[i]);
bb35febd
TI
1134 }
1135
1136 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1137 /* Toggle internal speakers muting */
a9fd4f3f
TI
1138 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1139 nid = spec->autocfg.speaker_pins[i];
1140 if (!nid)
1141 break;
bb35febd
TI
1142 if (pinctl) {
1143 snd_hda_codec_write(codec, nid, 0,
a9fd4f3f
TI
1144 AC_VERB_SET_PIN_WIDGET_CONTROL,
1145 spec->jack_present ? 0 : PIN_OUT);
bb35febd
TI
1146 } else {
1147 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1148 HDA_AMP_MUTE, mute);
1149 }
a9fd4f3f 1150 }
c9b58006
KY
1151}
1152
bb35febd
TI
1153static void alc_automute_pin(struct hda_codec *codec)
1154{
1155 alc_automute_speaker(codec, 1);
1156}
1157
6c819492
TI
1158static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1159 hda_nid_t nid)
1160{
1161 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1162 int i, nums;
1163
1164 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1165 for (i = 0; i < nums; i++)
1166 if (conn[i] == nid)
1167 return i;
1168 return -1;
1169}
1170
840b64c0
TI
1171/* switch the current ADC according to the jack state */
1172static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1173{
1174 struct alc_spec *spec = codec->spec;
1175 unsigned int present;
1176 hda_nid_t new_adc;
1177
1178 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1179 if (present)
1180 spec->cur_adc_idx = 1;
1181 else
1182 spec->cur_adc_idx = 0;
1183 new_adc = spec->adc_nids[spec->cur_adc_idx];
1184 if (spec->cur_adc && spec->cur_adc != new_adc) {
1185 /* stream is running, let's swap the current ADC */
f0cea797 1186 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1187 spec->cur_adc = new_adc;
1188 snd_hda_codec_setup_stream(codec, new_adc,
1189 spec->cur_adc_stream_tag, 0,
1190 spec->cur_adc_format);
1191 }
1192}
1193
7fb0d78f
KY
1194static void alc_mic_automute(struct hda_codec *codec)
1195{
1196 struct alc_spec *spec = codec->spec;
6c819492
TI
1197 struct alc_mic_route *dead, *alive;
1198 unsigned int present, type;
1199 hda_nid_t cap_nid;
1200
b59bdf3b
TI
1201 if (!spec->auto_mic)
1202 return;
6c819492
TI
1203 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1204 return;
1205 if (snd_BUG_ON(!spec->adc_nids))
1206 return;
1207
840b64c0
TI
1208 if (spec->dual_adc_switch) {
1209 alc_dual_mic_adc_auto_switch(codec);
1210 return;
1211 }
1212
6c819492
TI
1213 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1214
864f92be 1215 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1216 if (present) {
1217 alive = &spec->ext_mic;
1218 dead = &spec->int_mic;
1219 } else {
1220 alive = &spec->int_mic;
1221 dead = &spec->ext_mic;
1222 }
1223
6c819492
TI
1224 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1225 if (type == AC_WID_AUD_MIX) {
1226 /* Matrix-mixer style (e.g. ALC882) */
1227 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1228 alive->mux_idx,
1229 HDA_AMP_MUTE, 0);
1230 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1231 dead->mux_idx,
1232 HDA_AMP_MUTE, HDA_AMP_MUTE);
1233 } else {
1234 /* MUX style (e.g. ALC880) */
1235 snd_hda_codec_write_cache(codec, cap_nid, 0,
1236 AC_VERB_SET_CONNECT_SEL,
1237 alive->mux_idx);
1238 }
9ad0e496 1239 alc_report_jack(codec, spec->ext_mic.pin);
6c819492
TI
1240
1241 /* FIXME: analog mixer */
7fb0d78f
KY
1242}
1243
c9b58006
KY
1244/* unsolicited event for HP jack sensing */
1245static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1246{
1247 if (codec->vendor_id == 0x10ec0880)
1248 res >>= 28;
1249 else
1250 res >>= 26;
a9fd4f3f
TI
1251 switch (res) {
1252 case ALC880_HP_EVENT:
1253 alc_automute_pin(codec);
1254 break;
1255 case ALC880_MIC_EVENT:
7fb0d78f 1256 alc_mic_automute(codec);
a9fd4f3f
TI
1257 break;
1258 }
7fb0d78f
KY
1259}
1260
1261static void alc_inithook(struct hda_codec *codec)
1262{
a9fd4f3f 1263 alc_automute_pin(codec);
7fb0d78f 1264 alc_mic_automute(codec);
c9b58006
KY
1265}
1266
f9423e7a
KY
1267/* additional initialization for ALC888 variants */
1268static void alc888_coef_init(struct hda_codec *codec)
1269{
1270 unsigned int tmp;
1271
1272 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1273 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1274 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1275 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1276 /* alc888S-VC */
1277 snd_hda_codec_read(codec, 0x20, 0,
1278 AC_VERB_SET_PROC_COEF, 0x830);
1279 else
1280 /* alc888-VB */
1281 snd_hda_codec_read(codec, 0x20, 0,
1282 AC_VERB_SET_PROC_COEF, 0x3030);
1283}
1284
87a8c370
JK
1285static void alc889_coef_init(struct hda_codec *codec)
1286{
1287 unsigned int tmp;
1288
1289 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1290 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1291 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1292 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1293}
1294
3fb4a508
TI
1295/* turn on/off EAPD control (only if available) */
1296static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1297{
1298 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1299 return;
1300 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1301 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1302 on ? 2 : 0);
1303}
1304
4a79ba34 1305static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1306{
4a79ba34 1307 unsigned int tmp;
bc9f98a9 1308
4a79ba34
TI
1309 switch (type) {
1310 case ALC_INIT_GPIO1:
bc9f98a9
KY
1311 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1312 break;
4a79ba34 1313 case ALC_INIT_GPIO2:
bc9f98a9
KY
1314 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1315 break;
4a79ba34 1316 case ALC_INIT_GPIO3:
bdd148a3
KY
1317 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1318 break;
4a79ba34 1319 case ALC_INIT_DEFAULT:
bdd148a3 1320 switch (codec->vendor_id) {
c9b58006 1321 case 0x10ec0260:
3fb4a508
TI
1322 set_eapd(codec, 0x0f, 1);
1323 set_eapd(codec, 0x10, 1);
c9b58006
KY
1324 break;
1325 case 0x10ec0262:
bdd148a3
KY
1326 case 0x10ec0267:
1327 case 0x10ec0268:
c9b58006 1328 case 0x10ec0269:
3fb4a508 1329 case 0x10ec0270:
c6e8f2da 1330 case 0x10ec0272:
f9423e7a
KY
1331 case 0x10ec0660:
1332 case 0x10ec0662:
1333 case 0x10ec0663:
c9b58006 1334 case 0x10ec0862:
20a3a05d 1335 case 0x10ec0889:
3fb4a508
TI
1336 set_eapd(codec, 0x14, 1);
1337 set_eapd(codec, 0x15, 1);
c9b58006 1338 break;
bdd148a3 1339 }
c9b58006
KY
1340 switch (codec->vendor_id) {
1341 case 0x10ec0260:
1342 snd_hda_codec_write(codec, 0x1a, 0,
1343 AC_VERB_SET_COEF_INDEX, 7);
1344 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1345 AC_VERB_GET_PROC_COEF, 0);
1346 snd_hda_codec_write(codec, 0x1a, 0,
1347 AC_VERB_SET_COEF_INDEX, 7);
1348 snd_hda_codec_write(codec, 0x1a, 0,
1349 AC_VERB_SET_PROC_COEF,
1350 tmp | 0x2010);
1351 break;
1352 case 0x10ec0262:
1353 case 0x10ec0880:
1354 case 0x10ec0882:
1355 case 0x10ec0883:
1356 case 0x10ec0885:
4a5a4c56 1357 case 0x10ec0887:
20a3a05d 1358 case 0x10ec0889:
87a8c370 1359 alc889_coef_init(codec);
c9b58006 1360 break;
f9423e7a 1361 case 0x10ec0888:
4a79ba34 1362 alc888_coef_init(codec);
f9423e7a 1363 break;
0aea778e 1364#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1365 case 0x10ec0267:
1366 case 0x10ec0268:
1367 snd_hda_codec_write(codec, 0x20, 0,
1368 AC_VERB_SET_COEF_INDEX, 7);
1369 tmp = snd_hda_codec_read(codec, 0x20, 0,
1370 AC_VERB_GET_PROC_COEF, 0);
1371 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1372 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1373 snd_hda_codec_write(codec, 0x20, 0,
1374 AC_VERB_SET_PROC_COEF,
1375 tmp | 0x3000);
1376 break;
0aea778e 1377#endif /* XXX */
bc9f98a9 1378 }
4a79ba34
TI
1379 break;
1380 }
1381}
1382
1383static void alc_init_auto_hp(struct hda_codec *codec)
1384{
1385 struct alc_spec *spec = codec->spec;
bb35febd
TI
1386 struct auto_pin_cfg *cfg = &spec->autocfg;
1387 int i;
4a79ba34 1388
bb35febd
TI
1389 if (!cfg->hp_pins[0]) {
1390 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1391 return;
1392 }
4a79ba34 1393
bb35febd
TI
1394 if (!cfg->speaker_pins[0]) {
1395 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4a79ba34 1396 return;
bb35febd
TI
1397 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1398 sizeof(cfg->speaker_pins));
1399 cfg->speaker_outs = cfg->line_outs;
1400 }
1401
1402 if (!cfg->hp_pins[0]) {
1403 memcpy(cfg->hp_pins, cfg->line_out_pins,
1404 sizeof(cfg->hp_pins));
1405 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1406 }
1407
bb35febd
TI
1408 for (i = 0; i < cfg->hp_outs; i++) {
1409 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1410 cfg->hp_pins[i]);
1411 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
4a79ba34
TI
1412 AC_VERB_SET_UNSOLICITED_ENABLE,
1413 AC_USRSP_EN | ALC880_HP_EVENT);
bb35febd 1414 }
4a79ba34
TI
1415 spec->unsol_event = alc_sku_unsol_event;
1416}
1417
6c819492
TI
1418static void alc_init_auto_mic(struct hda_codec *codec)
1419{
1420 struct alc_spec *spec = codec->spec;
1421 struct auto_pin_cfg *cfg = &spec->autocfg;
1422 hda_nid_t fixed, ext;
1423 int i;
1424
1425 /* there must be only two mic inputs exclusively */
66ceeb6b 1426 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1427 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1428 return;
1429
1430 fixed = ext = 0;
66ceeb6b
TI
1431 for (i = 0; i < cfg->num_inputs; i++) {
1432 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1433 unsigned int defcfg;
6c819492 1434 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1435 switch (snd_hda_get_input_pin_attr(defcfg)) {
1436 case INPUT_PIN_ATTR_INT:
6c819492
TI
1437 if (fixed)
1438 return; /* already occupied */
1439 fixed = nid;
1440 break;
99ae28be
TI
1441 case INPUT_PIN_ATTR_UNUSED:
1442 return; /* invalid entry */
1443 default:
6c819492
TI
1444 if (ext)
1445 return; /* already occupied */
1446 ext = nid;
1447 break;
6c819492
TI
1448 }
1449 }
eaa9b3a7
TI
1450 if (!ext || !fixed)
1451 return;
6c819492
TI
1452 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1453 return; /* no unsol support */
1454 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1455 ext, fixed);
1456 spec->ext_mic.pin = ext;
1457 spec->int_mic.pin = fixed;
1458 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1459 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1460 spec->auto_mic = 1;
1461 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1462 AC_VERB_SET_UNSOLICITED_ENABLE,
1463 AC_USRSP_EN | ALC880_MIC_EVENT);
1464 spec->unsol_event = alc_sku_unsol_event;
1465}
1466
da00c244
KY
1467static int alc_auto_parse_customize_define(struct hda_codec *codec)
1468{
1469 unsigned int ass, tmp, i;
7fb56223 1470 unsigned nid = 0;
da00c244
KY
1471 struct alc_spec *spec = codec->spec;
1472
b6cbe517
TI
1473 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1474
da00c244 1475 ass = codec->subsystem_id & 0xffff;
b6cbe517 1476 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1477 goto do_sku;
1478
1479 nid = 0x1d;
1480 if (codec->vendor_id == 0x10ec0260)
1481 nid = 0x17;
1482 ass = snd_hda_codec_get_pincfg(codec, nid);
1483
1484 if (!(ass & 1)) {
1485 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1486 codec->chip_name, ass);
1487 return -1;
1488 }
1489
1490 /* check sum */
1491 tmp = 0;
1492 for (i = 1; i < 16; i++) {
1493 if ((ass >> i) & 1)
1494 tmp++;
1495 }
1496 if (((ass >> 16) & 0xf) != tmp)
1497 return -1;
1498
1499 spec->cdefine.port_connectivity = ass >> 30;
1500 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1501 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1502 spec->cdefine.customization = ass >> 8;
1503do_sku:
1504 spec->cdefine.sku_cfg = ass;
1505 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1506 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1507 spec->cdefine.swap = (ass & 0x2) >> 1;
1508 spec->cdefine.override = ass & 0x1;
1509
1510 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1511 nid, spec->cdefine.sku_cfg);
1512 snd_printd("SKU: port_connectivity=0x%x\n",
1513 spec->cdefine.port_connectivity);
1514 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1515 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1516 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1517 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1518 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1519 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1520 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1521
1522 return 0;
1523}
1524
4a79ba34
TI
1525/* check subsystem ID and set up device-specific initialization;
1526 * return 1 if initialized, 0 if invalid SSID
1527 */
1528/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1529 * 31 ~ 16 : Manufacture ID
1530 * 15 ~ 8 : SKU ID
1531 * 7 ~ 0 : Assembly ID
1532 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1533 */
1534static int alc_subsystem_id(struct hda_codec *codec,
1535 hda_nid_t porta, hda_nid_t porte,
6227cdce 1536 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1537{
1538 unsigned int ass, tmp, i;
1539 unsigned nid;
1540 struct alc_spec *spec = codec->spec;
1541
1542 ass = codec->subsystem_id & 0xffff;
1543 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1544 goto do_sku;
1545
1546 /* invalid SSID, check the special NID pin defcfg instead */
1547 /*
def319f9 1548 * 31~30 : port connectivity
4a79ba34
TI
1549 * 29~21 : reserve
1550 * 20 : PCBEEP input
1551 * 19~16 : Check sum (15:1)
1552 * 15~1 : Custom
1553 * 0 : override
1554 */
1555 nid = 0x1d;
1556 if (codec->vendor_id == 0x10ec0260)
1557 nid = 0x17;
1558 ass = snd_hda_codec_get_pincfg(codec, nid);
1559 snd_printd("realtek: No valid SSID, "
1560 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1561 ass, nid);
6227cdce 1562 if (!(ass & 1))
4a79ba34
TI
1563 return 0;
1564 if ((ass >> 30) != 1) /* no physical connection */
1565 return 0;
1566
1567 /* check sum */
1568 tmp = 0;
1569 for (i = 1; i < 16; i++) {
1570 if ((ass >> i) & 1)
1571 tmp++;
1572 }
1573 if (((ass >> 16) & 0xf) != tmp)
1574 return 0;
1575do_sku:
1576 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1577 ass & 0xffff, codec->vendor_id);
1578 /*
1579 * 0 : override
1580 * 1 : Swap Jack
1581 * 2 : 0 --> Desktop, 1 --> Laptop
1582 * 3~5 : External Amplifier control
1583 * 7~6 : Reserved
1584 */
1585 tmp = (ass & 0x38) >> 3; /* external Amp control */
1586 switch (tmp) {
1587 case 1:
1588 spec->init_amp = ALC_INIT_GPIO1;
1589 break;
1590 case 3:
1591 spec->init_amp = ALC_INIT_GPIO2;
1592 break;
1593 case 7:
1594 spec->init_amp = ALC_INIT_GPIO3;
1595 break;
1596 case 5:
1597 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1598 break;
1599 }
ea1fb29a 1600
8c427226 1601 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1602 * when the external headphone out jack is plugged"
1603 */
8c427226 1604 if (!(ass & 0x8000))
4a79ba34 1605 return 1;
c9b58006
KY
1606 /*
1607 * 10~8 : Jack location
1608 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1609 * 14~13: Resvered
1610 * 15 : 1 --> enable the function "Mute internal speaker
1611 * when the external headphone out jack is plugged"
1612 */
c9b58006 1613 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1614 hda_nid_t nid;
c9b58006
KY
1615 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1616 if (tmp == 0)
01d4825d 1617 nid = porta;
c9b58006 1618 else if (tmp == 1)
01d4825d 1619 nid = porte;
c9b58006 1620 else if (tmp == 2)
01d4825d 1621 nid = portd;
6227cdce
KY
1622 else if (tmp == 3)
1623 nid = porti;
c9b58006 1624 else
4a79ba34 1625 return 1;
01d4825d
TI
1626 for (i = 0; i < spec->autocfg.line_outs; i++)
1627 if (spec->autocfg.line_out_pins[i] == nid)
1628 return 1;
1629 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1630 }
1631
4a79ba34 1632 alc_init_auto_hp(codec);
6c819492 1633 alc_init_auto_mic(codec);
4a79ba34
TI
1634 return 1;
1635}
ea1fb29a 1636
4a79ba34 1637static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1638 hda_nid_t porta, hda_nid_t porte,
1639 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1640{
6227cdce 1641 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1642 struct alc_spec *spec = codec->spec;
1643 snd_printd("realtek: "
1644 "Enable default setup for auto mode as fallback\n");
1645 spec->init_amp = ALC_INIT_DEFAULT;
1646 alc_init_auto_hp(codec);
6c819492 1647 alc_init_auto_mic(codec);
4a79ba34 1648 }
bc9f98a9
KY
1649}
1650
f95474ec 1651/*
f8f25ba3 1652 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1653 */
1654
1655struct alc_pincfg {
1656 hda_nid_t nid;
1657 u32 val;
1658};
1659
f8f25ba3
TI
1660struct alc_fixup {
1661 const struct alc_pincfg *pins;
1662 const struct hda_verb *verbs;
1663};
1664
1665static void alc_pick_fixup(struct hda_codec *codec,
f95474ec 1666 const struct snd_pci_quirk *quirk,
7fa90e87
TI
1667 const struct alc_fixup *fix,
1668 int pre_init)
f95474ec
TI
1669{
1670 const struct alc_pincfg *cfg;
1671
1672 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1673 if (!quirk)
1674 return;
f8f25ba3
TI
1675 fix += quirk->value;
1676 cfg = fix->pins;
7fa90e87
TI
1677 if (pre_init && cfg) {
1678#ifdef CONFIG_SND_DEBUG_VERBOSE
1679 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1680 codec->chip_name, quirk->name);
1681#endif
f8f25ba3
TI
1682 for (; cfg->nid; cfg++)
1683 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1684 }
7fa90e87
TI
1685 if (!pre_init && fix->verbs) {
1686#ifdef CONFIG_SND_DEBUG_VERBOSE
1687 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1688 codec->chip_name, quirk->name);
1689#endif
f8f25ba3 1690 add_verb(codec->spec, fix->verbs);
7fa90e87 1691 }
f95474ec
TI
1692}
1693
274693f3
KY
1694static int alc_read_coef_idx(struct hda_codec *codec,
1695 unsigned int coef_idx)
1696{
1697 unsigned int val;
1698 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1699 coef_idx);
1700 val = snd_hda_codec_read(codec, 0x20, 0,
1701 AC_VERB_GET_PROC_COEF, 0);
1702 return val;
1703}
1704
977ddd6b
KY
1705static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1706 unsigned int coef_val)
1707{
1708 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1709 coef_idx);
1710 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1711 coef_val);
1712}
1713
757899ac
TI
1714/* set right pin controls for digital I/O */
1715static void alc_auto_init_digital(struct hda_codec *codec)
1716{
1717 struct alc_spec *spec = codec->spec;
1718 int i;
1719 hda_nid_t pin;
1720
1721 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1722 pin = spec->autocfg.dig_out_pins[i];
1723 if (pin) {
1724 snd_hda_codec_write(codec, pin, 0,
1725 AC_VERB_SET_PIN_WIDGET_CONTROL,
1726 PIN_OUT);
1727 }
1728 }
1729 pin = spec->autocfg.dig_in_pin;
1730 if (pin)
1731 snd_hda_codec_write(codec, pin, 0,
1732 AC_VERB_SET_PIN_WIDGET_CONTROL,
1733 PIN_IN);
1734}
1735
1736/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1737static void alc_auto_parse_digital(struct hda_codec *codec)
1738{
1739 struct alc_spec *spec = codec->spec;
1740 int i, err;
1741 hda_nid_t dig_nid;
1742
1743 /* support multiple SPDIFs; the secondary is set up as a slave */
1744 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1745 err = snd_hda_get_connections(codec,
1746 spec->autocfg.dig_out_pins[i],
1747 &dig_nid, 1);
1748 if (err < 0)
1749 continue;
1750 if (!i) {
1751 spec->multiout.dig_out_nid = dig_nid;
1752 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1753 } else {
1754 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1755 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1756 break;
1757 spec->slave_dig_outs[i - 1] = dig_nid;
1758 }
1759 }
1760
1761 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
1762 dig_nid = codec->start_nid;
1763 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1764 unsigned int wcaps = get_wcaps(codec, dig_nid);
1765 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1766 continue;
1767 if (!(wcaps & AC_WCAP_DIGITAL))
1768 continue;
1769 if (!(wcaps & AC_WCAP_CONN_LIST))
1770 continue;
1771 err = get_connection_index(codec, dig_nid,
1772 spec->autocfg.dig_in_pin);
1773 if (err >= 0) {
1774 spec->dig_in_nid = dig_nid;
1775 break;
1776 }
1777 }
757899ac
TI
1778 }
1779}
1780
ef8ef5fb
VP
1781/*
1782 * ALC888
1783 */
1784
1785/*
1786 * 2ch mode
1787 */
1788static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1789/* Mic-in jack as mic in */
1790 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1791 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1792/* Line-in jack as Line in */
1793 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1794 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1795/* Line-Out as Front */
1796 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1797 { } /* end */
1798};
1799
1800/*
1801 * 4ch mode
1802 */
1803static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1804/* Mic-in jack as mic in */
1805 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1806 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1807/* Line-in jack as Surround */
1808 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1809 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1810/* Line-Out as Front */
1811 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1812 { } /* end */
1813};
1814
1815/*
1816 * 6ch mode
1817 */
1818static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1819/* Mic-in jack as CLFE */
1820 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1821 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1822/* Line-in jack as Surround */
1823 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1824 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1825/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1826 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1827 { } /* end */
1828};
1829
1830/*
1831 * 8ch mode
1832 */
1833static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1834/* Mic-in jack as CLFE */
1835 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1836 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1837/* Line-in jack as Surround */
1838 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1839 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1840/* Line-Out as Side */
1841 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1842 { } /* end */
1843};
1844
1845static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1846 { 2, alc888_4ST_ch2_intel_init },
1847 { 4, alc888_4ST_ch4_intel_init },
1848 { 6, alc888_4ST_ch6_intel_init },
1849 { 8, alc888_4ST_ch8_intel_init },
1850};
1851
1852/*
1853 * ALC888 Fujitsu Siemens Amillo xa3530
1854 */
1855
1856static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1857/* Front Mic: set to PIN_IN (empty by default) */
1858 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1859/* Connect Internal HP to Front */
1860 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1861 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1862 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1863/* Connect Bass HP to Front */
1864 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1865 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1866 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1867/* Connect Line-Out side jack (SPDIF) to Side */
1868 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1869 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1870 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1871/* Connect Mic jack to CLFE */
1872 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1873 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1874 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1875/* Connect Line-in jack to Surround */
1876 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1877 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1878 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1879/* Connect HP out jack to Front */
1880 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1881 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1882 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1883/* Enable unsolicited event for HP jack and Line-out jack */
1884 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1885 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1886 {}
1887};
1888
a9fd4f3f 1889static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1890{
bb35febd 1891 alc_automute_speaker(codec, 0);
ef8ef5fb
VP
1892}
1893
a9fd4f3f
TI
1894static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1895 unsigned int res)
ef8ef5fb 1896{
a9fd4f3f
TI
1897 if (codec->vendor_id == 0x10ec0880)
1898 res >>= 28;
1899 else
1900 res >>= 26;
1901 if (res == ALC880_HP_EVENT)
1902 alc_automute_amp(codec);
ef8ef5fb
VP
1903}
1904
4f5d1706 1905static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1906{
1907 struct alc_spec *spec = codec->spec;
1908
1909 spec->autocfg.hp_pins[0] = 0x15;
1910 spec->autocfg.speaker_pins[0] = 0x14;
1911 spec->autocfg.speaker_pins[1] = 0x16;
1912 spec->autocfg.speaker_pins[2] = 0x17;
1913 spec->autocfg.speaker_pins[3] = 0x19;
1914 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1915}
1916
1917static void alc889_intel_init_hook(struct hda_codec *codec)
1918{
1919 alc889_coef_init(codec);
4f5d1706 1920 alc_automute_amp(codec);
6732bd0d
WF
1921}
1922
4f5d1706 1923static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1924{
1925 struct alc_spec *spec = codec->spec;
1926
1927 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1928 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1929 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1930 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1931}
ef8ef5fb 1932
5b2d1eca
VP
1933/*
1934 * ALC888 Acer Aspire 4930G model
1935 */
1936
1937static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1938/* Front Mic: set to PIN_IN (empty by default) */
1939 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1940/* Unselect Front Mic by default in input mixer 3 */
1941 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1942/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1943 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1944/* Connect Internal HP to front */
1945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1946 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1947 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1948/* Connect HP out to front */
1949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1951 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1952 { }
1953};
1954
d2fd4b09
TV
1955/*
1956 * ALC888 Acer Aspire 6530G model
1957 */
1958
1959static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
1960/* Route to built-in subwoofer as well as speakers */
1961 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1962 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1963 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1964 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
1965/* Bias voltage on for external mic port */
1966 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1967/* Front Mic: set to PIN_IN (empty by default) */
1968 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1969/* Unselect Front Mic by default in input mixer 3 */
1970 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1971/* Enable unsolicited event for HP jack */
1972 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1973/* Enable speaker output */
1974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1975 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 1976 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1977/* Enable headphone output */
1978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1979 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1980 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 1981 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1982 { }
1983};
1984
3b315d70 1985/*
018df418 1986 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1987 */
1988
018df418 1989static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1990/* Front Mic: set to PIN_IN (empty by default) */
1991 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1992/* Unselect Front Mic by default in input mixer 3 */
1993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1994/* Enable unsolicited event for HP jack */
1995 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1996/* Connect Internal Front to Front */
1997 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1998 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1999 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2000/* Connect Internal Rear to Rear */
2001 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2002 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2003 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2004/* Connect Internal CLFE to CLFE */
2005 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2006 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2007 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2008/* Connect HP out to Front */
018df418 2009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2010 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2011 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2012/* Enable all DACs */
2013/* DAC DISABLE/MUTE 1? */
2014/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2015 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2016 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2017/* DAC DISABLE/MUTE 2? */
2018/* some bit here disables the other DACs. Init=0x4900 */
2019 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2020 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2021/* DMIC fix
2022 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2023 * which makes the stereo useless. However, either the mic or the ALC889
2024 * makes the signal become a difference/sum signal instead of standard
2025 * stereo, which is annoying. So instead we flip this bit which makes the
2026 * codec replicate the sum signal to both channels, turning it into a
2027 * normal mono mic.
2028 */
2029/* DMIC_CONTROL? Init value = 0x0001 */
2030 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2031 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2032 { }
2033};
2034
ef8ef5fb 2035static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2036 /* Front mic only available on one ADC */
2037 {
2038 .num_items = 4,
2039 .items = {
2040 { "Mic", 0x0 },
2041 { "Line", 0x2 },
2042 { "CD", 0x4 },
2043 { "Front Mic", 0xb },
2044 },
2045 },
2046 {
2047 .num_items = 3,
2048 .items = {
2049 { "Mic", 0x0 },
2050 { "Line", 0x2 },
2051 { "CD", 0x4 },
2052 },
2053 }
2054};
2055
d2fd4b09
TV
2056static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2057 /* Interal mic only available on one ADC */
2058 {
684a8842 2059 .num_items = 5,
d2fd4b09
TV
2060 .items = {
2061 { "Ext Mic", 0x0 },
684a8842 2062 { "Line In", 0x2 },
d2fd4b09 2063 { "CD", 0x4 },
684a8842 2064 { "Input Mix", 0xa },
d2fd4b09
TV
2065 { "Int Mic", 0xb },
2066 },
2067 },
2068 {
684a8842 2069 .num_items = 4,
d2fd4b09
TV
2070 .items = {
2071 { "Ext Mic", 0x0 },
684a8842 2072 { "Line In", 0x2 },
d2fd4b09 2073 { "CD", 0x4 },
684a8842 2074 { "Input Mix", 0xa },
d2fd4b09
TV
2075 },
2076 }
2077};
2078
018df418
HM
2079static struct hda_input_mux alc889_capture_sources[3] = {
2080 /* Digital mic only available on first "ADC" */
2081 {
2082 .num_items = 5,
2083 .items = {
2084 { "Mic", 0x0 },
2085 { "Line", 0x2 },
2086 { "CD", 0x4 },
2087 { "Front Mic", 0xb },
2088 { "Input Mix", 0xa },
2089 },
2090 },
2091 {
2092 .num_items = 4,
2093 .items = {
2094 { "Mic", 0x0 },
2095 { "Line", 0x2 },
2096 { "CD", 0x4 },
2097 { "Input Mix", 0xa },
2098 },
2099 },
2100 {
2101 .num_items = 4,
2102 .items = {
2103 { "Mic", 0x0 },
2104 { "Line", 0x2 },
2105 { "CD", 0x4 },
2106 { "Input Mix", 0xa },
2107 },
2108 }
2109};
2110
ef8ef5fb 2111static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2113 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2114 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2115 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2116 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2117 HDA_OUTPUT),
2118 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2119 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2120 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2121 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2122 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2123 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2124 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2128 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
2129 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2130 { } /* end */
2131};
2132
556eea9a
HM
2133static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2136 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2137 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2138 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2139 HDA_OUTPUT),
2140 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2141 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2142 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2143 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2144 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2146 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
2147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2148 { } /* end */
2149};
2150
2151
4f5d1706 2152static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2153{
a9fd4f3f 2154 struct alc_spec *spec = codec->spec;
5b2d1eca 2155
a9fd4f3f
TI
2156 spec->autocfg.hp_pins[0] = 0x15;
2157 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2158 spec->autocfg.speaker_pins[1] = 0x16;
2159 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2160}
2161
4f5d1706 2162static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2163{
2164 struct alc_spec *spec = codec->spec;
2165
2166 spec->autocfg.hp_pins[0] = 0x15;
2167 spec->autocfg.speaker_pins[0] = 0x14;
2168 spec->autocfg.speaker_pins[1] = 0x16;
2169 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2170}
2171
4f5d1706 2172static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2173{
2174 struct alc_spec *spec = codec->spec;
2175
2176 spec->autocfg.hp_pins[0] = 0x15;
2177 spec->autocfg.speaker_pins[0] = 0x14;
2178 spec->autocfg.speaker_pins[1] = 0x16;
2179 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2180}
2181
1da177e4 2182/*
e9edcee0
TI
2183 * ALC880 3-stack model
2184 *
2185 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2186 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2187 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2188 */
2189
e9edcee0
TI
2190static hda_nid_t alc880_dac_nids[4] = {
2191 /* front, rear, clfe, rear_surr */
2192 0x02, 0x05, 0x04, 0x03
2193};
2194
2195static hda_nid_t alc880_adc_nids[3] = {
2196 /* ADC0-2 */
2197 0x07, 0x08, 0x09,
2198};
2199
2200/* The datasheet says the node 0x07 is connected from inputs,
2201 * but it shows zero connection in the real implementation on some devices.
df694daa 2202 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2203 */
e9edcee0
TI
2204static hda_nid_t alc880_adc_nids_alt[2] = {
2205 /* ADC1-2 */
2206 0x08, 0x09,
2207};
2208
2209#define ALC880_DIGOUT_NID 0x06
2210#define ALC880_DIGIN_NID 0x0a
2211
2212static struct hda_input_mux alc880_capture_source = {
2213 .num_items = 4,
2214 .items = {
2215 { "Mic", 0x0 },
2216 { "Front Mic", 0x3 },
2217 { "Line", 0x2 },
2218 { "CD", 0x4 },
2219 },
2220};
2221
2222/* channel source setting (2/6 channel selection for 3-stack) */
2223/* 2ch mode */
2224static struct hda_verb alc880_threestack_ch2_init[] = {
2225 /* set line-in to input, mute it */
2226 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2227 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2228 /* set mic-in to input vref 80%, mute it */
2229 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2230 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2231 { } /* end */
2232};
2233
2234/* 6ch mode */
2235static struct hda_verb alc880_threestack_ch6_init[] = {
2236 /* set line-in to output, unmute it */
2237 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2238 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2239 /* set mic-in to output, unmute it */
2240 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2241 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2242 { } /* end */
2243};
2244
d2a6d7dc 2245static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2246 { 2, alc880_threestack_ch2_init },
2247 { 6, alc880_threestack_ch6_init },
2248};
2249
c8b6bf9b 2250static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2251 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2252 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2253 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2254 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2255 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2256 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2257 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2258 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2259 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2260 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2261 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2262 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2264 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2265 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2266 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2267 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2268 {
2269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2270 .name = "Channel Mode",
df694daa
KY
2271 .info = alc_ch_mode_info,
2272 .get = alc_ch_mode_get,
2273 .put = alc_ch_mode_put,
e9edcee0
TI
2274 },
2275 { } /* end */
2276};
2277
2278/* capture mixer elements */
f9e336f6
TI
2279static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2280 struct snd_ctl_elem_info *uinfo)
2281{
2282 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2283 struct alc_spec *spec = codec->spec;
2284 int err;
1da177e4 2285
5a9e02e9 2286 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2287 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2288 HDA_INPUT);
2289 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2290 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2291 return err;
2292}
2293
2294static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2295 unsigned int size, unsigned int __user *tlv)
2296{
2297 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2298 struct alc_spec *spec = codec->spec;
2299 int err;
1da177e4 2300
5a9e02e9 2301 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2302 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2303 HDA_INPUT);
2304 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2305 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2306 return err;
2307}
2308
2309typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2310 struct snd_ctl_elem_value *ucontrol);
2311
2312static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2313 struct snd_ctl_elem_value *ucontrol,
2314 getput_call_t func)
2315{
2316 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2317 struct alc_spec *spec = codec->spec;
2318 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2319 int err;
2320
5a9e02e9 2321 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2322 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2323 3, 0, HDA_INPUT);
2324 err = func(kcontrol, ucontrol);
5a9e02e9 2325 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2326 return err;
2327}
2328
2329static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2330 struct snd_ctl_elem_value *ucontrol)
2331{
2332 return alc_cap_getput_caller(kcontrol, ucontrol,
2333 snd_hda_mixer_amp_volume_get);
2334}
2335
2336static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2337 struct snd_ctl_elem_value *ucontrol)
2338{
2339 return alc_cap_getput_caller(kcontrol, ucontrol,
2340 snd_hda_mixer_amp_volume_put);
2341}
2342
2343/* capture mixer elements */
2344#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2345
2346static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2347 struct snd_ctl_elem_value *ucontrol)
2348{
2349 return alc_cap_getput_caller(kcontrol, ucontrol,
2350 snd_hda_mixer_amp_switch_get);
2351}
2352
2353static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2354 struct snd_ctl_elem_value *ucontrol)
2355{
2356 return alc_cap_getput_caller(kcontrol, ucontrol,
2357 snd_hda_mixer_amp_switch_put);
2358}
2359
a23b688f 2360#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2361 { \
2362 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2363 .name = "Capture Switch", \
2364 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2365 .count = num, \
2366 .info = alc_cap_sw_info, \
2367 .get = alc_cap_sw_get, \
2368 .put = alc_cap_sw_put, \
2369 }, \
2370 { \
2371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2372 .name = "Capture Volume", \
2373 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2374 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2375 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2376 .count = num, \
2377 .info = alc_cap_vol_info, \
2378 .get = alc_cap_vol_get, \
2379 .put = alc_cap_vol_put, \
2380 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2381 }
2382
2383#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2384 { \
2385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2386 /* .name = "Capture Source", */ \
2387 .name = "Input Source", \
2388 .count = num, \
2389 .info = alc_mux_enum_info, \
2390 .get = alc_mux_enum_get, \
2391 .put = alc_mux_enum_put, \
a23b688f
TI
2392 }
2393
2394#define DEFINE_CAPMIX(num) \
2395static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2396 _DEFINE_CAPMIX(num), \
2397 _DEFINE_CAPSRC(num), \
2398 { } /* end */ \
2399}
2400
2401#define DEFINE_CAPMIX_NOSRC(num) \
2402static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2403 _DEFINE_CAPMIX(num), \
2404 { } /* end */ \
f9e336f6
TI
2405}
2406
2407/* up to three ADCs */
2408DEFINE_CAPMIX(1);
2409DEFINE_CAPMIX(2);
2410DEFINE_CAPMIX(3);
a23b688f
TI
2411DEFINE_CAPMIX_NOSRC(1);
2412DEFINE_CAPMIX_NOSRC(2);
2413DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2414
2415/*
2416 * ALC880 5-stack model
2417 *
9c7f852e
TI
2418 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2419 * Side = 0x02 (0xd)
e9edcee0
TI
2420 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2421 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2422 */
2423
2424/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2425static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2426 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2427 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2428 { } /* end */
2429};
2430
e9edcee0
TI
2431/* channel source setting (6/8 channel selection for 5-stack) */
2432/* 6ch mode */
2433static struct hda_verb alc880_fivestack_ch6_init[] = {
2434 /* set line-in to input, mute it */
2435 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2436 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2437 { } /* end */
2438};
2439
e9edcee0
TI
2440/* 8ch mode */
2441static struct hda_verb alc880_fivestack_ch8_init[] = {
2442 /* set line-in to output, unmute it */
2443 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2444 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2445 { } /* end */
2446};
2447
d2a6d7dc 2448static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2449 { 6, alc880_fivestack_ch6_init },
2450 { 8, alc880_fivestack_ch8_init },
2451};
2452
2453
2454/*
2455 * ALC880 6-stack model
2456 *
9c7f852e
TI
2457 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2458 * Side = 0x05 (0x0f)
e9edcee0
TI
2459 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2460 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2461 */
2462
2463static hda_nid_t alc880_6st_dac_nids[4] = {
2464 /* front, rear, clfe, rear_surr */
2465 0x02, 0x03, 0x04, 0x05
f12ab1e0 2466};
e9edcee0
TI
2467
2468static struct hda_input_mux alc880_6stack_capture_source = {
2469 .num_items = 4,
2470 .items = {
2471 { "Mic", 0x0 },
2472 { "Front Mic", 0x1 },
2473 { "Line", 0x2 },
2474 { "CD", 0x4 },
2475 },
2476};
2477
2478/* fixed 8-channels */
d2a6d7dc 2479static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2480 { 8, NULL },
2481};
2482
c8b6bf9b 2483static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2484 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2485 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2486 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2487 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2488 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2489 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2490 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2491 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2492 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2493 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2494 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2495 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2496 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2497 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2498 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2499 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2500 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2501 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2502 {
2503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2504 .name = "Channel Mode",
df694daa
KY
2505 .info = alc_ch_mode_info,
2506 .get = alc_ch_mode_get,
2507 .put = alc_ch_mode_put,
16ded525
TI
2508 },
2509 { } /* end */
2510};
2511
e9edcee0
TI
2512
2513/*
2514 * ALC880 W810 model
2515 *
2516 * W810 has rear IO for:
2517 * Front (DAC 02)
2518 * Surround (DAC 03)
2519 * Center/LFE (DAC 04)
2520 * Digital out (06)
2521 *
2522 * The system also has a pair of internal speakers, and a headphone jack.
2523 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2524 *
e9edcee0
TI
2525 * There is a variable resistor to control the speaker or headphone
2526 * volume. This is a hardware-only device without a software API.
2527 *
2528 * Plugging headphones in will disable the internal speakers. This is
2529 * implemented in hardware, not via the driver using jack sense. In
2530 * a similar fashion, plugging into the rear socket marked "front" will
2531 * disable both the speakers and headphones.
2532 *
2533 * For input, there's a microphone jack, and an "audio in" jack.
2534 * These may not do anything useful with this driver yet, because I
2535 * haven't setup any initialization verbs for these yet...
2536 */
2537
2538static hda_nid_t alc880_w810_dac_nids[3] = {
2539 /* front, rear/surround, clfe */
2540 0x02, 0x03, 0x04
16ded525
TI
2541};
2542
e9edcee0 2543/* fixed 6 channels */
d2a6d7dc 2544static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2545 { 6, NULL }
2546};
2547
2548/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2549static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2550 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2551 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2552 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2553 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2554 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2555 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2556 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2557 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2559 { } /* end */
2560};
2561
2562
2563/*
2564 * Z710V model
2565 *
2566 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2567 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2568 * Line = 0x1a
e9edcee0
TI
2569 */
2570
2571static hda_nid_t alc880_z71v_dac_nids[1] = {
2572 0x02
2573};
2574#define ALC880_Z71V_HP_DAC 0x03
2575
2576/* fixed 2 channels */
d2a6d7dc 2577static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2578 { 2, NULL }
2579};
2580
c8b6bf9b 2581static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2582 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2583 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2584 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2585 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2586 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2587 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2590 { } /* end */
2591};
2592
e9edcee0 2593
e9edcee0
TI
2594/*
2595 * ALC880 F1734 model
2596 *
2597 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2598 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2599 */
2600
2601static hda_nid_t alc880_f1734_dac_nids[1] = {
2602 0x03
2603};
2604#define ALC880_F1734_HP_DAC 0x02
2605
c8b6bf9b 2606static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2607 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2608 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2609 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2610 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2611 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2612 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2615 { } /* end */
2616};
2617
937b4160
TI
2618static struct hda_input_mux alc880_f1734_capture_source = {
2619 .num_items = 2,
2620 .items = {
2621 { "Mic", 0x1 },
2622 { "CD", 0x4 },
2623 },
2624};
2625
e9edcee0 2626
e9edcee0
TI
2627/*
2628 * ALC880 ASUS model
2629 *
2630 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2631 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2632 * Mic = 0x18, Line = 0x1a
2633 */
2634
2635#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2636#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2637
c8b6bf9b 2638static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2639 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2640 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2641 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2642 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2643 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2644 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2645 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2646 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2647 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2648 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2649 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2650 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2652 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2653 {
2654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2655 .name = "Channel Mode",
df694daa
KY
2656 .info = alc_ch_mode_info,
2657 .get = alc_ch_mode_get,
2658 .put = alc_ch_mode_put,
16ded525
TI
2659 },
2660 { } /* end */
2661};
e9edcee0 2662
e9edcee0
TI
2663/*
2664 * ALC880 ASUS W1V model
2665 *
2666 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2667 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2668 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2669 */
2670
2671/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2672static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2673 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2674 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2675 { } /* end */
2676};
2677
df694daa
KY
2678/* TCL S700 */
2679static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2680 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2681 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2682 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2683 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2684 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2687 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2688 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2689 { } /* end */
2690};
2691
ccc656ce
KY
2692/* Uniwill */
2693static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2694 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2695 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2696 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2697 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2698 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2699 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2700 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2701 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2702 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2703 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2705 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2708 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2709 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2710 {
2711 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2712 .name = "Channel Mode",
2713 .info = alc_ch_mode_info,
2714 .get = alc_ch_mode_get,
2715 .put = alc_ch_mode_put,
2716 },
2717 { } /* end */
2718};
2719
2cf9f0fc
TD
2720static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
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),
2725 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2726 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2727 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2728 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2729 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2730 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2731 { } /* end */
2732};
2733
ccc656ce 2734static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2735 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2736 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2737 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2738 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2740 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2741 { } /* end */
2742};
2743
2134ea4f
TI
2744/*
2745 * virtual master controls
2746 */
2747
2748/*
2749 * slave controls for virtual master
2750 */
2751static const char *alc_slave_vols[] = {
2752 "Front Playback Volume",
2753 "Surround Playback Volume",
2754 "Center Playback Volume",
2755 "LFE Playback Volume",
2756 "Side Playback Volume",
2757 "Headphone Playback Volume",
2758 "Speaker Playback Volume",
2759 "Mono Playback Volume",
2134ea4f 2760 "Line-Out Playback Volume",
26f5df26 2761 "PCM Playback Volume",
2134ea4f
TI
2762 NULL,
2763};
2764
2765static const char *alc_slave_sws[] = {
2766 "Front Playback Switch",
2767 "Surround Playback Switch",
2768 "Center Playback Switch",
2769 "LFE Playback Switch",
2770 "Side Playback Switch",
2771 "Headphone Playback Switch",
2772 "Speaker Playback Switch",
2773 "Mono Playback Switch",
edb54a55 2774 "IEC958 Playback Switch",
23033b2b
TI
2775 "Line-Out Playback Switch",
2776 "PCM Playback Switch",
2134ea4f
TI
2777 NULL,
2778};
2779
1da177e4 2780/*
e9edcee0 2781 * build control elements
1da177e4 2782 */
603c4019 2783
5b0cb1d8
JK
2784#define NID_MAPPING (-1)
2785
2786#define SUBDEV_SPEAKER_ (0 << 6)
2787#define SUBDEV_HP_ (1 << 6)
2788#define SUBDEV_LINE_ (2 << 6)
2789#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2790#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2791#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2792
603c4019
TI
2793static void alc_free_kctls(struct hda_codec *codec);
2794
67d634c0 2795#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2796/* additional beep mixers; the actual parameters are overwritten at build */
2797static struct snd_kcontrol_new alc_beep_mixer[] = {
2798 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2799 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2800 { } /* end */
2801};
67d634c0 2802#endif
45bdd1c1 2803
1da177e4
LT
2804static int alc_build_controls(struct hda_codec *codec)
2805{
2806 struct alc_spec *spec = codec->spec;
2f44f847 2807 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2808 struct snd_kcontrol_new *knew;
2809 int i, j, err;
2810 unsigned int u;
2811 hda_nid_t nid;
1da177e4
LT
2812
2813 for (i = 0; i < spec->num_mixers; i++) {
2814 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2815 if (err < 0)
2816 return err;
2817 }
f9e336f6
TI
2818 if (spec->cap_mixer) {
2819 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2820 if (err < 0)
2821 return err;
2822 }
1da177e4 2823 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2824 err = snd_hda_create_spdif_out_ctls(codec,
2825 spec->multiout.dig_out_nid);
1da177e4
LT
2826 if (err < 0)
2827 return err;
e64f14f4
TI
2828 if (!spec->no_analog) {
2829 err = snd_hda_create_spdif_share_sw(codec,
2830 &spec->multiout);
2831 if (err < 0)
2832 return err;
2833 spec->multiout.share_spdif = 1;
2834 }
1da177e4
LT
2835 }
2836 if (spec->dig_in_nid) {
2837 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2838 if (err < 0)
2839 return err;
2840 }
2134ea4f 2841
67d634c0 2842#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2843 /* create beep controls if needed */
2844 if (spec->beep_amp) {
2845 struct snd_kcontrol_new *knew;
2846 for (knew = alc_beep_mixer; knew->name; knew++) {
2847 struct snd_kcontrol *kctl;
2848 kctl = snd_ctl_new1(knew, codec);
2849 if (!kctl)
2850 return -ENOMEM;
2851 kctl->private_value = spec->beep_amp;
5e26dfd0 2852 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2853 if (err < 0)
2854 return err;
2855 }
2856 }
67d634c0 2857#endif
45bdd1c1 2858
2134ea4f 2859 /* if we have no master control, let's create it */
e64f14f4
TI
2860 if (!spec->no_analog &&
2861 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2862 unsigned int vmaster_tlv[4];
2134ea4f 2863 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2864 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2865 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2866 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2867 if (err < 0)
2868 return err;
2869 }
e64f14f4
TI
2870 if (!spec->no_analog &&
2871 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2872 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2873 NULL, alc_slave_sws);
2874 if (err < 0)
2875 return err;
2876 }
2877
5b0cb1d8 2878 /* assign Capture Source enums to NID */
fbe618f2
TI
2879 if (spec->capsrc_nids || spec->adc_nids) {
2880 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2881 if (!kctl)
2882 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2883 for (i = 0; kctl && i < kctl->count; i++) {
2884 hda_nid_t *nids = spec->capsrc_nids;
2885 if (!nids)
2886 nids = spec->adc_nids;
2887 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2888 if (err < 0)
2889 return err;
2890 }
5b0cb1d8
JK
2891 }
2892 if (spec->cap_mixer) {
2893 const char *kname = kctl ? kctl->id.name : NULL;
2894 for (knew = spec->cap_mixer; knew->name; knew++) {
2895 if (kname && strcmp(knew->name, kname) == 0)
2896 continue;
2897 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2898 for (i = 0; kctl && i < kctl->count; i++) {
2899 err = snd_hda_add_nid(codec, kctl, i,
2900 spec->adc_nids[i]);
2901 if (err < 0)
2902 return err;
2903 }
2904 }
2905 }
2906
2907 /* other nid->control mapping */
2908 for (i = 0; i < spec->num_mixers; i++) {
2909 for (knew = spec->mixers[i]; knew->name; knew++) {
2910 if (knew->iface != NID_MAPPING)
2911 continue;
2912 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2913 if (kctl == NULL)
2914 continue;
2915 u = knew->subdevice;
2916 for (j = 0; j < 4; j++, u >>= 8) {
2917 nid = u & 0x3f;
2918 if (nid == 0)
2919 continue;
2920 switch (u & 0xc0) {
2921 case SUBDEV_SPEAKER_:
2922 nid = spec->autocfg.speaker_pins[nid];
2923 break;
2924 case SUBDEV_LINE_:
2925 nid = spec->autocfg.line_out_pins[nid];
2926 break;
2927 case SUBDEV_HP_:
2928 nid = spec->autocfg.hp_pins[nid];
2929 break;
2930 default:
2931 continue;
2932 }
2933 err = snd_hda_add_nid(codec, kctl, 0, nid);
2934 if (err < 0)
2935 return err;
2936 }
2937 u = knew->private_value;
2938 for (j = 0; j < 4; j++, u >>= 8) {
2939 nid = u & 0xff;
2940 if (nid == 0)
2941 continue;
2942 err = snd_hda_add_nid(codec, kctl, 0, nid);
2943 if (err < 0)
2944 return err;
2945 }
2946 }
2947 }
bae84e70
TI
2948
2949 alc_free_kctls(codec); /* no longer needed */
2950
1da177e4
LT
2951 return 0;
2952}
2953
e9edcee0 2954
1da177e4
LT
2955/*
2956 * initialize the codec volumes, etc
2957 */
2958
e9edcee0
TI
2959/*
2960 * generic initialization of ADC, input mixers and output mixers
2961 */
2962static struct hda_verb alc880_volume_init_verbs[] = {
2963 /*
2964 * Unmute ADC0-2 and set the default input to mic-in
2965 */
71fe7b82 2966 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2968 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2969 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2970 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2971 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2972
e9edcee0
TI
2973 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2974 * mixer widget
9c7f852e
TI
2975 * Note: PASD motherboards uses the Line In 2 as the input for front
2976 * panel mic (mic 2)
1da177e4 2977 */
e9edcee0 2978 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2979 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2980 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2981 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2982 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2983 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2984 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2985 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2986
e9edcee0
TI
2987 /*
2988 * Set up output mixers (0x0c - 0x0f)
1da177e4 2989 */
e9edcee0
TI
2990 /* set vol=0 to output mixers */
2991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2993 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2994 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2995 /* set up input amps for analog loopback */
2996 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2997 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2999 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3000 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3001 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3002 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3003 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3004 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3005
3006 { }
3007};
3008
e9edcee0
TI
3009/*
3010 * 3-stack pin configuration:
3011 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3012 */
3013static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3014 /*
3015 * preset connection lists of input pins
3016 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3017 */
3018 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3019 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3020 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3021
3022 /*
3023 * Set pin mode and muting
3024 */
3025 /* set front pin widgets 0x14 for output */
05acb863 3026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3027 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3028 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3029 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3030 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3031 /* Mic2 (as headphone out) for HP output */
3032 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3033 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3034 /* Line In pin widget for input */
05acb863 3035 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3036 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3037 /* Line2 (as front mic) pin widget for input and vref at 80% */
3038 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3039 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3040 /* CD pin widget for input */
05acb863 3041 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3042
e9edcee0
TI
3043 { }
3044};
1da177e4 3045
e9edcee0
TI
3046/*
3047 * 5-stack pin configuration:
3048 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3049 * line-in/side = 0x1a, f-mic = 0x1b
3050 */
3051static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3052 /*
3053 * preset connection lists of input pins
3054 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3055 */
e9edcee0
TI
3056 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3057 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3058
e9edcee0
TI
3059 /*
3060 * Set pin mode and muting
1da177e4 3061 */
e9edcee0
TI
3062 /* set pin widgets 0x14-0x17 for output */
3063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3065 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3066 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3067 /* unmute pins for output (no gain on this amp) */
3068 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3069 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3070 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3071 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3072
3073 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3074 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3075 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3076 /* Mic2 (as headphone out) for HP output */
3077 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3078 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3079 /* Line In pin widget for input */
3080 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3081 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3082 /* Line2 (as front mic) pin widget for input and vref at 80% */
3083 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3085 /* CD pin widget for input */
3086 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3087
3088 { }
3089};
3090
e9edcee0
TI
3091/*
3092 * W810 pin configuration:
3093 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3094 */
3095static struct hda_verb alc880_pin_w810_init_verbs[] = {
3096 /* hphone/speaker input selector: front DAC */
3097 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3098
05acb863 3099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3100 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3101 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3102 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3103 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3104 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3105
e9edcee0 3106 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3107 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3108
1da177e4
LT
3109 { }
3110};
3111
e9edcee0
TI
3112/*
3113 * Z71V pin configuration:
3114 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3115 */
3116static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3120 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3121
16ded525 3122 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3123 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3124 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3125 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3126
3127 { }
3128};
3129
e9edcee0
TI
3130/*
3131 * 6-stack pin configuration:
9c7f852e
TI
3132 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3133 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3134 */
3135static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3136 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3137
16ded525 3138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3141 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3142 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3143 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3144 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3145 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3146
16ded525 3147 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3148 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3149 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3150 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3152 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3153 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3154 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3155 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3156
e9edcee0
TI
3157 { }
3158};
3159
ccc656ce
KY
3160/*
3161 * Uniwill pin configuration:
3162 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3163 * line = 0x1a
3164 */
3165static struct hda_verb alc880_uniwill_init_verbs[] = {
3166 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3167
3168 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3169 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3170 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3171 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3172 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3173 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3174 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3175 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3176 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3177 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3178 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3179 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3180 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3182
3183 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3184 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3185 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3186 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3187 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3188 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3189 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3190 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3191 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3192
3193 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3194 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3195
3196 { }
3197};
3198
3199/*
3200* Uniwill P53
ea1fb29a 3201* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3202 */
3203static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3204 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3205
3206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3209 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3210 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3211 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3214 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3215 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3216 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3217 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3218
3219 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3220 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3221 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3222 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3223 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3224 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3225
3226 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3227 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3228
3229 { }
3230};
3231
2cf9f0fc
TD
3232static struct hda_verb alc880_beep_init_verbs[] = {
3233 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3234 { }
3235};
3236
458a4fab
TI
3237/* auto-toggle front mic */
3238static void alc880_uniwill_mic_automute(struct hda_codec *codec)
3239{
3240 unsigned int present;
3241 unsigned char bits;
ccc656ce 3242
864f92be 3243 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3244 bits = present ? HDA_AMP_MUTE : 0;
3245 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3246}
3247
4f5d1706 3248static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3249{
a9fd4f3f
TI
3250 struct alc_spec *spec = codec->spec;
3251
3252 spec->autocfg.hp_pins[0] = 0x14;
3253 spec->autocfg.speaker_pins[0] = 0x15;
3254 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3255}
3256
3257static void alc880_uniwill_init_hook(struct hda_codec *codec)
3258{
a9fd4f3f 3259 alc_automute_amp(codec);
458a4fab 3260 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
3261}
3262
3263static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3264 unsigned int res)
3265{
3266 /* Looks like the unsol event is incompatible with the standard
3267 * definition. 4bit tag is placed at 28 bit!
3268 */
458a4fab 3269 switch (res >> 28) {
458a4fab
TI
3270 case ALC880_MIC_EVENT:
3271 alc880_uniwill_mic_automute(codec);
3272 break;
a9fd4f3f
TI
3273 default:
3274 alc_automute_amp_unsol_event(codec, res);
3275 break;
458a4fab 3276 }
ccc656ce
KY
3277}
3278
4f5d1706 3279static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3280{
a9fd4f3f 3281 struct alc_spec *spec = codec->spec;
ccc656ce 3282
a9fd4f3f
TI
3283 spec->autocfg.hp_pins[0] = 0x14;
3284 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3285}
3286
3287static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3288{
3289 unsigned int present;
ea1fb29a 3290
ccc656ce 3291 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3292 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3293 present &= HDA_AMP_VOLMASK;
3294 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3295 HDA_AMP_VOLMASK, present);
3296 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3297 HDA_AMP_VOLMASK, present);
ccc656ce 3298}
47fd830a 3299
ccc656ce
KY
3300static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3301 unsigned int res)
3302{
3303 /* Looks like the unsol event is incompatible with the standard
3304 * definition. 4bit tag is placed at 28 bit!
3305 */
f12ab1e0 3306 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3307 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3308 else
3309 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3310}
3311
e9edcee0
TI
3312/*
3313 * F1734 pin configuration:
3314 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3315 */
3316static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3317 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3318 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3319 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3320 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3321 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3322
e9edcee0 3323 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3324 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3327
e9edcee0
TI
3328 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3329 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3330 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3331 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3332 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3333 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3334 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3335 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3336 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3337
937b4160
TI
3338 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3339 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3340
dfc0ff62
TI
3341 { }
3342};
3343
e9edcee0
TI
3344/*
3345 * ASUS pin configuration:
3346 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3347 */
3348static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3349 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3350 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3351 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3352 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3353
3354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3355 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3356 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3358 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3359 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3360 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3361 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3362
3363 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3365 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3366 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3367 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3368 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3369 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3370 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3371 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3372
e9edcee0
TI
3373 { }
3374};
16ded525 3375
e9edcee0 3376/* Enable GPIO mask and set output */
bc9f98a9
KY
3377#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3378#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3379#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3380
3381/* Clevo m520g init */
3382static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3383 /* headphone output */
3384 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3385 /* line-out */
3386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3387 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3388 /* Line-in */
3389 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3390 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3391 /* CD */
3392 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3393 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3394 /* Mic1 (rear panel) */
3395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3397 /* Mic2 (front panel) */
3398 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3399 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3400 /* headphone */
3401 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3402 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3403 /* change to EAPD mode */
3404 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3405 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3406
3407 { }
16ded525
TI
3408};
3409
df694daa 3410static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3411 /* change to EAPD mode */
3412 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3413 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3414
df694daa
KY
3415 /* Headphone output */
3416 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3417 /* Front output*/
3418 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3419 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3420
3421 /* Line In pin widget for input */
3422 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3423 /* CD pin widget for input */
3424 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3425 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3426 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3427
3428 /* change to EAPD mode */
3429 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3430 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3431
3432 { }
3433};
16ded525 3434
e9edcee0 3435/*
ae6b813a
TI
3436 * LG m1 express dual
3437 *
3438 * Pin assignment:
3439 * Rear Line-In/Out (blue): 0x14
3440 * Build-in Mic-In: 0x15
3441 * Speaker-out: 0x17
3442 * HP-Out (green): 0x1b
3443 * Mic-In/Out (red): 0x19
3444 * SPDIF-Out: 0x1e
3445 */
3446
3447/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3448static hda_nid_t alc880_lg_dac_nids[3] = {
3449 0x05, 0x02, 0x03
3450};
3451
3452/* seems analog CD is not working */
3453static struct hda_input_mux alc880_lg_capture_source = {
3454 .num_items = 3,
3455 .items = {
3456 { "Mic", 0x1 },
3457 { "Line", 0x5 },
3458 { "Internal Mic", 0x6 },
3459 },
3460};
3461
3462/* 2,4,6 channel modes */
3463static struct hda_verb alc880_lg_ch2_init[] = {
3464 /* set line-in and mic-in to input */
3465 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3466 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3467 { }
3468};
3469
3470static struct hda_verb alc880_lg_ch4_init[] = {
3471 /* set line-in to out and mic-in to input */
3472 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3473 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3474 { }
3475};
3476
3477static struct hda_verb alc880_lg_ch6_init[] = {
3478 /* set line-in and mic-in to output */
3479 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3480 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3481 { }
3482};
3483
3484static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3485 { 2, alc880_lg_ch2_init },
3486 { 4, alc880_lg_ch4_init },
3487 { 6, alc880_lg_ch6_init },
3488};
3489
3490static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3491 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3492 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3493 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3494 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3495 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3496 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3497 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3498 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3500 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3501 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3502 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3503 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3504 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3505 {
3506 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3507 .name = "Channel Mode",
3508 .info = alc_ch_mode_info,
3509 .get = alc_ch_mode_get,
3510 .put = alc_ch_mode_put,
3511 },
3512 { } /* end */
3513};
3514
3515static struct hda_verb alc880_lg_init_verbs[] = {
3516 /* set capture source to mic-in */
3517 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3518 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3519 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3520 /* mute all amp mixer inputs */
3521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3524 /* line-in to input */
3525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3526 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3527 /* built-in mic */
3528 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3529 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3530 /* speaker-out */
3531 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3532 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3533 /* mic-in to input */
3534 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3535 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3536 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3537 /* HP-out */
3538 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3539 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3540 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541 /* jack sense */
a9fd4f3f 3542 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3543 { }
3544};
3545
3546/* toggle speaker-output according to the hp-jack state */
4f5d1706 3547static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3548{
a9fd4f3f 3549 struct alc_spec *spec = codec->spec;
ae6b813a 3550
a9fd4f3f
TI
3551 spec->autocfg.hp_pins[0] = 0x1b;
3552 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3553}
3554
d681518a
TI
3555/*
3556 * LG LW20
3557 *
3558 * Pin assignment:
3559 * Speaker-out: 0x14
3560 * Mic-In: 0x18
e4f41da9
CM
3561 * Built-in Mic-In: 0x19
3562 * Line-In: 0x1b
3563 * HP-Out: 0x1a
d681518a
TI
3564 * SPDIF-Out: 0x1e
3565 */
3566
d681518a 3567static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3568 .num_items = 3,
d681518a
TI
3569 .items = {
3570 { "Mic", 0x0 },
3571 { "Internal Mic", 0x1 },
e4f41da9 3572 { "Line In", 0x2 },
d681518a
TI
3573 },
3574};
3575
0a8c5da3
CM
3576#define alc880_lg_lw_modes alc880_threestack_modes
3577
d681518a 3578static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3579 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3580 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3581 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3582 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3583 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3584 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3585 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3586 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3587 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3588 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3589 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3591 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3592 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3593 {
3594 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3595 .name = "Channel Mode",
3596 .info = alc_ch_mode_info,
3597 .get = alc_ch_mode_get,
3598 .put = alc_ch_mode_put,
3599 },
d681518a
TI
3600 { } /* end */
3601};
3602
3603static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3604 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3605 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3606 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3607
d681518a
TI
3608 /* set capture source to mic-in */
3609 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3610 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3611 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3612 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3613 /* speaker-out */
3614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3615 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3616 /* HP-out */
d681518a
TI
3617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3618 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3619 /* mic-in to input */
3620 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3621 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3622 /* built-in mic */
3623 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3624 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3625 /* jack sense */
a9fd4f3f 3626 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3627 { }
3628};
3629
3630/* toggle speaker-output according to the hp-jack state */
4f5d1706 3631static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3632{
a9fd4f3f 3633 struct alc_spec *spec = codec->spec;
d681518a 3634
a9fd4f3f
TI
3635 spec->autocfg.hp_pins[0] = 0x1b;
3636 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3637}
3638
df99cd33
TI
3639static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3640 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3641 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3642 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3643 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3644 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3645 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3646 { } /* end */
3647};
3648
3649static struct hda_input_mux alc880_medion_rim_capture_source = {
3650 .num_items = 2,
3651 .items = {
3652 { "Mic", 0x0 },
3653 { "Internal Mic", 0x1 },
3654 },
3655};
3656
3657static struct hda_verb alc880_medion_rim_init_verbs[] = {
3658 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3659
3660 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3661 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3662
3663 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3666 /* Mic2 (as headphone out) for HP output */
3667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3669 /* Internal Speaker */
3670 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3671 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3672
3673 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3674 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3675
3676 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3677 { }
3678};
3679
3680/* toggle speaker-output according to the hp-jack state */
3681static void alc880_medion_rim_automute(struct hda_codec *codec)
3682{
a9fd4f3f
TI
3683 struct alc_spec *spec = codec->spec;
3684 alc_automute_amp(codec);
3685 /* toggle EAPD */
3686 if (spec->jack_present)
df99cd33
TI
3687 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3688 else
3689 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3690}
3691
3692static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3693 unsigned int res)
3694{
3695 /* Looks like the unsol event is incompatible with the standard
3696 * definition. 4bit tag is placed at 28 bit!
3697 */
3698 if ((res >> 28) == ALC880_HP_EVENT)
3699 alc880_medion_rim_automute(codec);
3700}
3701
4f5d1706 3702static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3703{
3704 struct alc_spec *spec = codec->spec;
3705
3706 spec->autocfg.hp_pins[0] = 0x14;
3707 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3708}
3709
cb53c626
TI
3710#ifdef CONFIG_SND_HDA_POWER_SAVE
3711static struct hda_amp_list alc880_loopbacks[] = {
3712 { 0x0b, HDA_INPUT, 0 },
3713 { 0x0b, HDA_INPUT, 1 },
3714 { 0x0b, HDA_INPUT, 2 },
3715 { 0x0b, HDA_INPUT, 3 },
3716 { 0x0b, HDA_INPUT, 4 },
3717 { } /* end */
3718};
3719
3720static struct hda_amp_list alc880_lg_loopbacks[] = {
3721 { 0x0b, HDA_INPUT, 1 },
3722 { 0x0b, HDA_INPUT, 6 },
3723 { 0x0b, HDA_INPUT, 7 },
3724 { } /* end */
3725};
3726#endif
3727
ae6b813a
TI
3728/*
3729 * Common callbacks
e9edcee0
TI
3730 */
3731
1da177e4
LT
3732static int alc_init(struct hda_codec *codec)
3733{
3734 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3735 unsigned int i;
3736
2c3bf9ab 3737 alc_fix_pll(codec);
4a79ba34 3738 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3739
e9edcee0
TI
3740 for (i = 0; i < spec->num_init_verbs; i++)
3741 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3742
3743 if (spec->init_hook)
3744 spec->init_hook(codec);
3745
9e5341b9 3746 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
3747 return 0;
3748}
3749
ae6b813a
TI
3750static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3751{
3752 struct alc_spec *spec = codec->spec;
3753
3754 if (spec->unsol_event)
3755 spec->unsol_event(codec, res);
3756}
3757
cb53c626
TI
3758#ifdef CONFIG_SND_HDA_POWER_SAVE
3759static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3760{
3761 struct alc_spec *spec = codec->spec;
3762 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3763}
3764#endif
3765
1da177e4
LT
3766/*
3767 * Analog playback callbacks
3768 */
3769static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3770 struct hda_codec *codec,
c8b6bf9b 3771 struct snd_pcm_substream *substream)
1da177e4
LT
3772{
3773 struct alc_spec *spec = codec->spec;
9a08160b
TI
3774 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3775 hinfo);
1da177e4
LT
3776}
3777
3778static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3779 struct hda_codec *codec,
3780 unsigned int stream_tag,
3781 unsigned int format,
c8b6bf9b 3782 struct snd_pcm_substream *substream)
1da177e4
LT
3783{
3784 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3785 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3786 stream_tag, format, substream);
1da177e4
LT
3787}
3788
3789static int alc880_playback_pcm_cleanup(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_analog_cleanup(codec, &spec->multiout);
3795}
3796
3797/*
3798 * Digital out
3799 */
3800static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3801 struct hda_codec *codec,
c8b6bf9b 3802 struct snd_pcm_substream *substream)
1da177e4
LT
3803{
3804 struct alc_spec *spec = codec->spec;
3805 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3806}
3807
6b97eb45
TI
3808static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3809 struct hda_codec *codec,
3810 unsigned int stream_tag,
3811 unsigned int format,
3812 struct snd_pcm_substream *substream)
3813{
3814 struct alc_spec *spec = codec->spec;
3815 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3816 stream_tag, format, substream);
3817}
3818
9b5f12e5
TI
3819static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3820 struct hda_codec *codec,
3821 struct snd_pcm_substream *substream)
3822{
3823 struct alc_spec *spec = codec->spec;
3824 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3825}
3826
1da177e4
LT
3827static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3828 struct hda_codec *codec,
c8b6bf9b 3829 struct snd_pcm_substream *substream)
1da177e4
LT
3830{
3831 struct alc_spec *spec = codec->spec;
3832 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3833}
3834
3835/*
3836 * Analog capture
3837 */
6330079f 3838static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3839 struct hda_codec *codec,
3840 unsigned int stream_tag,
3841 unsigned int format,
c8b6bf9b 3842 struct snd_pcm_substream *substream)
1da177e4
LT
3843{
3844 struct alc_spec *spec = codec->spec;
3845
6330079f 3846 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3847 stream_tag, 0, format);
3848 return 0;
3849}
3850
6330079f 3851static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3852 struct hda_codec *codec,
c8b6bf9b 3853 struct snd_pcm_substream *substream)
1da177e4
LT
3854{
3855 struct alc_spec *spec = codec->spec;
3856
888afa15
TI
3857 snd_hda_codec_cleanup_stream(codec,
3858 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3859 return 0;
3860}
3861
840b64c0
TI
3862/* analog capture with dynamic dual-adc changes */
3863static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3864 struct hda_codec *codec,
3865 unsigned int stream_tag,
3866 unsigned int format,
3867 struct snd_pcm_substream *substream)
3868{
3869 struct alc_spec *spec = codec->spec;
3870 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3871 spec->cur_adc_stream_tag = stream_tag;
3872 spec->cur_adc_format = format;
3873 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3874 return 0;
3875}
3876
3877static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3878 struct hda_codec *codec,
3879 struct snd_pcm_substream *substream)
3880{
3881 struct alc_spec *spec = codec->spec;
3882 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3883 spec->cur_adc = 0;
3884 return 0;
3885}
3886
3887static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3888 .substreams = 1,
3889 .channels_min = 2,
3890 .channels_max = 2,
3891 .nid = 0, /* fill later */
3892 .ops = {
3893 .prepare = dualmic_capture_pcm_prepare,
3894 .cleanup = dualmic_capture_pcm_cleanup
3895 },
3896};
1da177e4
LT
3897
3898/*
3899 */
3900static struct hda_pcm_stream alc880_pcm_analog_playback = {
3901 .substreams = 1,
3902 .channels_min = 2,
3903 .channels_max = 8,
e9edcee0 3904 /* NID is set in alc_build_pcms */
1da177e4
LT
3905 .ops = {
3906 .open = alc880_playback_pcm_open,
3907 .prepare = alc880_playback_pcm_prepare,
3908 .cleanup = alc880_playback_pcm_cleanup
3909 },
3910};
3911
3912static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3913 .substreams = 1,
3914 .channels_min = 2,
3915 .channels_max = 2,
3916 /* NID is set in alc_build_pcms */
3917};
3918
3919static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3920 .substreams = 1,
3921 .channels_min = 2,
3922 .channels_max = 2,
3923 /* NID is set in alc_build_pcms */
3924};
3925
3926static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3927 .substreams = 2, /* can be overridden */
1da177e4
LT
3928 .channels_min = 2,
3929 .channels_max = 2,
e9edcee0 3930 /* NID is set in alc_build_pcms */
1da177e4 3931 .ops = {
6330079f
TI
3932 .prepare = alc880_alt_capture_pcm_prepare,
3933 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3934 },
3935};
3936
3937static struct hda_pcm_stream alc880_pcm_digital_playback = {
3938 .substreams = 1,
3939 .channels_min = 2,
3940 .channels_max = 2,
3941 /* NID is set in alc_build_pcms */
3942 .ops = {
3943 .open = alc880_dig_playback_pcm_open,
6b97eb45 3944 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3945 .prepare = alc880_dig_playback_pcm_prepare,
3946 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3947 },
3948};
3949
3950static struct hda_pcm_stream alc880_pcm_digital_capture = {
3951 .substreams = 1,
3952 .channels_min = 2,
3953 .channels_max = 2,
3954 /* NID is set in alc_build_pcms */
3955};
3956
4c5186ed 3957/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3958static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3959 .substreams = 0,
3960 .channels_min = 0,
3961 .channels_max = 0,
3962};
3963
1da177e4
LT
3964static int alc_build_pcms(struct hda_codec *codec)
3965{
3966 struct alc_spec *spec = codec->spec;
3967 struct hda_pcm *info = spec->pcm_rec;
3968 int i;
3969
3970 codec->num_pcms = 1;
3971 codec->pcm_info = info;
3972
e64f14f4
TI
3973 if (spec->no_analog)
3974 goto skip_analog;
3975
812a2cca
TI
3976 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3977 "%s Analog", codec->chip_name);
1da177e4 3978 info->name = spec->stream_name_analog;
274693f3 3979
4a471b7d 3980 if (spec->stream_analog_playback) {
da3cec35
TI
3981 if (snd_BUG_ON(!spec->multiout.dac_nids))
3982 return -EINVAL;
4a471b7d
TI
3983 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3984 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3985 }
3986 if (spec->stream_analog_capture) {
da3cec35
TI
3987 if (snd_BUG_ON(!spec->adc_nids))
3988 return -EINVAL;
4a471b7d
TI
3989 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3990 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3991 }
3992
3993 if (spec->channel_mode) {
3994 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3995 for (i = 0; i < spec->num_channel_mode; i++) {
3996 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3997 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3998 }
1da177e4
LT
3999 }
4000 }
4001
e64f14f4 4002 skip_analog:
e08a007d 4003 /* SPDIF for stream index #1 */
1da177e4 4004 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4005 snprintf(spec->stream_name_digital,
4006 sizeof(spec->stream_name_digital),
4007 "%s Digital", codec->chip_name);
e08a007d 4008 codec->num_pcms = 2;
b25c9da1 4009 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4010 info = spec->pcm_rec + 1;
1da177e4 4011 info->name = spec->stream_name_digital;
8c441982
TI
4012 if (spec->dig_out_type)
4013 info->pcm_type = spec->dig_out_type;
4014 else
4015 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4016 if (spec->multiout.dig_out_nid &&
4017 spec->stream_digital_playback) {
1da177e4
LT
4018 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4019 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4020 }
4a471b7d
TI
4021 if (spec->dig_in_nid &&
4022 spec->stream_digital_capture) {
1da177e4
LT
4023 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4024 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4025 }
963f803f
TI
4026 /* FIXME: do we need this for all Realtek codec models? */
4027 codec->spdif_status_reset = 1;
1da177e4
LT
4028 }
4029
e64f14f4
TI
4030 if (spec->no_analog)
4031 return 0;
4032
e08a007d
TI
4033 /* If the use of more than one ADC is requested for the current
4034 * model, configure a second analog capture-only PCM.
4035 */
4036 /* Additional Analaog capture for index #2 */
6330079f
TI
4037 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4038 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4039 codec->num_pcms = 3;
c06134d7 4040 info = spec->pcm_rec + 2;
e08a007d 4041 info->name = spec->stream_name_analog;
6330079f
TI
4042 if (spec->alt_dac_nid) {
4043 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4044 *spec->stream_analog_alt_playback;
4045 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4046 spec->alt_dac_nid;
4047 } else {
4048 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4049 alc_pcm_null_stream;
4050 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4051 }
4052 if (spec->num_adc_nids > 1) {
4053 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4054 *spec->stream_analog_alt_capture;
4055 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4056 spec->adc_nids[1];
4057 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4058 spec->num_adc_nids - 1;
4059 } else {
4060 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4061 alc_pcm_null_stream;
4062 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4063 }
4064 }
4065
1da177e4
LT
4066 return 0;
4067}
4068
a4e09aa3
TI
4069static inline void alc_shutup(struct hda_codec *codec)
4070{
4071 snd_hda_shutup_pins(codec);
4072}
4073
603c4019
TI
4074static void alc_free_kctls(struct hda_codec *codec)
4075{
4076 struct alc_spec *spec = codec->spec;
4077
4078 if (spec->kctls.list) {
4079 struct snd_kcontrol_new *kctl = spec->kctls.list;
4080 int i;
4081 for (i = 0; i < spec->kctls.used; i++)
4082 kfree(kctl[i].name);
4083 }
4084 snd_array_free(&spec->kctls);
4085}
4086
1da177e4
LT
4087static void alc_free(struct hda_codec *codec)
4088{
e9edcee0 4089 struct alc_spec *spec = codec->spec;
e9edcee0 4090
f12ab1e0 4091 if (!spec)
e9edcee0
TI
4092 return;
4093
a4e09aa3 4094 alc_shutup(codec);
603c4019 4095 alc_free_kctls(codec);
e9edcee0 4096 kfree(spec);
680cd536 4097 snd_hda_detach_beep_device(codec);
1da177e4
LT
4098}
4099
f5de24b0 4100#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4101static void alc_power_eapd(struct hda_codec *codec)
4102{
4103 /* We currently only handle front, HP */
4104 switch (codec->vendor_id) {
4105 case 0x10ec0260:
9e4c8496
TI
4106 set_eapd(codec, 0x0f, 0);
4107 set_eapd(codec, 0x10, 0);
c97259df
DC
4108 break;
4109 case 0x10ec0262:
4110 case 0x10ec0267:
4111 case 0x10ec0268:
4112 case 0x10ec0269:
9e4c8496 4113 case 0x10ec0270:
c97259df
DC
4114 case 0x10ec0272:
4115 case 0x10ec0660:
4116 case 0x10ec0662:
4117 case 0x10ec0663:
4118 case 0x10ec0862:
4119 case 0x10ec0889:
9e4c8496
TI
4120 set_eapd(codec, 0x14, 0);
4121 set_eapd(codec, 0x15, 0);
c97259df
DC
4122 break;
4123 }
4124}
4125
f5de24b0
HM
4126static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4127{
4128 struct alc_spec *spec = codec->spec;
a4e09aa3 4129 alc_shutup(codec);
f5de24b0 4130 if (spec && spec->power_hook)
c97259df 4131 spec->power_hook(codec);
f5de24b0
HM
4132 return 0;
4133}
4134#endif
4135
e044c39a 4136#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4137static int alc_resume(struct hda_codec *codec)
4138{
e044c39a
TI
4139 codec->patch_ops.init(codec);
4140 snd_hda_codec_resume_amp(codec);
4141 snd_hda_codec_resume_cache(codec);
9e5341b9 4142 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4143 return 0;
4144}
e044c39a
TI
4145#endif
4146
1da177e4
LT
4147/*
4148 */
4149static struct hda_codec_ops alc_patch_ops = {
4150 .build_controls = alc_build_controls,
4151 .build_pcms = alc_build_pcms,
4152 .init = alc_init,
4153 .free = alc_free,
ae6b813a 4154 .unsol_event = alc_unsol_event,
e044c39a
TI
4155#ifdef SND_HDA_NEEDS_RESUME
4156 .resume = alc_resume,
4157#endif
cb53c626 4158#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4159 .suspend = alc_suspend,
cb53c626
TI
4160 .check_power_status = alc_check_power_status,
4161#endif
c97259df 4162 .reboot_notify = alc_shutup,
1da177e4
LT
4163};
4164
c027ddcd
KY
4165/* replace the codec chip_name with the given string */
4166static int alc_codec_rename(struct hda_codec *codec, const char *name)
4167{
4168 kfree(codec->chip_name);
4169 codec->chip_name = kstrdup(name, GFP_KERNEL);
4170 if (!codec->chip_name) {
4171 alc_free(codec);
4172 return -ENOMEM;
4173 }
4174 return 0;
4175}
4176
2fa522be
TI
4177/*
4178 * Test configuration for debugging
4179 *
4180 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4181 * enum controls.
4182 */
4183#ifdef CONFIG_SND_DEBUG
4184static hda_nid_t alc880_test_dac_nids[4] = {
4185 0x02, 0x03, 0x04, 0x05
4186};
4187
4188static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4189 .num_items = 7,
2fa522be
TI
4190 .items = {
4191 { "In-1", 0x0 },
4192 { "In-2", 0x1 },
4193 { "In-3", 0x2 },
4194 { "In-4", 0x3 },
4195 { "CD", 0x4 },
ae6b813a
TI
4196 { "Front", 0x5 },
4197 { "Surround", 0x6 },
2fa522be
TI
4198 },
4199};
4200
d2a6d7dc 4201static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4202 { 2, NULL },
fd2c326d 4203 { 4, NULL },
2fa522be 4204 { 6, NULL },
fd2c326d 4205 { 8, NULL },
2fa522be
TI
4206};
4207
9c7f852e
TI
4208static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4209 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4210{
4211 static char *texts[] = {
4212 "N/A", "Line Out", "HP Out",
4213 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4214 };
4215 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4216 uinfo->count = 1;
4217 uinfo->value.enumerated.items = 8;
4218 if (uinfo->value.enumerated.item >= 8)
4219 uinfo->value.enumerated.item = 7;
4220 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4221 return 0;
4222}
4223
9c7f852e
TI
4224static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4225 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4226{
4227 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4228 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4229 unsigned int pin_ctl, item = 0;
4230
4231 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4232 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4233 if (pin_ctl & AC_PINCTL_OUT_EN) {
4234 if (pin_ctl & AC_PINCTL_HP_EN)
4235 item = 2;
4236 else
4237 item = 1;
4238 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4239 switch (pin_ctl & AC_PINCTL_VREFEN) {
4240 case AC_PINCTL_VREF_HIZ: item = 3; break;
4241 case AC_PINCTL_VREF_50: item = 4; break;
4242 case AC_PINCTL_VREF_GRD: item = 5; break;
4243 case AC_PINCTL_VREF_80: item = 6; break;
4244 case AC_PINCTL_VREF_100: item = 7; break;
4245 }
4246 }
4247 ucontrol->value.enumerated.item[0] = item;
4248 return 0;
4249}
4250
9c7f852e
TI
4251static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4252 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4253{
4254 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4255 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4256 static unsigned int ctls[] = {
4257 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4258 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4259 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4260 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4261 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4262 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4263 };
4264 unsigned int old_ctl, new_ctl;
4265
4266 old_ctl = snd_hda_codec_read(codec, nid, 0,
4267 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4268 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4269 if (old_ctl != new_ctl) {
82beb8fd
TI
4270 int val;
4271 snd_hda_codec_write_cache(codec, nid, 0,
4272 AC_VERB_SET_PIN_WIDGET_CONTROL,
4273 new_ctl);
47fd830a
TI
4274 val = ucontrol->value.enumerated.item[0] >= 3 ?
4275 HDA_AMP_MUTE : 0;
4276 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4277 HDA_AMP_MUTE, val);
2fa522be
TI
4278 return 1;
4279 }
4280 return 0;
4281}
4282
9c7f852e
TI
4283static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4284 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4285{
4286 static char *texts[] = {
4287 "Front", "Surround", "CLFE", "Side"
4288 };
4289 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4290 uinfo->count = 1;
4291 uinfo->value.enumerated.items = 4;
4292 if (uinfo->value.enumerated.item >= 4)
4293 uinfo->value.enumerated.item = 3;
4294 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4295 return 0;
4296}
4297
9c7f852e
TI
4298static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4299 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4300{
4301 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4302 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4303 unsigned int sel;
4304
4305 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4306 ucontrol->value.enumerated.item[0] = sel & 3;
4307 return 0;
4308}
4309
9c7f852e
TI
4310static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4311 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4312{
4313 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4314 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4315 unsigned int sel;
4316
4317 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4318 if (ucontrol->value.enumerated.item[0] != sel) {
4319 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4320 snd_hda_codec_write_cache(codec, nid, 0,
4321 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4322 return 1;
4323 }
4324 return 0;
4325}
4326
4327#define PIN_CTL_TEST(xname,nid) { \
4328 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4329 .name = xname, \
5b0cb1d8 4330 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4331 .info = alc_test_pin_ctl_info, \
4332 .get = alc_test_pin_ctl_get, \
4333 .put = alc_test_pin_ctl_put, \
4334 .private_value = nid \
4335 }
4336
4337#define PIN_SRC_TEST(xname,nid) { \
4338 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4339 .name = xname, \
5b0cb1d8 4340 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4341 .info = alc_test_pin_src_info, \
4342 .get = alc_test_pin_src_get, \
4343 .put = alc_test_pin_src_put, \
4344 .private_value = nid \
4345 }
4346
c8b6bf9b 4347static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4348 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4349 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4350 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4351 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4352 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4353 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4354 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4355 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4356 PIN_CTL_TEST("Front Pin Mode", 0x14),
4357 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4358 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4359 PIN_CTL_TEST("Side Pin Mode", 0x17),
4360 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4361 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4362 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4363 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4364 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4365 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4366 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4367 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4368 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4369 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4370 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4371 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4372 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4373 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4374 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4375 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4376 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4377 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4378 {
4379 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4380 .name = "Channel Mode",
df694daa
KY
4381 .info = alc_ch_mode_info,
4382 .get = alc_ch_mode_get,
4383 .put = alc_ch_mode_put,
2fa522be
TI
4384 },
4385 { } /* end */
4386};
4387
4388static struct hda_verb alc880_test_init_verbs[] = {
4389 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4390 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4392 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4394 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4395 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4396 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4397 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4398 /* Vol output for 0x0c-0x0f */
05acb863
TI
4399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4400 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4401 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4403 /* Set output pins 0x14-0x17 */
05acb863
TI
4404 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4406 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4407 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4408 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4409 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4410 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4411 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4412 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4413 /* Set input pins 0x18-0x1c */
16ded525
TI
4414 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4415 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4416 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4417 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4418 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4419 /* Mute input pins 0x18-0x1b */
05acb863
TI
4420 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4421 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4422 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4423 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4424 /* ADC set up */
05acb863 4425 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4426 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4427 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4428 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4429 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4430 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4431 /* Analog input/passthru */
4432 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4433 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4434 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4435 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4436 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4437 { }
4438};
4439#endif
4440
1da177e4
LT
4441/*
4442 */
4443
f5fcc13c
TI
4444static const char *alc880_models[ALC880_MODEL_LAST] = {
4445 [ALC880_3ST] = "3stack",
4446 [ALC880_TCL_S700] = "tcl",
4447 [ALC880_3ST_DIG] = "3stack-digout",
4448 [ALC880_CLEVO] = "clevo",
4449 [ALC880_5ST] = "5stack",
4450 [ALC880_5ST_DIG] = "5stack-digout",
4451 [ALC880_W810] = "w810",
4452 [ALC880_Z71V] = "z71v",
4453 [ALC880_6ST] = "6stack",
4454 [ALC880_6ST_DIG] = "6stack-digout",
4455 [ALC880_ASUS] = "asus",
4456 [ALC880_ASUS_W1V] = "asus-w1v",
4457 [ALC880_ASUS_DIG] = "asus-dig",
4458 [ALC880_ASUS_DIG2] = "asus-dig2",
4459 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4460 [ALC880_UNIWILL_P53] = "uniwill-p53",
4461 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4462 [ALC880_F1734] = "F1734",
4463 [ALC880_LG] = "lg",
4464 [ALC880_LG_LW] = "lg-lw",
df99cd33 4465 [ALC880_MEDION_RIM] = "medion",
2fa522be 4466#ifdef CONFIG_SND_DEBUG
f5fcc13c 4467 [ALC880_TEST] = "test",
2fa522be 4468#endif
f5fcc13c
TI
4469 [ALC880_AUTO] = "auto",
4470};
4471
4472static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4473 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4474 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4475 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4476 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4477 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4478 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4479 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4480 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4481 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4482 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4483 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4484 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4485 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4486 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4487 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4488 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4489 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4490 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4491 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4492 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4493 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4494 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4495 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4496 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4497 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4498 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4499 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4500 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4501 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4502 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4503 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4504 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4505 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4506 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4507 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4508 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4509 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4510 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4511 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4512 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4513 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4514 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4515 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4516 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4517 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4518 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4519 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4520 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4521 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4522 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4523 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4524 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
4525 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4526 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4527 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4528 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4529 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4530 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4531 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4532 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4533 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4534 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4535 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4536 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4537 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4538 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4539 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4540 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4541 /* default Intel */
4542 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4543 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4544 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4545 {}
4546};
4547
16ded525 4548/*
df694daa 4549 * ALC880 codec presets
16ded525 4550 */
16ded525
TI
4551static struct alc_config_preset alc880_presets[] = {
4552 [ALC880_3ST] = {
e9edcee0 4553 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4554 .init_verbs = { alc880_volume_init_verbs,
4555 alc880_pin_3stack_init_verbs },
16ded525 4556 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4557 .dac_nids = alc880_dac_nids,
16ded525
TI
4558 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4559 .channel_mode = alc880_threestack_modes,
4e195a7b 4560 .need_dac_fix = 1,
16ded525
TI
4561 .input_mux = &alc880_capture_source,
4562 },
4563 [ALC880_3ST_DIG] = {
e9edcee0 4564 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4565 .init_verbs = { alc880_volume_init_verbs,
4566 alc880_pin_3stack_init_verbs },
16ded525 4567 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4568 .dac_nids = alc880_dac_nids,
4569 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4570 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4571 .channel_mode = alc880_threestack_modes,
4e195a7b 4572 .need_dac_fix = 1,
16ded525
TI
4573 .input_mux = &alc880_capture_source,
4574 },
df694daa
KY
4575 [ALC880_TCL_S700] = {
4576 .mixers = { alc880_tcl_s700_mixer },
4577 .init_verbs = { alc880_volume_init_verbs,
4578 alc880_pin_tcl_S700_init_verbs,
4579 alc880_gpio2_init_verbs },
4580 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4581 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4582 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4583 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4584 .hp_nid = 0x03,
4585 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4586 .channel_mode = alc880_2_jack_modes,
4587 .input_mux = &alc880_capture_source,
4588 },
16ded525 4589 [ALC880_5ST] = {
f12ab1e0
TI
4590 .mixers = { alc880_three_stack_mixer,
4591 alc880_five_stack_mixer},
4592 .init_verbs = { alc880_volume_init_verbs,
4593 alc880_pin_5stack_init_verbs },
16ded525
TI
4594 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4595 .dac_nids = alc880_dac_nids,
16ded525
TI
4596 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4597 .channel_mode = alc880_fivestack_modes,
4598 .input_mux = &alc880_capture_source,
4599 },
4600 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4601 .mixers = { alc880_three_stack_mixer,
4602 alc880_five_stack_mixer },
4603 .init_verbs = { alc880_volume_init_verbs,
4604 alc880_pin_5stack_init_verbs },
16ded525
TI
4605 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4606 .dac_nids = alc880_dac_nids,
4607 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4608 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4609 .channel_mode = alc880_fivestack_modes,
4610 .input_mux = &alc880_capture_source,
4611 },
b6482d48
TI
4612 [ALC880_6ST] = {
4613 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4614 .init_verbs = { alc880_volume_init_verbs,
4615 alc880_pin_6stack_init_verbs },
b6482d48
TI
4616 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4617 .dac_nids = alc880_6st_dac_nids,
4618 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4619 .channel_mode = alc880_sixstack_modes,
4620 .input_mux = &alc880_6stack_capture_source,
4621 },
16ded525 4622 [ALC880_6ST_DIG] = {
e9edcee0 4623 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4624 .init_verbs = { alc880_volume_init_verbs,
4625 alc880_pin_6stack_init_verbs },
16ded525
TI
4626 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4627 .dac_nids = alc880_6st_dac_nids,
4628 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4629 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4630 .channel_mode = alc880_sixstack_modes,
4631 .input_mux = &alc880_6stack_capture_source,
4632 },
4633 [ALC880_W810] = {
e9edcee0 4634 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4635 .init_verbs = { alc880_volume_init_verbs,
4636 alc880_pin_w810_init_verbs,
b0af0de5 4637 alc880_gpio2_init_verbs },
16ded525
TI
4638 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4639 .dac_nids = alc880_w810_dac_nids,
4640 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4641 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4642 .channel_mode = alc880_w810_modes,
4643 .input_mux = &alc880_capture_source,
4644 },
4645 [ALC880_Z71V] = {
e9edcee0 4646 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4647 .init_verbs = { alc880_volume_init_verbs,
4648 alc880_pin_z71v_init_verbs },
16ded525
TI
4649 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4650 .dac_nids = alc880_z71v_dac_nids,
4651 .dig_out_nid = ALC880_DIGOUT_NID,
4652 .hp_nid = 0x03,
e9edcee0
TI
4653 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4654 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4655 .input_mux = &alc880_capture_source,
4656 },
4657 [ALC880_F1734] = {
e9edcee0 4658 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4659 .init_verbs = { alc880_volume_init_verbs,
4660 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4661 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4662 .dac_nids = alc880_f1734_dac_nids,
4663 .hp_nid = 0x02,
4664 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4665 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4666 .input_mux = &alc880_f1734_capture_source,
4667 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4668 .setup = alc880_uniwill_p53_setup,
4669 .init_hook = alc_automute_amp,
16ded525
TI
4670 },
4671 [ALC880_ASUS] = {
e9edcee0 4672 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4673 .init_verbs = { alc880_volume_init_verbs,
4674 alc880_pin_asus_init_verbs,
e9edcee0
TI
4675 alc880_gpio1_init_verbs },
4676 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4677 .dac_nids = alc880_asus_dac_nids,
4678 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4679 .channel_mode = alc880_asus_modes,
4e195a7b 4680 .need_dac_fix = 1,
16ded525
TI
4681 .input_mux = &alc880_capture_source,
4682 },
4683 [ALC880_ASUS_DIG] = {
e9edcee0 4684 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4685 .init_verbs = { alc880_volume_init_verbs,
4686 alc880_pin_asus_init_verbs,
e9edcee0
TI
4687 alc880_gpio1_init_verbs },
4688 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4689 .dac_nids = alc880_asus_dac_nids,
16ded525 4690 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4691 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4692 .channel_mode = alc880_asus_modes,
4e195a7b 4693 .need_dac_fix = 1,
16ded525
TI
4694 .input_mux = &alc880_capture_source,
4695 },
df694daa
KY
4696 [ALC880_ASUS_DIG2] = {
4697 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4698 .init_verbs = { alc880_volume_init_verbs,
4699 alc880_pin_asus_init_verbs,
df694daa
KY
4700 alc880_gpio2_init_verbs }, /* use GPIO2 */
4701 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4702 .dac_nids = alc880_asus_dac_nids,
4703 .dig_out_nid = ALC880_DIGOUT_NID,
4704 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4705 .channel_mode = alc880_asus_modes,
4e195a7b 4706 .need_dac_fix = 1,
df694daa
KY
4707 .input_mux = &alc880_capture_source,
4708 },
16ded525 4709 [ALC880_ASUS_W1V] = {
e9edcee0 4710 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4711 .init_verbs = { alc880_volume_init_verbs,
4712 alc880_pin_asus_init_verbs,
e9edcee0
TI
4713 alc880_gpio1_init_verbs },
4714 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4715 .dac_nids = alc880_asus_dac_nids,
16ded525 4716 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4717 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4718 .channel_mode = alc880_asus_modes,
4e195a7b 4719 .need_dac_fix = 1,
16ded525
TI
4720 .input_mux = &alc880_capture_source,
4721 },
4722 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4723 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4724 .init_verbs = { alc880_volume_init_verbs,
4725 alc880_pin_asus_init_verbs },
e9edcee0
TI
4726 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4727 .dac_nids = alc880_asus_dac_nids,
16ded525 4728 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4729 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4730 .channel_mode = alc880_asus_modes,
4e195a7b 4731 .need_dac_fix = 1,
16ded525
TI
4732 .input_mux = &alc880_capture_source,
4733 },
ccc656ce
KY
4734 [ALC880_UNIWILL] = {
4735 .mixers = { alc880_uniwill_mixer },
4736 .init_verbs = { alc880_volume_init_verbs,
4737 alc880_uniwill_init_verbs },
4738 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4739 .dac_nids = alc880_asus_dac_nids,
4740 .dig_out_nid = ALC880_DIGOUT_NID,
4741 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4742 .channel_mode = alc880_threestack_modes,
4743 .need_dac_fix = 1,
4744 .input_mux = &alc880_capture_source,
4745 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4746 .setup = alc880_uniwill_setup,
a9fd4f3f 4747 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4748 },
4749 [ALC880_UNIWILL_P53] = {
4750 .mixers = { alc880_uniwill_p53_mixer },
4751 .init_verbs = { alc880_volume_init_verbs,
4752 alc880_uniwill_p53_init_verbs },
4753 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4754 .dac_nids = alc880_asus_dac_nids,
4755 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4756 .channel_mode = alc880_threestack_modes,
4757 .input_mux = &alc880_capture_source,
4758 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4759 .setup = alc880_uniwill_p53_setup,
4760 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4761 },
4762 [ALC880_FUJITSU] = {
45bdd1c1 4763 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4764 .init_verbs = { alc880_volume_init_verbs,
4765 alc880_uniwill_p53_init_verbs,
4766 alc880_beep_init_verbs },
4767 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4768 .dac_nids = alc880_dac_nids,
d53d7d9e 4769 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4770 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4771 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4772 .input_mux = &alc880_capture_source,
4773 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4774 .setup = alc880_uniwill_p53_setup,
4775 .init_hook = alc_automute_amp,
ccc656ce 4776 },
df694daa
KY
4777 [ALC880_CLEVO] = {
4778 .mixers = { alc880_three_stack_mixer },
4779 .init_verbs = { alc880_volume_init_verbs,
4780 alc880_pin_clevo_init_verbs },
4781 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4782 .dac_nids = alc880_dac_nids,
4783 .hp_nid = 0x03,
4784 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4785 .channel_mode = alc880_threestack_modes,
4e195a7b 4786 .need_dac_fix = 1,
df694daa
KY
4787 .input_mux = &alc880_capture_source,
4788 },
ae6b813a
TI
4789 [ALC880_LG] = {
4790 .mixers = { alc880_lg_mixer },
4791 .init_verbs = { alc880_volume_init_verbs,
4792 alc880_lg_init_verbs },
4793 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4794 .dac_nids = alc880_lg_dac_nids,
4795 .dig_out_nid = ALC880_DIGOUT_NID,
4796 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4797 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4798 .need_dac_fix = 1,
ae6b813a 4799 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4800 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4801 .setup = alc880_lg_setup,
4802 .init_hook = alc_automute_amp,
cb53c626
TI
4803#ifdef CONFIG_SND_HDA_POWER_SAVE
4804 .loopbacks = alc880_lg_loopbacks,
4805#endif
ae6b813a 4806 },
d681518a
TI
4807 [ALC880_LG_LW] = {
4808 .mixers = { alc880_lg_lw_mixer },
4809 .init_verbs = { alc880_volume_init_verbs,
4810 alc880_lg_lw_init_verbs },
0a8c5da3 4811 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4812 .dac_nids = alc880_dac_nids,
4813 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4814 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4815 .channel_mode = alc880_lg_lw_modes,
d681518a 4816 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4817 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4818 .setup = alc880_lg_lw_setup,
4819 .init_hook = alc_automute_amp,
d681518a 4820 },
df99cd33
TI
4821 [ALC880_MEDION_RIM] = {
4822 .mixers = { alc880_medion_rim_mixer },
4823 .init_verbs = { alc880_volume_init_verbs,
4824 alc880_medion_rim_init_verbs,
4825 alc_gpio2_init_verbs },
4826 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4827 .dac_nids = alc880_dac_nids,
4828 .dig_out_nid = ALC880_DIGOUT_NID,
4829 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4830 .channel_mode = alc880_2_jack_modes,
4831 .input_mux = &alc880_medion_rim_capture_source,
4832 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4833 .setup = alc880_medion_rim_setup,
4834 .init_hook = alc880_medion_rim_automute,
df99cd33 4835 },
16ded525
TI
4836#ifdef CONFIG_SND_DEBUG
4837 [ALC880_TEST] = {
e9edcee0
TI
4838 .mixers = { alc880_test_mixer },
4839 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4840 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4841 .dac_nids = alc880_test_dac_nids,
4842 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4843 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4844 .channel_mode = alc880_test_modes,
4845 .input_mux = &alc880_test_capture_source,
4846 },
4847#endif
4848};
4849
e9edcee0
TI
4850/*
4851 * Automatic parse of I/O pins from the BIOS configuration
4852 */
4853
e9edcee0
TI
4854enum {
4855 ALC_CTL_WIDGET_VOL,
4856 ALC_CTL_WIDGET_MUTE,
4857 ALC_CTL_BIND_MUTE,
4858};
c8b6bf9b 4859static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4860 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4861 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4862 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4863};
4864
4865/* add dynamic controls */
f12ab1e0 4866static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 4867 int cidx, unsigned long val)
e9edcee0 4868{
c8b6bf9b 4869 struct snd_kcontrol_new *knew;
e9edcee0 4870
603c4019
TI
4871 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4872 knew = snd_array_new(&spec->kctls);
4873 if (!knew)
4874 return -ENOMEM;
e9edcee0 4875 *knew = alc880_control_templates[type];
543537bd 4876 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4877 if (!knew->name)
e9edcee0 4878 return -ENOMEM;
66ceeb6b 4879 knew->index = cidx;
4d02d1b6 4880 if (get_amp_nid_(val))
5e26dfd0 4881 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 4882 knew->private_value = val;
e9edcee0
TI
4883 return 0;
4884}
4885
0afe5f89
TI
4886static int add_control_with_pfx(struct alc_spec *spec, int type,
4887 const char *pfx, const char *dir,
66ceeb6b 4888 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
4889{
4890 char name[32];
4891 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 4892 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
4893}
4894
66ceeb6b
TI
4895#define add_pb_vol_ctrl(spec, type, pfx, val) \
4896 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
4897#define add_pb_sw_ctrl(spec, type, pfx, val) \
4898 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
4899#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
4900 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
4901#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
4902 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 4903
e9edcee0
TI
4904#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4905#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4906#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4907#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4908#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4909#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4910#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4911#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4912#define ALC880_PIN_CD_NID 0x1c
4913
4914/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4915static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4916 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4917{
4918 hda_nid_t nid;
4919 int assigned[4];
4920 int i, j;
4921
4922 memset(assigned, 0, sizeof(assigned));
b0af0de5 4923 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4924
4925 /* check the pins hardwired to audio widget */
4926 for (i = 0; i < cfg->line_outs; i++) {
4927 nid = cfg->line_out_pins[i];
4928 if (alc880_is_fixed_pin(nid)) {
4929 int idx = alc880_fixed_pin_idx(nid);
5014f193 4930 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4931 assigned[idx] = 1;
4932 }
4933 }
4934 /* left pins can be connect to any audio widget */
4935 for (i = 0; i < cfg->line_outs; i++) {
4936 nid = cfg->line_out_pins[i];
4937 if (alc880_is_fixed_pin(nid))
4938 continue;
4939 /* search for an empty channel */
4940 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4941 if (!assigned[j]) {
4942 spec->multiout.dac_nids[i] =
4943 alc880_idx_to_dac(j);
e9edcee0
TI
4944 assigned[j] = 1;
4945 break;
4946 }
4947 }
4948 }
4949 spec->multiout.num_dacs = cfg->line_outs;
4950 return 0;
4951}
4952
4953/* add playback controls from the parsed DAC table */
df694daa
KY
4954static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4955 const struct auto_pin_cfg *cfg)
e9edcee0 4956{
f12ab1e0
TI
4957 static const char *chname[4] = {
4958 "Front", "Surround", NULL /*CLFE*/, "Side"
4959 };
e9edcee0
TI
4960 hda_nid_t nid;
4961 int i, err;
4962
4963 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4964 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4965 continue;
4966 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4967 if (i == 2) {
4968 /* Center/LFE */
0afe5f89
TI
4969 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4970 "Center",
f12ab1e0
TI
4971 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4972 HDA_OUTPUT));
4973 if (err < 0)
e9edcee0 4974 return err;
0afe5f89
TI
4975 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4976 "LFE",
f12ab1e0
TI
4977 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4978 HDA_OUTPUT));
4979 if (err < 0)
e9edcee0 4980 return err;
0afe5f89
TI
4981 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4982 "Center",
f12ab1e0
TI
4983 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4984 HDA_INPUT));
4985 if (err < 0)
e9edcee0 4986 return err;
0afe5f89
TI
4987 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4988 "LFE",
f12ab1e0
TI
4989 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4990 HDA_INPUT));
4991 if (err < 0)
e9edcee0
TI
4992 return err;
4993 } else {
cb162b6b
TI
4994 const char *pfx;
4995 if (cfg->line_outs == 1 &&
4996 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4997 pfx = "Speaker";
4998 else
4999 pfx = chname[i];
0afe5f89 5000 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5001 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5002 HDA_OUTPUT));
5003 if (err < 0)
e9edcee0 5004 return err;
0afe5f89 5005 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5006 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5007 HDA_INPUT));
5008 if (err < 0)
e9edcee0
TI
5009 return err;
5010 }
5011 }
e9edcee0
TI
5012 return 0;
5013}
5014
8d88bc3d
TI
5015/* add playback controls for speaker and HP outputs */
5016static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5017 const char *pfx)
e9edcee0
TI
5018{
5019 hda_nid_t nid;
5020 int err;
5021
f12ab1e0 5022 if (!pin)
e9edcee0
TI
5023 return 0;
5024
5025 if (alc880_is_fixed_pin(pin)) {
5026 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5027 /* specify the DAC as the extra output */
f12ab1e0 5028 if (!spec->multiout.hp_nid)
e9edcee0 5029 spec->multiout.hp_nid = nid;
82bc955f
TI
5030 else
5031 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5032 /* control HP volume/switch on the output mixer amp */
5033 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5034 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5035 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5036 if (err < 0)
e9edcee0 5037 return err;
0afe5f89 5038 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5039 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5040 if (err < 0)
e9edcee0
TI
5041 return err;
5042 } else if (alc880_is_multi_pin(pin)) {
5043 /* set manual connection */
e9edcee0 5044 /* we have only a switch on HP-out PIN */
0afe5f89 5045 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5046 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5047 if (err < 0)
e9edcee0
TI
5048 return err;
5049 }
5050 return 0;
5051}
5052
5053/* create input playback/capture controls for the given pin */
f12ab1e0 5054static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5055 const char *ctlname, int ctlidx,
df694daa 5056 int idx, hda_nid_t mix_nid)
e9edcee0 5057{
df694daa 5058 int err;
e9edcee0 5059
66ceeb6b 5060 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5061 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5062 if (err < 0)
e9edcee0 5063 return err;
66ceeb6b 5064 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5065 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5066 if (err < 0)
e9edcee0
TI
5067 return err;
5068 return 0;
5069}
5070
05f5f477
TI
5071static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5072{
5073 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5074 return (pincap & AC_PINCAP_IN) != 0;
5075}
5076
e9edcee0 5077/* create playback/capture controls for input pins */
05f5f477
TI
5078static int alc_auto_create_input_ctls(struct hda_codec *codec,
5079 const struct auto_pin_cfg *cfg,
5080 hda_nid_t mixer,
5081 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5082{
05f5f477 5083 struct alc_spec *spec = codec->spec;
61b9b9b1 5084 struct hda_input_mux *imux = &spec->private_imux[0];
66ceeb6b 5085 int i, err, idx, type, type_idx = 0;
e9edcee0 5086
66ceeb6b 5087 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5088 hda_nid_t pin;
10a20af7 5089 const char *label;
05f5f477 5090
66ceeb6b 5091 pin = cfg->inputs[i].pin;
05f5f477
TI
5092 if (!alc_is_input_pin(codec, pin))
5093 continue;
5094
66ceeb6b
TI
5095 type = cfg->inputs[i].type;
5096 if (i > 0 && type == cfg->inputs[i - 1].type)
5097 type_idx++;
5098 else
5099 type_idx = 0;
10a20af7 5100 label = hda_get_autocfg_input_label(codec, cfg, i);
05f5f477
TI
5101 if (mixer) {
5102 idx = get_connection_index(codec, mixer, pin);
5103 if (idx >= 0) {
5104 err = new_analog_input(spec, pin,
10a20af7
TI
5105 label, type_idx,
5106 idx, mixer);
05f5f477
TI
5107 if (err < 0)
5108 return err;
5109 }
5110 }
5111
5112 if (!cap1)
5113 continue;
5114 idx = get_connection_index(codec, cap1, pin);
5115 if (idx < 0 && cap2)
5116 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5117 if (idx >= 0)
5118 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5119 }
5120 return 0;
5121}
5122
05f5f477
TI
5123static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5124 const struct auto_pin_cfg *cfg)
5125{
5126 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5127}
5128
f6c7e546
TI
5129static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5130 unsigned int pin_type)
5131{
5132 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5133 pin_type);
5134 /* unmute pin */
d260cdf6
TI
5135 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5136 AMP_OUT_UNMUTE);
f6c7e546
TI
5137}
5138
df694daa
KY
5139static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5140 hda_nid_t nid, int pin_type,
e9edcee0
TI
5141 int dac_idx)
5142{
f6c7e546 5143 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5144 /* need the manual connection? */
5145 if (alc880_is_multi_pin(nid)) {
5146 struct alc_spec *spec = codec->spec;
5147 int idx = alc880_multi_pin_idx(nid);
5148 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5149 AC_VERB_SET_CONNECT_SEL,
5150 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5151 }
5152}
5153
baba8ee9
TI
5154static int get_pin_type(int line_out_type)
5155{
5156 if (line_out_type == AUTO_PIN_HP_OUT)
5157 return PIN_HP;
5158 else
5159 return PIN_OUT;
5160}
5161
e9edcee0
TI
5162static void alc880_auto_init_multi_out(struct hda_codec *codec)
5163{
5164 struct alc_spec *spec = codec->spec;
5165 int i;
ea1fb29a 5166
e9edcee0
TI
5167 for (i = 0; i < spec->autocfg.line_outs; i++) {
5168 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5169 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5170 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5171 }
5172}
5173
8d88bc3d 5174static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5175{
5176 struct alc_spec *spec = codec->spec;
5177 hda_nid_t pin;
5178
82bc955f 5179 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5180 if (pin) /* connect to front */
5181 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5182 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5183 if (pin) /* connect to front */
5184 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5185}
5186
5187static void alc880_auto_init_analog_input(struct hda_codec *codec)
5188{
5189 struct alc_spec *spec = codec->spec;
66ceeb6b 5190 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5191 int i;
5192
66ceeb6b
TI
5193 for (i = 0; i < cfg->num_inputs; i++) {
5194 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5195 if (alc_is_input_pin(codec, nid)) {
30ea098f 5196 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5197 if (nid != ALC880_PIN_CD_NID &&
5198 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5199 snd_hda_codec_write(codec, nid, 0,
5200 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5201 AMP_OUT_MUTE);
5202 }
5203 }
5204}
5205
7f311a46
TI
5206static void alc880_auto_init_input_src(struct hda_codec *codec)
5207{
5208 struct alc_spec *spec = codec->spec;
5209 int c;
5210
5211 for (c = 0; c < spec->num_adc_nids; c++) {
5212 unsigned int mux_idx;
5213 const struct hda_input_mux *imux;
5214 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5215 imux = &spec->input_mux[mux_idx];
5216 if (!imux->num_items && mux_idx > 0)
5217 imux = &spec->input_mux[0];
5218 if (imux)
5219 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5220 AC_VERB_SET_CONNECT_SEL,
5221 imux->items[0].index);
5222 }
5223}
5224
e9edcee0 5225/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5226/* return 1 if successful, 0 if the proper config is not found,
5227 * or a negative error code
5228 */
e9edcee0
TI
5229static int alc880_parse_auto_config(struct hda_codec *codec)
5230{
5231 struct alc_spec *spec = codec->spec;
757899ac 5232 int err;
df694daa 5233 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5234
f12ab1e0
TI
5235 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5236 alc880_ignore);
5237 if (err < 0)
e9edcee0 5238 return err;
f12ab1e0 5239 if (!spec->autocfg.line_outs)
e9edcee0 5240 return 0; /* can't find valid BIOS pin config */
df694daa 5241
f12ab1e0
TI
5242 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5243 if (err < 0)
5244 return err;
5245 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5246 if (err < 0)
5247 return err;
5248 err = alc880_auto_create_extra_out(spec,
5249 spec->autocfg.speaker_pins[0],
5250 "Speaker");
5251 if (err < 0)
5252 return err;
5253 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5254 "Headphone");
5255 if (err < 0)
5256 return err;
05f5f477 5257 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5258 if (err < 0)
e9edcee0
TI
5259 return err;
5260
5261 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5262
757899ac 5263 alc_auto_parse_digital(codec);
e9edcee0 5264
603c4019 5265 if (spec->kctls.list)
d88897ea 5266 add_mixer(spec, spec->kctls.list);
e9edcee0 5267
d88897ea 5268 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5269
a1e8d2da 5270 spec->num_mux_defs = 1;
61b9b9b1 5271 spec->input_mux = &spec->private_imux[0];
e9edcee0 5272
6227cdce 5273 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5274
e9edcee0
TI
5275 return 1;
5276}
5277
ae6b813a
TI
5278/* additional initialization for auto-configuration model */
5279static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5280{
f6c7e546 5281 struct alc_spec *spec = codec->spec;
e9edcee0 5282 alc880_auto_init_multi_out(codec);
8d88bc3d 5283 alc880_auto_init_extra_out(codec);
e9edcee0 5284 alc880_auto_init_analog_input(codec);
7f311a46 5285 alc880_auto_init_input_src(codec);
757899ac 5286 alc_auto_init_digital(codec);
f6c7e546 5287 if (spec->unsol_event)
7fb0d78f 5288 alc_inithook(codec);
e9edcee0
TI
5289}
5290
b59bdf3b
TI
5291/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5292 * one of two digital mic pins, e.g. on ALC272
5293 */
5294static void fixup_automic_adc(struct hda_codec *codec)
5295{
5296 struct alc_spec *spec = codec->spec;
5297 int i;
5298
5299 for (i = 0; i < spec->num_adc_nids; i++) {
5300 hda_nid_t cap = spec->capsrc_nids ?
5301 spec->capsrc_nids[i] : spec->adc_nids[i];
5302 int iidx, eidx;
5303
5304 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5305 if (iidx < 0)
5306 continue;
5307 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5308 if (eidx < 0)
5309 continue;
5310 spec->int_mic.mux_idx = iidx;
5311 spec->ext_mic.mux_idx = eidx;
5312 if (spec->capsrc_nids)
5313 spec->capsrc_nids += i;
5314 spec->adc_nids += i;
5315 spec->num_adc_nids = 1;
5316 return;
5317 }
5318 snd_printd(KERN_INFO "hda_codec: %s: "
5319 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5320 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5321 spec->auto_mic = 0; /* disable auto-mic to be sure */
5322}
5323
748cce43
TI
5324/* select or unmute the given capsrc route */
5325static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5326 int idx)
5327{
5328 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5329 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5330 HDA_AMP_MUTE, 0);
5331 } else {
5332 snd_hda_codec_write_cache(codec, cap, 0,
5333 AC_VERB_SET_CONNECT_SEL, idx);
5334 }
5335}
5336
840b64c0
TI
5337/* set the default connection to that pin */
5338static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5339{
5340 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5341 int i;
5342
eaa9b3a7
TI
5343 for (i = 0; i < spec->num_adc_nids; i++) {
5344 hda_nid_t cap = spec->capsrc_nids ?
5345 spec->capsrc_nids[i] : spec->adc_nids[i];
5346 int idx;
5347
5348 idx = get_connection_index(codec, cap, pin);
5349 if (idx < 0)
5350 continue;
748cce43 5351 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5352 return i; /* return the found index */
5353 }
5354 return -1; /* not found */
5355}
5356
5357/* choose the ADC/MUX containing the input pin and initialize the setup */
5358static void fixup_single_adc(struct hda_codec *codec)
5359{
5360 struct alc_spec *spec = codec->spec;
66ceeb6b 5361 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5362 int i;
5363
5364 /* search for the input pin; there must be only one */
66ceeb6b 5365 if (cfg->num_inputs != 1)
eaa9b3a7 5366 return;
66ceeb6b 5367 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5368 if (i >= 0) {
5369 /* use only this ADC */
5370 if (spec->capsrc_nids)
5371 spec->capsrc_nids += i;
5372 spec->adc_nids += i;
5373 spec->num_adc_nids = 1;
eaa9b3a7
TI
5374 }
5375}
5376
840b64c0
TI
5377/* initialize dual adcs */
5378static void fixup_dual_adc_switch(struct hda_codec *codec)
5379{
5380 struct alc_spec *spec = codec->spec;
5381 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5382 init_capsrc_for_pin(codec, spec->int_mic.pin);
5383}
5384
b59bdf3b 5385static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5386{
b59bdf3b 5387 struct alc_spec *spec = codec->spec;
a23b688f
TI
5388 static struct snd_kcontrol_new *caps[2][3] = {
5389 { alc_capture_mixer_nosrc1,
5390 alc_capture_mixer_nosrc2,
5391 alc_capture_mixer_nosrc3 },
5392 { alc_capture_mixer1,
5393 alc_capture_mixer2,
5394 alc_capture_mixer3 },
f9e336f6 5395 };
a23b688f 5396 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5397 int mux = 0;
840b64c0
TI
5398 int num_adcs = spec->num_adc_nids;
5399 if (spec->dual_adc_switch)
5400 fixup_dual_adc_switch(codec);
5401 else if (spec->auto_mic)
b59bdf3b 5402 fixup_automic_adc(codec);
eaa9b3a7
TI
5403 else if (spec->input_mux) {
5404 if (spec->input_mux->num_items > 1)
5405 mux = 1;
5406 else if (spec->input_mux->num_items == 1)
5407 fixup_single_adc(codec);
5408 }
840b64c0
TI
5409 if (spec->dual_adc_switch)
5410 num_adcs = 1;
5411 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5412 }
f9e336f6
TI
5413}
5414
6694635d
TI
5415/* fill adc_nids (and capsrc_nids) containing all active input pins */
5416static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5417 int num_nids)
5418{
5419 struct alc_spec *spec = codec->spec;
66ceeb6b 5420 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5421 int n;
5422 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5423
5424 for (n = 0; n < num_nids; n++) {
5425 hda_nid_t adc, cap;
5426 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5427 int nconns, i, j;
5428
5429 adc = nids[n];
5430 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5431 continue;
5432 cap = adc;
5433 nconns = snd_hda_get_connections(codec, cap, conn,
5434 ARRAY_SIZE(conn));
5435 if (nconns == 1) {
5436 cap = conn[0];
5437 nconns = snd_hda_get_connections(codec, cap, conn,
5438 ARRAY_SIZE(conn));
5439 }
5440 if (nconns <= 0)
5441 continue;
5442 if (!fallback_adc) {
5443 fallback_adc = adc;
5444 fallback_cap = cap;
5445 }
66ceeb6b
TI
5446 for (i = 0; i < cfg->num_inputs; i++) {
5447 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5448 for (j = 0; j < nconns; j++) {
5449 if (conn[j] == nid)
5450 break;
5451 }
5452 if (j >= nconns)
5453 break;
5454 }
66ceeb6b 5455 if (i >= cfg->num_inputs) {
6694635d
TI
5456 int num_adcs = spec->num_adc_nids;
5457 spec->private_adc_nids[num_adcs] = adc;
5458 spec->private_capsrc_nids[num_adcs] = cap;
5459 spec->num_adc_nids++;
5460 spec->adc_nids = spec->private_adc_nids;
5461 if (adc != cap)
5462 spec->capsrc_nids = spec->private_capsrc_nids;
5463 }
5464 }
5465 if (!spec->num_adc_nids) {
5466 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5467 " using fallback 0x%x\n",
5468 codec->chip_name, fallback_adc);
6694635d
TI
5469 spec->private_adc_nids[0] = fallback_adc;
5470 spec->adc_nids = spec->private_adc_nids;
5471 if (fallback_adc != fallback_cap) {
5472 spec->private_capsrc_nids[0] = fallback_cap;
5473 spec->capsrc_nids = spec->private_adc_nids;
5474 }
5475 }
5476}
5477
67d634c0 5478#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5479#define set_beep_amp(spec, nid, idx, dir) \
5480 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5481
5482static struct snd_pci_quirk beep_white_list[] = {
5483 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5484 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5485 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5486 {}
5487};
5488
5489static inline int has_cdefine_beep(struct hda_codec *codec)
5490{
5491 struct alc_spec *spec = codec->spec;
5492 const struct snd_pci_quirk *q;
5493 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5494 if (q)
5495 return q->value;
5496 return spec->cdefine.enable_pcbeep;
5497}
67d634c0
TI
5498#else
5499#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5500#define has_cdefine_beep(codec) 0
67d634c0 5501#endif
45bdd1c1
TI
5502
5503/*
5504 * OK, here we have finally the patch for ALC880
5505 */
5506
1da177e4
LT
5507static int patch_alc880(struct hda_codec *codec)
5508{
5509 struct alc_spec *spec;
5510 int board_config;
df694daa 5511 int err;
1da177e4 5512
e560d8d8 5513 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5514 if (spec == NULL)
5515 return -ENOMEM;
5516
5517 codec->spec = spec;
5518
f5fcc13c
TI
5519 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5520 alc880_models,
5521 alc880_cfg_tbl);
5522 if (board_config < 0) {
9a11f1aa
TI
5523 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5524 codec->chip_name);
e9edcee0 5525 board_config = ALC880_AUTO;
1da177e4 5526 }
1da177e4 5527
e9edcee0
TI
5528 if (board_config == ALC880_AUTO) {
5529 /* automatic parse from the BIOS config */
5530 err = alc880_parse_auto_config(codec);
5531 if (err < 0) {
5532 alc_free(codec);
5533 return err;
f12ab1e0 5534 } else if (!err) {
9c7f852e
TI
5535 printk(KERN_INFO
5536 "hda_codec: Cannot set up configuration "
5537 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5538 board_config = ALC880_3ST;
5539 }
1da177e4
LT
5540 }
5541
680cd536
KK
5542 err = snd_hda_attach_beep_device(codec, 0x1);
5543 if (err < 0) {
5544 alc_free(codec);
5545 return err;
5546 }
5547
df694daa 5548 if (board_config != ALC880_AUTO)
e9c364c0 5549 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5550
1da177e4
LT
5551 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5552 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5553 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5554
1da177e4
LT
5555 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5556 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5557
f12ab1e0 5558 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5559 /* check whether NID 0x07 is valid */
54d17403 5560 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5561 /* get type */
a22d543a 5562 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5563 if (wcap != AC_WID_AUD_IN) {
5564 spec->adc_nids = alc880_adc_nids_alt;
5565 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5566 } else {
5567 spec->adc_nids = alc880_adc_nids;
5568 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5569 }
5570 }
b59bdf3b 5571 set_capture_mixer(codec);
45bdd1c1 5572 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5573
2134ea4f
TI
5574 spec->vmaster_nid = 0x0c;
5575
1da177e4 5576 codec->patch_ops = alc_patch_ops;
e9edcee0 5577 if (board_config == ALC880_AUTO)
ae6b813a 5578 spec->init_hook = alc880_auto_init;
cb53c626
TI
5579#ifdef CONFIG_SND_HDA_POWER_SAVE
5580 if (!spec->loopback.amplist)
5581 spec->loopback.amplist = alc880_loopbacks;
5582#endif
1da177e4
LT
5583
5584 return 0;
5585}
5586
e9edcee0 5587
1da177e4
LT
5588/*
5589 * ALC260 support
5590 */
5591
e9edcee0
TI
5592static hda_nid_t alc260_dac_nids[1] = {
5593 /* front */
5594 0x02,
5595};
5596
5597static hda_nid_t alc260_adc_nids[1] = {
5598 /* ADC0 */
5599 0x04,
5600};
5601
df694daa 5602static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5603 /* ADC1 */
5604 0x05,
5605};
5606
d57fdac0
JW
5607/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5608 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5609 */
5610static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5611 /* ADC0, ADC1 */
5612 0x04, 0x05
5613};
5614
e9edcee0
TI
5615#define ALC260_DIGOUT_NID 0x03
5616#define ALC260_DIGIN_NID 0x06
5617
5618static struct hda_input_mux alc260_capture_source = {
5619 .num_items = 4,
5620 .items = {
5621 { "Mic", 0x0 },
5622 { "Front Mic", 0x1 },
5623 { "Line", 0x2 },
5624 { "CD", 0x4 },
5625 },
5626};
5627
17e7aec6 5628/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5629 * headphone jack and the internal CD lines since these are the only pins at
5630 * which audio can appear. For flexibility, also allow the option of
5631 * recording the mixer output on the second ADC (ADC0 doesn't have a
5632 * connection to the mixer output).
a9430dd8 5633 */
a1e8d2da
JW
5634static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5635 {
5636 .num_items = 3,
5637 .items = {
5638 { "Mic/Line", 0x0 },
5639 { "CD", 0x4 },
5640 { "Headphone", 0x2 },
5641 },
a9430dd8 5642 },
a1e8d2da
JW
5643 {
5644 .num_items = 4,
5645 .items = {
5646 { "Mic/Line", 0x0 },
5647 { "CD", 0x4 },
5648 { "Headphone", 0x2 },
5649 { "Mixer", 0x5 },
5650 },
5651 },
5652
a9430dd8
JW
5653};
5654
a1e8d2da
JW
5655/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5656 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5657 */
a1e8d2da
JW
5658static struct hda_input_mux alc260_acer_capture_sources[2] = {
5659 {
5660 .num_items = 4,
5661 .items = {
5662 { "Mic", 0x0 },
5663 { "Line", 0x2 },
5664 { "CD", 0x4 },
5665 { "Headphone", 0x5 },
5666 },
5667 },
5668 {
5669 .num_items = 5,
5670 .items = {
5671 { "Mic", 0x0 },
5672 { "Line", 0x2 },
5673 { "CD", 0x4 },
5674 { "Headphone", 0x6 },
5675 { "Mixer", 0x5 },
5676 },
0bfc90e9
JW
5677 },
5678};
cc959489
MS
5679
5680/* Maxdata Favorit 100XS */
5681static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5682 {
5683 .num_items = 2,
5684 .items = {
5685 { "Line/Mic", 0x0 },
5686 { "CD", 0x4 },
5687 },
5688 },
5689 {
5690 .num_items = 3,
5691 .items = {
5692 { "Line/Mic", 0x0 },
5693 { "CD", 0x4 },
5694 { "Mixer", 0x5 },
5695 },
5696 },
5697};
5698
1da177e4
LT
5699/*
5700 * This is just place-holder, so there's something for alc_build_pcms to look
5701 * at when it calculates the maximum number of channels. ALC260 has no mixer
5702 * element which allows changing the channel mode, so the verb list is
5703 * never used.
5704 */
d2a6d7dc 5705static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5706 { 2, NULL },
5707};
5708
df694daa
KY
5709
5710/* Mixer combinations
5711 *
5712 * basic: base_output + input + pc_beep + capture
5713 * HP: base_output + input + capture_alt
5714 * HP_3013: hp_3013 + input + capture
5715 * fujitsu: fujitsu + capture
0bfc90e9 5716 * acer: acer + capture
df694daa
KY
5717 */
5718
5719static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5720 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5721 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5723 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5724 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5725 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5726 { } /* end */
f12ab1e0 5727};
1da177e4 5728
df694daa 5729static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5730 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5731 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5732 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5733 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5735 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5736 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5737 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5738 { } /* end */
5739};
5740
bec15c3a
TI
5741/* update HP, line and mono out pins according to the master switch */
5742static void alc260_hp_master_update(struct hda_codec *codec,
5743 hda_nid_t hp, hda_nid_t line,
5744 hda_nid_t mono)
5745{
5746 struct alc_spec *spec = codec->spec;
5747 unsigned int val = spec->master_sw ? PIN_HP : 0;
5748 /* change HP and line-out pins */
30cde0aa 5749 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5750 val);
30cde0aa 5751 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5752 val);
5753 /* mono (speaker) depending on the HP jack sense */
5754 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5755 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5756 val);
5757}
5758
5759static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5760 struct snd_ctl_elem_value *ucontrol)
5761{
5762 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5763 struct alc_spec *spec = codec->spec;
5764 *ucontrol->value.integer.value = spec->master_sw;
5765 return 0;
5766}
5767
5768static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5769 struct snd_ctl_elem_value *ucontrol)
5770{
5771 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5772 struct alc_spec *spec = codec->spec;
5773 int val = !!*ucontrol->value.integer.value;
5774 hda_nid_t hp, line, mono;
5775
5776 if (val == spec->master_sw)
5777 return 0;
5778 spec->master_sw = val;
5779 hp = (kcontrol->private_value >> 16) & 0xff;
5780 line = (kcontrol->private_value >> 8) & 0xff;
5781 mono = kcontrol->private_value & 0xff;
5782 alc260_hp_master_update(codec, hp, line, mono);
5783 return 1;
5784}
5785
5786static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5787 {
5788 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5789 .name = "Master Playback Switch",
5b0cb1d8 5790 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5791 .info = snd_ctl_boolean_mono_info,
5792 .get = alc260_hp_master_sw_get,
5793 .put = alc260_hp_master_sw_put,
5794 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5795 },
5796 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5797 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5798 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5799 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5800 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5801 HDA_OUTPUT),
5802 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5803 { } /* end */
5804};
5805
5806static struct hda_verb alc260_hp_unsol_verbs[] = {
5807 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5808 {},
5809};
5810
5811static void alc260_hp_automute(struct hda_codec *codec)
5812{
5813 struct alc_spec *spec = codec->spec;
bec15c3a 5814
864f92be 5815 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5816 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5817}
5818
5819static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5820{
5821 if ((res >> 26) == ALC880_HP_EVENT)
5822 alc260_hp_automute(codec);
5823}
5824
df694daa 5825static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5826 {
5827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5828 .name = "Master Playback Switch",
5b0cb1d8 5829 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5830 .info = snd_ctl_boolean_mono_info,
5831 .get = alc260_hp_master_sw_get,
5832 .put = alc260_hp_master_sw_put,
30cde0aa 5833 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5834 },
df694daa
KY
5835 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5836 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5837 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5838 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5839 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5840 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5841 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5842 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5843 { } /* end */
5844};
5845
3f878308
KY
5846static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5847 .ops = &snd_hda_bind_vol,
5848 .values = {
5849 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5850 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5851 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5852 0
5853 },
5854};
5855
5856static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5857 .ops = &snd_hda_bind_sw,
5858 .values = {
5859 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5860 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5861 0
5862 },
5863};
5864
5865static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5866 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5867 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5868 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5869 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5870 { } /* end */
5871};
5872
bec15c3a
TI
5873static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5874 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5875 {},
5876};
5877
5878static void alc260_hp_3013_automute(struct hda_codec *codec)
5879{
5880 struct alc_spec *spec = codec->spec;
bec15c3a 5881
864f92be 5882 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5883 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5884}
5885
5886static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5887 unsigned int res)
5888{
5889 if ((res >> 26) == ALC880_HP_EVENT)
5890 alc260_hp_3013_automute(codec);
5891}
5892
3f878308
KY
5893static void alc260_hp_3012_automute(struct hda_codec *codec)
5894{
864f92be 5895 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5896
3f878308
KY
5897 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5898 bits);
5899 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5900 bits);
5901 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5902 bits);
5903}
5904
5905static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5906 unsigned int res)
5907{
5908 if ((res >> 26) == ALC880_HP_EVENT)
5909 alc260_hp_3012_automute(codec);
5910}
5911
5912/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5913 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5914 */
c8b6bf9b 5915static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5917 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5918 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5919 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5920 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5921 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5922 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5923 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5924 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5925 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5926 { } /* end */
5927};
5928
a1e8d2da
JW
5929/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5930 * versions of the ALC260 don't act on requests to enable mic bias from NID
5931 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5932 * datasheet doesn't mention this restriction. At this stage it's not clear
5933 * whether this behaviour is intentional or is a hardware bug in chip
5934 * revisions available in early 2006. Therefore for now allow the
5935 * "Headphone Jack Mode" control to span all choices, but if it turns out
5936 * that the lack of mic bias for this NID is intentional we could change the
5937 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5938 *
5939 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5940 * don't appear to make the mic bias available from the "line" jack, even
5941 * though the NID used for this jack (0x14) can supply it. The theory is
5942 * that perhaps Acer have included blocking capacitors between the ALC260
5943 * and the output jack. If this turns out to be the case for all such
5944 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5945 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5946 *
5947 * The C20x Tablet series have a mono internal speaker which is controlled
5948 * via the chip's Mono sum widget and pin complex, so include the necessary
5949 * controls for such models. On models without a "mono speaker" the control
5950 * won't do anything.
a1e8d2da 5951 */
0bfc90e9
JW
5952static struct snd_kcontrol_new alc260_acer_mixer[] = {
5953 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5954 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5955 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5956 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5957 HDA_OUTPUT),
31bffaa9 5958 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5959 HDA_INPUT),
0bfc90e9
JW
5960 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5961 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5962 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5963 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5964 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5965 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5966 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5967 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5968 { } /* end */
5969};
5970
cc959489
MS
5971/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5972 */
5973static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5974 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5975 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5976 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5977 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5978 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5979 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5980 { } /* end */
5981};
5982
bc9f98a9
KY
5983/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5984 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5985 */
5986static struct snd_kcontrol_new alc260_will_mixer[] = {
5987 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5988 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5990 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5991 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5992 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5993 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5994 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5995 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5996 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5997 { } /* end */
5998};
5999
6000/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6001 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6002 */
6003static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6004 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6005 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6007 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6008 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6009 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6010 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6011 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6012 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6013 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6014 { } /* end */
6015};
6016
df694daa
KY
6017/*
6018 * initialization verbs
6019 */
1da177e4
LT
6020static struct hda_verb alc260_init_verbs[] = {
6021 /* Line In pin widget for input */
05acb863 6022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6023 /* CD pin widget for input */
05acb863 6024 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6025 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6026 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6027 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6028 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6029 /* LINE-2 is used for line-out in rear */
05acb863 6030 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6031 /* select line-out */
fd56f2db 6032 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6033 /* LINE-OUT pin */
05acb863 6034 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6035 /* enable HP */
05acb863 6036 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6037 /* enable Mono */
05acb863
TI
6038 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6039 /* mute capture amp left and right */
16ded525 6040 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6041 /* set connection select to line in (default select for this ADC) */
6042 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6043 /* mute capture amp left and right */
6044 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6045 /* set connection select to line in (default select for this ADC) */
6046 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6047 /* set vol=0 Line-Out mixer amp left and right */
6048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6049 /* unmute pin widget amp left and right (no gain on this amp) */
6050 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6051 /* set vol=0 HP mixer amp left and right */
6052 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6053 /* unmute pin widget amp left and right (no gain on this amp) */
6054 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6055 /* set vol=0 Mono mixer amp left and right */
6056 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6057 /* unmute pin widget amp left and right (no gain on this amp) */
6058 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6059 /* unmute LINE-2 out pin */
6060 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6061 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6062 * Line In 2 = 0x03
6063 */
cb53c626
TI
6064 /* mute analog inputs */
6065 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6066 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6067 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6068 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6070 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6071 /* mute Front out path */
6072 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6074 /* mute Headphone out path */
6075 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6077 /* mute Mono out path */
6078 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6079 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6080 { }
6081};
6082
474167d6 6083#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6084static struct hda_verb alc260_hp_init_verbs[] = {
6085 /* Headphone and output */
6086 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6087 /* mono output */
6088 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6089 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6090 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6091 /* Mic2 (front panel) pin widget for input and vref at 80% */
6092 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6093 /* Line In pin widget for input */
6094 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6095 /* Line-2 pin widget for output */
6096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6097 /* CD pin widget for input */
6098 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6099 /* unmute amp left and right */
6100 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6101 /* set connection select to line in (default select for this ADC) */
6102 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6103 /* unmute Line-Out mixer amp left and right (volume = 0) */
6104 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6105 /* mute pin widget amp left and right (no gain on this amp) */
6106 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6107 /* unmute HP mixer amp left and right (volume = 0) */
6108 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6109 /* mute pin widget amp left and right (no gain on this amp) */
6110 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6111 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6112 * Line In 2 = 0x03
6113 */
cb53c626
TI
6114 /* mute analog inputs */
6115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6119 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6120 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6121 /* Unmute Front out path */
6122 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6123 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6124 /* Unmute Headphone out path */
6125 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6127 /* Unmute Mono out path */
6128 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6129 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6130 { }
6131};
474167d6 6132#endif
df694daa
KY
6133
6134static struct hda_verb alc260_hp_3013_init_verbs[] = {
6135 /* Line out and output */
6136 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6137 /* mono output */
6138 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6139 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6140 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6141 /* Mic2 (front panel) pin widget for input and vref at 80% */
6142 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6143 /* Line In pin widget for input */
6144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6145 /* Headphone pin widget for output */
6146 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6147 /* CD pin widget for input */
6148 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6149 /* unmute amp left and right */
6150 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6151 /* set connection select to line in (default select for this ADC) */
6152 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6153 /* unmute Line-Out mixer amp left and right (volume = 0) */
6154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6155 /* mute pin widget amp left and right (no gain on this amp) */
6156 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6157 /* unmute HP mixer amp left and right (volume = 0) */
6158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6159 /* mute pin widget amp left and right (no gain on this amp) */
6160 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6161 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6162 * Line In 2 = 0x03
6163 */
cb53c626
TI
6164 /* mute analog inputs */
6165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6168 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6169 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6170 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6171 /* Unmute Front out path */
6172 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6173 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6174 /* Unmute Headphone out path */
6175 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6176 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6177 /* Unmute Mono out path */
6178 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6179 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6180 { }
6181};
6182
a9430dd8 6183/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6184 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6185 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6186 */
6187static struct hda_verb alc260_fujitsu_init_verbs[] = {
6188 /* Disable all GPIOs */
6189 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6190 /* Internal speaker is connected to headphone pin */
6191 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6192 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6193 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6194 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6195 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6196 /* Ensure all other unused pins are disabled and muted. */
6197 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6198 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6199 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6200 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6201 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6202 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6205
6206 /* Disable digital (SPDIF) pins */
6207 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6208 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6209
ea1fb29a 6210 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6211 * when acting as an output.
6212 */
6213 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6214
f7ace40d 6215 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6216 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6217 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6218 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6219 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6220 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6221 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6222 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6223 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6224 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6225
f7ace40d
JW
6226 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6227 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6228 /* Unmute Line1 pin widget output buffer since it starts as an output.
6229 * If the pin mode is changed by the user the pin mode control will
6230 * take care of enabling the pin's input/output buffers as needed.
6231 * Therefore there's no need to enable the input buffer at this
6232 * stage.
cdcd9268 6233 */
f7ace40d 6234 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6235 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6236 * mixer ctrl)
6237 */
f7ace40d
JW
6238 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6239
6240 /* Mute capture amp left and right */
6241 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6242 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6243 * in (on mic1 pin)
6244 */
6245 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6246
6247 /* Do the same for the second ADC: mute capture input amp and
6248 * set ADC connection to line in (on mic1 pin)
6249 */
6250 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6251 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6252
6253 /* Mute all inputs to mixer widget (even unconnected ones) */
6254 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6256 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6259 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6260 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6261 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6262
6263 { }
a9430dd8
JW
6264};
6265
0bfc90e9
JW
6266/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6267 * similar laptops (adapted from Fujitsu init verbs).
6268 */
6269static struct hda_verb alc260_acer_init_verbs[] = {
6270 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6271 * the headphone jack. Turn this on and rely on the standard mute
6272 * methods whenever the user wants to turn these outputs off.
6273 */
6274 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6275 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6276 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6277 /* Internal speaker/Headphone jack is connected to Line-out pin */
6278 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6279 /* Internal microphone/Mic jack is connected to Mic1 pin */
6280 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6281 /* Line In jack is connected to Line1 pin */
6282 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6283 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6284 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6285 /* Ensure all other unused pins are disabled and muted. */
6286 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6287 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6288 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6289 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6292 /* Disable digital (SPDIF) pins */
6293 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6294 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6295
ea1fb29a 6296 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6297 * bus when acting as outputs.
6298 */
6299 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6300 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6301
6302 /* Start with output sum widgets muted and their output gains at min */
6303 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6304 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6305 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6306 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6307 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6308 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6309 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6310 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6311 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6312
f12ab1e0
TI
6313 /* Unmute Line-out pin widget amp left and right
6314 * (no equiv mixer ctrl)
6315 */
0bfc90e9 6316 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6317 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6318 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6319 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6320 * inputs. If the pin mode is changed by the user the pin mode control
6321 * will take care of enabling the pin's input/output buffers as needed.
6322 * Therefore there's no need to enable the input buffer at this
6323 * stage.
6324 */
6325 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6327
6328 /* Mute capture amp left and right */
6329 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6330 /* Set ADC connection select to match default mixer setting - mic
6331 * (on mic1 pin)
6332 */
6333 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6334
6335 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6336 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6337 */
6338 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6339 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6340
6341 /* Mute all inputs to mixer widget (even unconnected ones) */
6342 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6343 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6344 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6345 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6346 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6347 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6348 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6349 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6350
6351 { }
6352};
6353
cc959489
MS
6354/* Initialisation sequence for Maxdata Favorit 100XS
6355 * (adapted from Acer init verbs).
6356 */
6357static struct hda_verb alc260_favorit100_init_verbs[] = {
6358 /* GPIO 0 enables the output jack.
6359 * Turn this on and rely on the standard mute
6360 * methods whenever the user wants to turn these outputs off.
6361 */
6362 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6363 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6364 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6365 /* Line/Mic input jack is connected to Mic1 pin */
6366 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6367 /* Ensure all other unused pins are disabled and muted. */
6368 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6369 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6370 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6371 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6372 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6373 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6374 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6375 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6378 /* Disable digital (SPDIF) pins */
6379 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6380 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6381
6382 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6383 * bus when acting as outputs.
6384 */
6385 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6386 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6387
6388 /* Start with output sum widgets muted and their output gains at min */
6389 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6390 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6391 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6392 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6394 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6395 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6396 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6397 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6398
6399 /* Unmute Line-out pin widget amp left and right
6400 * (no equiv mixer ctrl)
6401 */
6402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6403 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6404 * inputs. If the pin mode is changed by the user the pin mode control
6405 * will take care of enabling the pin's input/output buffers as needed.
6406 * Therefore there's no need to enable the input buffer at this
6407 * stage.
6408 */
6409 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6410
6411 /* Mute capture amp left and right */
6412 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6413 /* Set ADC connection select to match default mixer setting - mic
6414 * (on mic1 pin)
6415 */
6416 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6417
6418 /* Do similar with the second ADC: mute capture input amp and
6419 * set ADC connection to mic to match ALSA's default state.
6420 */
6421 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6422 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6423
6424 /* Mute all inputs to mixer widget (even unconnected ones) */
6425 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6426 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6427 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6433
6434 { }
6435};
6436
bc9f98a9
KY
6437static struct hda_verb alc260_will_verbs[] = {
6438 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6439 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6440 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6441 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6442 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6443 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6444 {}
6445};
6446
6447static struct hda_verb alc260_replacer_672v_verbs[] = {
6448 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6449 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6450 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6451
6452 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6453 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6454 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6455
6456 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6457 {}
6458};
6459
6460/* toggle speaker-output according to the hp-jack state */
6461static void alc260_replacer_672v_automute(struct hda_codec *codec)
6462{
6463 unsigned int present;
6464
6465 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6466 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6467 if (present) {
82beb8fd
TI
6468 snd_hda_codec_write_cache(codec, 0x01, 0,
6469 AC_VERB_SET_GPIO_DATA, 1);
6470 snd_hda_codec_write_cache(codec, 0x0f, 0,
6471 AC_VERB_SET_PIN_WIDGET_CONTROL,
6472 PIN_HP);
bc9f98a9 6473 } else {
82beb8fd
TI
6474 snd_hda_codec_write_cache(codec, 0x01, 0,
6475 AC_VERB_SET_GPIO_DATA, 0);
6476 snd_hda_codec_write_cache(codec, 0x0f, 0,
6477 AC_VERB_SET_PIN_WIDGET_CONTROL,
6478 PIN_OUT);
bc9f98a9
KY
6479 }
6480}
6481
6482static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6483 unsigned int res)
6484{
6485 if ((res >> 26) == ALC880_HP_EVENT)
6486 alc260_replacer_672v_automute(codec);
6487}
6488
3f878308
KY
6489static struct hda_verb alc260_hp_dc7600_verbs[] = {
6490 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6491 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6492 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6493 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6494 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6496 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6497 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6498 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6499 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6500 {}
6501};
6502
7cf51e48
JW
6503/* Test configuration for debugging, modelled after the ALC880 test
6504 * configuration.
6505 */
6506#ifdef CONFIG_SND_DEBUG
6507static hda_nid_t alc260_test_dac_nids[1] = {
6508 0x02,
6509};
6510static hda_nid_t alc260_test_adc_nids[2] = {
6511 0x04, 0x05,
6512};
a1e8d2da 6513/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6514 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6515 * is NID 0x04.
17e7aec6 6516 */
a1e8d2da
JW
6517static struct hda_input_mux alc260_test_capture_sources[2] = {
6518 {
6519 .num_items = 7,
6520 .items = {
6521 { "MIC1 pin", 0x0 },
6522 { "MIC2 pin", 0x1 },
6523 { "LINE1 pin", 0x2 },
6524 { "LINE2 pin", 0x3 },
6525 { "CD pin", 0x4 },
6526 { "LINE-OUT pin", 0x5 },
6527 { "HP-OUT pin", 0x6 },
6528 },
6529 },
6530 {
6531 .num_items = 8,
6532 .items = {
6533 { "MIC1 pin", 0x0 },
6534 { "MIC2 pin", 0x1 },
6535 { "LINE1 pin", 0x2 },
6536 { "LINE2 pin", 0x3 },
6537 { "CD pin", 0x4 },
6538 { "Mixer", 0x5 },
6539 { "LINE-OUT pin", 0x6 },
6540 { "HP-OUT pin", 0x7 },
6541 },
7cf51e48
JW
6542 },
6543};
6544static struct snd_kcontrol_new alc260_test_mixer[] = {
6545 /* Output driver widgets */
6546 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6547 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6548 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6549 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6550 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6551 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6552
a1e8d2da
JW
6553 /* Modes for retasking pin widgets
6554 * Note: the ALC260 doesn't seem to act on requests to enable mic
6555 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6556 * mention this restriction. At this stage it's not clear whether
6557 * this behaviour is intentional or is a hardware bug in chip
6558 * revisions available at least up until early 2006. Therefore for
6559 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6560 * choices, but if it turns out that the lack of mic bias for these
6561 * NIDs is intentional we could change their modes from
6562 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6563 */
7cf51e48
JW
6564 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6565 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6566 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6567 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6568 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6569 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6570
6571 /* Loopback mixer controls */
6572 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6573 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6574 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6575 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6576 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6577 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6578 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6579 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6580 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6581 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6582 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6583 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6584 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6585 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6586
6587 /* Controls for GPIO pins, assuming they are configured as outputs */
6588 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6589 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6590 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6591 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6592
92621f13
JW
6593 /* Switches to allow the digital IO pins to be enabled. The datasheet
6594 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6595 * make this output available should provide clarification.
92621f13
JW
6596 */
6597 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6598 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6599
f8225f6d
JW
6600 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6601 * this output to turn on an external amplifier.
6602 */
6603 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6604 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6605
7cf51e48
JW
6606 { } /* end */
6607};
6608static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6609 /* Enable all GPIOs as outputs with an initial value of 0 */
6610 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6611 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6612 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6613
7cf51e48
JW
6614 /* Enable retasking pins as output, initially without power amp */
6615 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6616 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6617 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6619 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6620 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6621
92621f13
JW
6622 /* Disable digital (SPDIF) pins initially, but users can enable
6623 * them via a mixer switch. In the case of SPDIF-out, this initverb
6624 * payload also sets the generation to 0, output to be in "consumer"
6625 * PCM format, copyright asserted, no pre-emphasis and no validity
6626 * control.
6627 */
7cf51e48
JW
6628 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6629 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6630
ea1fb29a 6631 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6632 * OUT1 sum bus when acting as an output.
6633 */
6634 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6635 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6636 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6637 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6638
6639 /* Start with output sum widgets muted and their output gains at min */
6640 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6641 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6642 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6643 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6644 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6645 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6646 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6647 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6648 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6649
cdcd9268
JW
6650 /* Unmute retasking pin widget output buffers since the default
6651 * state appears to be output. As the pin mode is changed by the
6652 * user the pin mode control will take care of enabling the pin's
6653 * input/output buffers as needed.
6654 */
7cf51e48
JW
6655 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6656 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6657 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6658 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6659 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6660 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6661 /* Also unmute the mono-out pin widget */
6662 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6663
7cf51e48
JW
6664 /* Mute capture amp left and right */
6665 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6666 /* Set ADC connection select to match default mixer setting (mic1
6667 * pin)
7cf51e48
JW
6668 */
6669 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6670
6671 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6672 * set ADC connection to mic1 pin
7cf51e48
JW
6673 */
6674 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6675 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6676
6677 /* Mute all inputs to mixer widget (even unconnected ones) */
6678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6679 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6680 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6686
6687 { }
6688};
6689#endif
6690
6330079f
TI
6691#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6692#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6693
a3bcba38
TI
6694#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6695#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6696
df694daa
KY
6697/*
6698 * for BIOS auto-configuration
6699 */
16ded525 6700
df694daa 6701static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6702 const char *pfx, int *vol_bits)
df694daa
KY
6703{
6704 hda_nid_t nid_vol;
6705 unsigned long vol_val, sw_val;
df694daa
KY
6706 int err;
6707
6708 if (nid >= 0x0f && nid < 0x11) {
6709 nid_vol = nid - 0x7;
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 if (nid == 0x11) {
6713 nid_vol = nid - 0x7;
6714 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6715 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6716 } else if (nid >= 0x12 && nid <= 0x15) {
6717 nid_vol = 0x08;
6718 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6719 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6720 } else
6721 return 0; /* N/A */
ea1fb29a 6722
863b4518
TI
6723 if (!(*vol_bits & (1 << nid_vol))) {
6724 /* first control for the volume widget */
0afe5f89 6725 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6726 if (err < 0)
6727 return err;
6728 *vol_bits |= (1 << nid_vol);
6729 }
0afe5f89 6730 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6731 if (err < 0)
df694daa
KY
6732 return err;
6733 return 1;
6734}
6735
6736/* add playback controls from the parsed DAC table */
6737static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6738 const struct auto_pin_cfg *cfg)
6739{
6740 hda_nid_t nid;
6741 int err;
863b4518 6742 int vols = 0;
df694daa
KY
6743
6744 spec->multiout.num_dacs = 1;
6745 spec->multiout.dac_nids = spec->private_dac_nids;
6746 spec->multiout.dac_nids[0] = 0x02;
6747
6748 nid = cfg->line_out_pins[0];
6749 if (nid) {
23112d6d
TI
6750 const char *pfx;
6751 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6752 pfx = "Master";
6753 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6754 pfx = "Speaker";
6755 else
6756 pfx = "Front";
6757 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6758 if (err < 0)
6759 return err;
6760 }
6761
82bc955f 6762 nid = cfg->speaker_pins[0];
df694daa 6763 if (nid) {
863b4518 6764 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6765 if (err < 0)
6766 return err;
6767 }
6768
eb06ed8f 6769 nid = cfg->hp_pins[0];
df694daa 6770 if (nid) {
863b4518
TI
6771 err = alc260_add_playback_controls(spec, nid, "Headphone",
6772 &vols);
df694daa
KY
6773 if (err < 0)
6774 return err;
6775 }
f12ab1e0 6776 return 0;
df694daa
KY
6777}
6778
6779/* create playback/capture controls for input pins */
05f5f477 6780static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6781 const struct auto_pin_cfg *cfg)
6782{
05f5f477 6783 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6784}
6785
6786static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6787 hda_nid_t nid, int pin_type,
6788 int sel_idx)
6789{
f6c7e546 6790 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6791 /* need the manual connection? */
6792 if (nid >= 0x12) {
6793 int idx = nid - 0x12;
6794 snd_hda_codec_write(codec, idx + 0x0b, 0,
6795 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6796 }
6797}
6798
6799static void alc260_auto_init_multi_out(struct hda_codec *codec)
6800{
6801 struct alc_spec *spec = codec->spec;
6802 hda_nid_t nid;
6803
f12ab1e0 6804 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6805 if (nid) {
6806 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6807 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6808 }
ea1fb29a 6809
82bc955f 6810 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6811 if (nid)
6812 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6813
eb06ed8f 6814 nid = spec->autocfg.hp_pins[0];
df694daa 6815 if (nid)
baba8ee9 6816 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6817}
df694daa
KY
6818
6819#define ALC260_PIN_CD_NID 0x16
6820static void alc260_auto_init_analog_input(struct hda_codec *codec)
6821{
6822 struct alc_spec *spec = codec->spec;
66ceeb6b 6823 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6824 int i;
6825
66ceeb6b
TI
6826 for (i = 0; i < cfg->num_inputs; i++) {
6827 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6828 if (nid >= 0x12) {
30ea098f 6829 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6830 if (nid != ALC260_PIN_CD_NID &&
6831 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6832 snd_hda_codec_write(codec, nid, 0,
6833 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6834 AMP_OUT_MUTE);
6835 }
6836 }
6837}
6838
7f311a46
TI
6839#define alc260_auto_init_input_src alc880_auto_init_input_src
6840
df694daa
KY
6841/*
6842 * generic initialization of ADC, input mixers and output mixers
6843 */
6844static struct hda_verb alc260_volume_init_verbs[] = {
6845 /*
6846 * Unmute ADC0-1 and set the default input to mic-in
6847 */
6848 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6849 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6850 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6851 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6852
df694daa
KY
6853 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6854 * mixer widget
f12ab1e0
TI
6855 * Note: PASD motherboards uses the Line In 2 as the input for
6856 * front panel mic (mic 2)
df694daa
KY
6857 */
6858 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6859 /* mute analog inputs */
6860 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6862 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6863 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6864 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6865
6866 /*
6867 * Set up output mixers (0x08 - 0x0a)
6868 */
6869 /* set vol=0 to output mixers */
6870 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6871 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6872 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6873 /* set up input amps for analog loopback */
6874 /* Amp Indices: DAC = 0, mixer = 1 */
6875 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6876 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6877 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6878 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6879 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6880 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6881
df694daa
KY
6882 { }
6883};
6884
6885static int alc260_parse_auto_config(struct hda_codec *codec)
6886{
6887 struct alc_spec *spec = codec->spec;
df694daa
KY
6888 int err;
6889 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6890
f12ab1e0
TI
6891 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6892 alc260_ignore);
6893 if (err < 0)
df694daa 6894 return err;
f12ab1e0
TI
6895 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6896 if (err < 0)
4a471b7d 6897 return err;
603c4019 6898 if (!spec->kctls.list)
df694daa 6899 return 0; /* can't find valid BIOS pin config */
05f5f477 6900 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6901 if (err < 0)
df694daa
KY
6902 return err;
6903
6904 spec->multiout.max_channels = 2;
6905
0852d7a6 6906 if (spec->autocfg.dig_outs)
df694daa 6907 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6908 if (spec->kctls.list)
d88897ea 6909 add_mixer(spec, spec->kctls.list);
df694daa 6910
d88897ea 6911 add_verb(spec, alc260_volume_init_verbs);
df694daa 6912
a1e8d2da 6913 spec->num_mux_defs = 1;
61b9b9b1 6914 spec->input_mux = &spec->private_imux[0];
df694daa 6915
6227cdce 6916 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6917
df694daa
KY
6918 return 1;
6919}
6920
ae6b813a
TI
6921/* additional initialization for auto-configuration model */
6922static void alc260_auto_init(struct hda_codec *codec)
df694daa 6923{
f6c7e546 6924 struct alc_spec *spec = codec->spec;
df694daa
KY
6925 alc260_auto_init_multi_out(codec);
6926 alc260_auto_init_analog_input(codec);
7f311a46 6927 alc260_auto_init_input_src(codec);
757899ac 6928 alc_auto_init_digital(codec);
f6c7e546 6929 if (spec->unsol_event)
7fb0d78f 6930 alc_inithook(codec);
df694daa
KY
6931}
6932
cb53c626
TI
6933#ifdef CONFIG_SND_HDA_POWER_SAVE
6934static struct hda_amp_list alc260_loopbacks[] = {
6935 { 0x07, HDA_INPUT, 0 },
6936 { 0x07, HDA_INPUT, 1 },
6937 { 0x07, HDA_INPUT, 2 },
6938 { 0x07, HDA_INPUT, 3 },
6939 { 0x07, HDA_INPUT, 4 },
6940 { } /* end */
6941};
6942#endif
6943
fc091769
TI
6944/*
6945 * Pin config fixes
6946 */
6947enum {
6948 PINFIX_HP_DC5750,
6949};
6950
fc091769
TI
6951static const struct alc_fixup alc260_fixups[] = {
6952 [PINFIX_HP_DC5750] = {
73413b12
TI
6953 .pins = (const struct alc_pincfg[]) {
6954 { 0x11, 0x90130110 }, /* speaker */
6955 { }
6956 }
fc091769
TI
6957 },
6958};
6959
6960static struct snd_pci_quirk alc260_fixup_tbl[] = {
6961 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
6962 {}
6963};
6964
df694daa
KY
6965/*
6966 * ALC260 configurations
6967 */
f5fcc13c
TI
6968static const char *alc260_models[ALC260_MODEL_LAST] = {
6969 [ALC260_BASIC] = "basic",
6970 [ALC260_HP] = "hp",
6971 [ALC260_HP_3013] = "hp-3013",
2922c9af 6972 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6973 [ALC260_FUJITSU_S702X] = "fujitsu",
6974 [ALC260_ACER] = "acer",
bc9f98a9
KY
6975 [ALC260_WILL] = "will",
6976 [ALC260_REPLACER_672V] = "replacer",
cc959489 6977 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6978#ifdef CONFIG_SND_DEBUG
f5fcc13c 6979 [ALC260_TEST] = "test",
7cf51e48 6980#endif
f5fcc13c
TI
6981 [ALC260_AUTO] = "auto",
6982};
6983
6984static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6985 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6986 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6987 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6988 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6989 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6990 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6991 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6992 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6993 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6994 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6995 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6996 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6997 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6998 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6999 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7000 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7001 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7002 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7003 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7004 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7005 {}
7006};
7007
7008static struct alc_config_preset alc260_presets[] = {
7009 [ALC260_BASIC] = {
7010 .mixers = { alc260_base_output_mixer,
45bdd1c1 7011 alc260_input_mixer },
df694daa
KY
7012 .init_verbs = { alc260_init_verbs },
7013 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7014 .dac_nids = alc260_dac_nids,
f9e336f6 7015 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7016 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7017 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7018 .channel_mode = alc260_modes,
7019 .input_mux = &alc260_capture_source,
7020 },
7021 [ALC260_HP] = {
bec15c3a 7022 .mixers = { alc260_hp_output_mixer,
f9e336f6 7023 alc260_input_mixer },
bec15c3a
TI
7024 .init_verbs = { alc260_init_verbs,
7025 alc260_hp_unsol_verbs },
df694daa
KY
7026 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7027 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7028 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7029 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7030 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7031 .channel_mode = alc260_modes,
7032 .input_mux = &alc260_capture_source,
bec15c3a
TI
7033 .unsol_event = alc260_hp_unsol_event,
7034 .init_hook = alc260_hp_automute,
df694daa 7035 },
3f878308
KY
7036 [ALC260_HP_DC7600] = {
7037 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7038 alc260_input_mixer },
3f878308
KY
7039 .init_verbs = { alc260_init_verbs,
7040 alc260_hp_dc7600_verbs },
7041 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7042 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7043 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7044 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7045 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7046 .channel_mode = alc260_modes,
7047 .input_mux = &alc260_capture_source,
7048 .unsol_event = alc260_hp_3012_unsol_event,
7049 .init_hook = alc260_hp_3012_automute,
7050 },
df694daa
KY
7051 [ALC260_HP_3013] = {
7052 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7053 alc260_input_mixer },
bec15c3a
TI
7054 .init_verbs = { alc260_hp_3013_init_verbs,
7055 alc260_hp_3013_unsol_verbs },
df694daa
KY
7056 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7057 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7058 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7059 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7060 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7061 .channel_mode = alc260_modes,
7062 .input_mux = &alc260_capture_source,
bec15c3a
TI
7063 .unsol_event = alc260_hp_3013_unsol_event,
7064 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7065 },
7066 [ALC260_FUJITSU_S702X] = {
f9e336f6 7067 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7068 .init_verbs = { alc260_fujitsu_init_verbs },
7069 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7070 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7071 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7072 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7073 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7074 .channel_mode = alc260_modes,
a1e8d2da
JW
7075 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7076 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7077 },
0bfc90e9 7078 [ALC260_ACER] = {
f9e336f6 7079 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7080 .init_verbs = { alc260_acer_init_verbs },
7081 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7082 .dac_nids = alc260_dac_nids,
7083 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7084 .adc_nids = alc260_dual_adc_nids,
7085 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7086 .channel_mode = alc260_modes,
a1e8d2da
JW
7087 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7088 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7089 },
cc959489
MS
7090 [ALC260_FAVORIT100] = {
7091 .mixers = { alc260_favorit100_mixer },
7092 .init_verbs = { alc260_favorit100_init_verbs },
7093 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7094 .dac_nids = alc260_dac_nids,
7095 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7096 .adc_nids = alc260_dual_adc_nids,
7097 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7098 .channel_mode = alc260_modes,
7099 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7100 .input_mux = alc260_favorit100_capture_sources,
7101 },
bc9f98a9 7102 [ALC260_WILL] = {
f9e336f6 7103 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7104 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7105 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7106 .dac_nids = alc260_dac_nids,
7107 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7108 .adc_nids = alc260_adc_nids,
7109 .dig_out_nid = ALC260_DIGOUT_NID,
7110 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7111 .channel_mode = alc260_modes,
7112 .input_mux = &alc260_capture_source,
7113 },
7114 [ALC260_REPLACER_672V] = {
f9e336f6 7115 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7116 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7117 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7118 .dac_nids = alc260_dac_nids,
7119 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7120 .adc_nids = alc260_adc_nids,
7121 .dig_out_nid = ALC260_DIGOUT_NID,
7122 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7123 .channel_mode = alc260_modes,
7124 .input_mux = &alc260_capture_source,
7125 .unsol_event = alc260_replacer_672v_unsol_event,
7126 .init_hook = alc260_replacer_672v_automute,
7127 },
7cf51e48
JW
7128#ifdef CONFIG_SND_DEBUG
7129 [ALC260_TEST] = {
f9e336f6 7130 .mixers = { alc260_test_mixer },
7cf51e48
JW
7131 .init_verbs = { alc260_test_init_verbs },
7132 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7133 .dac_nids = alc260_test_dac_nids,
7134 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7135 .adc_nids = alc260_test_adc_nids,
7136 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7137 .channel_mode = alc260_modes,
a1e8d2da
JW
7138 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7139 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7140 },
7141#endif
df694daa
KY
7142};
7143
7144static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7145{
7146 struct alc_spec *spec;
df694daa 7147 int err, board_config;
1da177e4 7148
e560d8d8 7149 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7150 if (spec == NULL)
7151 return -ENOMEM;
7152
7153 codec->spec = spec;
7154
f5fcc13c
TI
7155 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7156 alc260_models,
7157 alc260_cfg_tbl);
7158 if (board_config < 0) {
9a11f1aa 7159 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7160 codec->chip_name);
df694daa 7161 board_config = ALC260_AUTO;
16ded525 7162 }
1da177e4 7163
fc091769
TI
7164 if (board_config == ALC260_AUTO)
7165 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1);
7166
df694daa
KY
7167 if (board_config == ALC260_AUTO) {
7168 /* automatic parse from the BIOS config */
7169 err = alc260_parse_auto_config(codec);
7170 if (err < 0) {
7171 alc_free(codec);
7172 return err;
f12ab1e0 7173 } else if (!err) {
9c7f852e
TI
7174 printk(KERN_INFO
7175 "hda_codec: Cannot set up configuration "
7176 "from BIOS. Using base mode...\n");
df694daa
KY
7177 board_config = ALC260_BASIC;
7178 }
a9430dd8 7179 }
e9edcee0 7180
680cd536
KK
7181 err = snd_hda_attach_beep_device(codec, 0x1);
7182 if (err < 0) {
7183 alc_free(codec);
7184 return err;
7185 }
7186
df694daa 7187 if (board_config != ALC260_AUTO)
e9c364c0 7188 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7189
1da177e4
LT
7190 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7191 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7192 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7193
a3bcba38
TI
7194 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7195 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7196
4ef0ef19
TI
7197 if (!spec->adc_nids && spec->input_mux) {
7198 /* check whether NID 0x04 is valid */
7199 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7200 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7201 /* get type */
7202 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7203 spec->adc_nids = alc260_adc_nids_alt;
7204 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7205 } else {
7206 spec->adc_nids = alc260_adc_nids;
7207 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7208 }
7209 }
b59bdf3b 7210 set_capture_mixer(codec);
45bdd1c1 7211 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7212
fc091769
TI
7213 if (board_config == ALC260_AUTO)
7214 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0);
7215
2134ea4f
TI
7216 spec->vmaster_nid = 0x08;
7217
1da177e4 7218 codec->patch_ops = alc_patch_ops;
df694daa 7219 if (board_config == ALC260_AUTO)
ae6b813a 7220 spec->init_hook = alc260_auto_init;
cb53c626
TI
7221#ifdef CONFIG_SND_HDA_POWER_SAVE
7222 if (!spec->loopback.amplist)
7223 spec->loopback.amplist = alc260_loopbacks;
7224#endif
1da177e4
LT
7225
7226 return 0;
7227}
7228
e9edcee0 7229
1da177e4 7230/*
4953550a 7231 * ALC882/883/885/888/889 support
1da177e4
LT
7232 *
7233 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7234 * configuration. Each pin widget can choose any input DACs and a mixer.
7235 * Each ADC is connected from a mixer of all inputs. This makes possible
7236 * 6-channel independent captures.
7237 *
7238 * In addition, an independent DAC for the multi-playback (not used in this
7239 * driver yet).
7240 */
df694daa
KY
7241#define ALC882_DIGOUT_NID 0x06
7242#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7243#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7244#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7245#define ALC1200_DIGOUT_NID 0x10
7246
1da177e4 7247
d2a6d7dc 7248static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7249 { 8, NULL }
7250};
7251
4953550a 7252/* DACs */
1da177e4
LT
7253static hda_nid_t alc882_dac_nids[4] = {
7254 /* front, rear, clfe, rear_surr */
7255 0x02, 0x03, 0x04, 0x05
7256};
4953550a 7257#define alc883_dac_nids alc882_dac_nids
1da177e4 7258
4953550a 7259/* ADCs */
df694daa
KY
7260#define alc882_adc_nids alc880_adc_nids
7261#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7262#define alc883_adc_nids alc882_adc_nids_alt
7263static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7264static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7265#define alc889_adc_nids alc880_adc_nids
1da177e4 7266
e1406348
TI
7267static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7268static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7269#define alc883_capsrc_nids alc882_capsrc_nids_alt
7270static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7271#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7272
1da177e4
LT
7273/* input MUX */
7274/* FIXME: should be a matrix-type input source selection */
7275
7276static struct hda_input_mux alc882_capture_source = {
7277 .num_items = 4,
7278 .items = {
7279 { "Mic", 0x0 },
7280 { "Front Mic", 0x1 },
7281 { "Line", 0x2 },
7282 { "CD", 0x4 },
7283 },
7284};
41d5545d 7285
4953550a
TI
7286#define alc883_capture_source alc882_capture_source
7287
87a8c370
JK
7288static struct hda_input_mux alc889_capture_source = {
7289 .num_items = 3,
7290 .items = {
7291 { "Front Mic", 0x0 },
7292 { "Mic", 0x3 },
7293 { "Line", 0x2 },
7294 },
7295};
7296
41d5545d
KS
7297static struct hda_input_mux mb5_capture_source = {
7298 .num_items = 3,
7299 .items = {
7300 { "Mic", 0x1 },
b8f171e7 7301 { "Line", 0x7 },
41d5545d
KS
7302 { "CD", 0x4 },
7303 },
7304};
7305
e458b1fa
LY
7306static struct hda_input_mux macmini3_capture_source = {
7307 .num_items = 2,
7308 .items = {
7309 { "Line", 0x2 },
7310 { "CD", 0x4 },
7311 },
7312};
7313
4953550a
TI
7314static struct hda_input_mux alc883_3stack_6ch_intel = {
7315 .num_items = 4,
7316 .items = {
7317 { "Mic", 0x1 },
7318 { "Front Mic", 0x0 },
7319 { "Line", 0x2 },
7320 { "CD", 0x4 },
7321 },
7322};
7323
7324static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7325 .num_items = 2,
7326 .items = {
7327 { "Mic", 0x1 },
7328 { "Line", 0x2 },
7329 },
7330};
7331
7332static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7333 .num_items = 4,
7334 .items = {
7335 { "Mic", 0x0 },
150b432f 7336 { "Int Mic", 0x1 },
4953550a
TI
7337 { "Line", 0x2 },
7338 { "CD", 0x4 },
7339 },
7340};
7341
7342static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7343 .num_items = 2,
7344 .items = {
7345 { "Mic", 0x0 },
7346 { "Int Mic", 0x1 },
7347 },
7348};
7349
7350static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7351 .num_items = 3,
7352 .items = {
7353 { "Mic", 0x0 },
7354 { "Front Mic", 0x1 },
7355 { "Line", 0x4 },
7356 },
7357};
7358
7359static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7360 .num_items = 2,
7361 .items = {
7362 { "Mic", 0x0 },
7363 { "Line", 0x2 },
7364 },
7365};
7366
7367static struct hda_input_mux alc889A_mb31_capture_source = {
7368 .num_items = 2,
7369 .items = {
7370 { "Mic", 0x0 },
7371 /* Front Mic (0x01) unused */
7372 { "Line", 0x2 },
7373 /* Line 2 (0x03) unused */
af901ca1 7374 /* CD (0x04) unused? */
4953550a
TI
7375 },
7376};
7377
b7cccc52
JM
7378static struct hda_input_mux alc889A_imac91_capture_source = {
7379 .num_items = 2,
7380 .items = {
7381 { "Mic", 0x01 },
7382 { "Line", 0x2 }, /* Not sure! */
7383 },
7384};
7385
4953550a
TI
7386/*
7387 * 2ch mode
7388 */
7389static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7390 { 2, NULL }
7391};
7392
272a527c
KY
7393/*
7394 * 2ch mode
7395 */
7396static struct hda_verb alc882_3ST_ch2_init[] = {
7397 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7398 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7399 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7400 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7401 { } /* end */
7402};
7403
4953550a
TI
7404/*
7405 * 4ch mode
7406 */
7407static struct hda_verb alc882_3ST_ch4_init[] = {
7408 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7409 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7410 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7411 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7412 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7413 { } /* end */
7414};
7415
272a527c
KY
7416/*
7417 * 6ch mode
7418 */
7419static struct hda_verb alc882_3ST_ch6_init[] = {
7420 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7421 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7422 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7423 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7424 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7425 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7426 { } /* end */
7427};
7428
4953550a 7429static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7430 { 2, alc882_3ST_ch2_init },
4953550a 7431 { 4, alc882_3ST_ch4_init },
272a527c
KY
7432 { 6, alc882_3ST_ch6_init },
7433};
7434
4953550a
TI
7435#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7436
a65cc60f 7437/*
7438 * 2ch mode
7439 */
7440static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7441 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7442 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7443 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7444 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7445 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7446 { } /* end */
7447};
7448
7449/*
7450 * 4ch mode
7451 */
7452static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7453 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7454 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7455 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7456 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7457 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7458 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7459 { } /* end */
7460};
7461
7462/*
7463 * 6ch mode
7464 */
7465static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7466 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7467 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7468 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7469 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7470 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7471 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7472 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7473 { } /* end */
7474};
7475
7476static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7477 { 2, alc883_3ST_ch2_clevo_init },
7478 { 4, alc883_3ST_ch4_clevo_init },
7479 { 6, alc883_3ST_ch6_clevo_init },
7480};
7481
7482
df694daa
KY
7483/*
7484 * 6ch mode
7485 */
7486static struct hda_verb alc882_sixstack_ch6_init[] = {
7487 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7488 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7489 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7490 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7491 { } /* end */
7492};
7493
7494/*
7495 * 8ch mode
7496 */
7497static struct hda_verb alc882_sixstack_ch8_init[] = {
7498 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7499 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7500 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7501 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7502 { } /* end */
7503};
7504
7505static struct hda_channel_mode alc882_sixstack_modes[2] = {
7506 { 6, alc882_sixstack_ch6_init },
7507 { 8, alc882_sixstack_ch8_init },
7508};
7509
76e6f5a9
RH
7510
7511/* Macbook Air 2,1 */
7512
7513static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7514 { 2, NULL },
7515};
7516
87350ad0 7517/*
def319f9 7518 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7519 */
7520
7521/*
7522 * 2ch mode
7523 */
7524static struct hda_verb alc885_mbp_ch2_init[] = {
7525 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7526 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7527 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7528 { } /* end */
7529};
7530
7531/*
a3f730af 7532 * 4ch mode
87350ad0 7533 */
a3f730af 7534static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7535 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7536 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7537 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7538 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7539 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7540 { } /* end */
7541};
7542
a3f730af 7543static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7544 { 2, alc885_mbp_ch2_init },
a3f730af 7545 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7546};
7547
92b9de83
KS
7548/*
7549 * 2ch
7550 * Speakers/Woofer/HP = Front
7551 * LineIn = Input
7552 */
7553static struct hda_verb alc885_mb5_ch2_init[] = {
7554 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7556 { } /* end */
7557};
7558
7559/*
7560 * 6ch mode
7561 * Speakers/HP = Front
7562 * Woofer = LFE
7563 * LineIn = Surround
7564 */
7565static struct hda_verb alc885_mb5_ch6_init[] = {
7566 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7567 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7568 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7569 { } /* end */
7570};
7571
7572static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7573 { 2, alc885_mb5_ch2_init },
7574 { 6, alc885_mb5_ch6_init },
7575};
87350ad0 7576
d01aecdf 7577#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7578
7579/*
7580 * 2ch mode
7581 */
7582static struct hda_verb alc883_4ST_ch2_init[] = {
7583 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7584 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7585 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7586 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7587 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7588 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7589 { } /* end */
7590};
7591
7592/*
7593 * 4ch mode
7594 */
7595static struct hda_verb alc883_4ST_ch4_init[] = {
7596 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7597 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7598 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7599 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7600 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7601 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7602 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7603 { } /* end */
7604};
7605
7606/*
7607 * 6ch mode
7608 */
7609static struct hda_verb alc883_4ST_ch6_init[] = {
7610 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7611 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7612 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7613 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7614 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7615 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7616 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7617 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7618 { } /* end */
7619};
7620
7621/*
7622 * 8ch mode
7623 */
7624static struct hda_verb alc883_4ST_ch8_init[] = {
7625 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7626 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7627 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7628 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7629 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7630 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7631 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7632 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7633 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7634 { } /* end */
7635};
7636
7637static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7638 { 2, alc883_4ST_ch2_init },
7639 { 4, alc883_4ST_ch4_init },
7640 { 6, alc883_4ST_ch6_init },
7641 { 8, alc883_4ST_ch8_init },
7642};
7643
7644
7645/*
7646 * 2ch mode
7647 */
7648static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7649 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7650 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7651 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7652 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7653 { } /* end */
7654};
7655
7656/*
7657 * 4ch mode
7658 */
7659static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7660 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7661 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7662 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7663 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7664 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7665 { } /* end */
7666};
7667
7668/*
7669 * 6ch mode
7670 */
7671static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7672 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7673 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7674 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7675 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7676 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7677 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7678 { } /* end */
7679};
7680
7681static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7682 { 2, alc883_3ST_ch2_intel_init },
7683 { 4, alc883_3ST_ch4_intel_init },
7684 { 6, alc883_3ST_ch6_intel_init },
7685};
7686
dd7714c9
WF
7687/*
7688 * 2ch mode
7689 */
7690static struct hda_verb alc889_ch2_intel_init[] = {
7691 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7692 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7693 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7694 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7695 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7696 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7697 { } /* end */
7698};
7699
87a8c370
JK
7700/*
7701 * 6ch mode
7702 */
7703static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7704 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7705 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7706 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7707 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7708 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7709 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7710 { } /* end */
7711};
7712
7713/*
7714 * 8ch mode
7715 */
7716static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7717 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7718 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7719 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7720 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7721 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7722 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7723 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7724 { } /* end */
7725};
7726
dd7714c9
WF
7727static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7728 { 2, alc889_ch2_intel_init },
87a8c370
JK
7729 { 6, alc889_ch6_intel_init },
7730 { 8, alc889_ch8_intel_init },
7731};
7732
4953550a
TI
7733/*
7734 * 6ch mode
7735 */
7736static struct hda_verb alc883_sixstack_ch6_init[] = {
7737 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7738 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7739 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7740 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7741 { } /* end */
7742};
7743
7744/*
7745 * 8ch mode
7746 */
7747static struct hda_verb alc883_sixstack_ch8_init[] = {
7748 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7749 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7750 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7751 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7752 { } /* end */
7753};
7754
7755static struct hda_channel_mode alc883_sixstack_modes[2] = {
7756 { 6, alc883_sixstack_ch6_init },
7757 { 8, alc883_sixstack_ch8_init },
7758};
7759
7760
1da177e4
LT
7761/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7762 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7763 */
c8b6bf9b 7764static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7765 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7766 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7767 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7768 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7769 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7770 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7771 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7772 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7773 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7774 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7776 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7777 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7778 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7779 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7781 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7782 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7783 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7784 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7785 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7786 { } /* end */
7787};
7788
76e6f5a9
RH
7789/* Macbook Air 2,1 same control for HP and internal Speaker */
7790
7791static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7792 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7793 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7794 { }
7795};
7796
7797
87350ad0 7798static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7799 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7800 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7801 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7802 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7803 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7804 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7805 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7807 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7808 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7809 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7810 { } /* end */
7811};
41d5545d
KS
7812
7813static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7814 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7815 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7816 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7817 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7818 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7819 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7820 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7821 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7822 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7823 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7824 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7825 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7826 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7827 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7828 { } /* end */
7829};
92b9de83 7830
e458b1fa
LY
7831static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7832 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7833 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7834 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7835 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7836 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7837 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7838 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7839 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7840 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7841 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7842 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7843 { } /* end */
7844};
7845
4b7e1803 7846static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7847 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7848 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7849 { } /* end */
7850};
7851
7852
bdd148a3
KY
7853static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7854 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7855 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7858 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7859 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7863 { } /* end */
7864};
7865
272a527c
KY
7866static struct snd_kcontrol_new alc882_targa_mixer[] = {
7867 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7868 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7869 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7870 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7871 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7872 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7873 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7876 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7877 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7878 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7879 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7880 { } /* end */
7881};
7882
7883/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7884 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7885 */
7886static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7888 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7889 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7890 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7891 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7892 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7893 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7894 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7895 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7896 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7899 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7900 { } /* end */
7901};
7902
914759b7
TI
7903static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7904 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7905 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7906 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7907 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7908 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7909 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7910 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7912 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7914 { } /* end */
7915};
7916
df694daa
KY
7917static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7918 {
7919 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7920 .name = "Channel Mode",
7921 .info = alc_ch_mode_info,
7922 .get = alc_ch_mode_get,
7923 .put = alc_ch_mode_put,
7924 },
7925 { } /* end */
7926};
7927
4953550a 7928static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7929 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7932 /* Rear mixer */
05acb863
TI
7933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7935 /* CLFE mixer */
05acb863
TI
7936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7937 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7938 /* Side mixer */
05acb863
TI
7939 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7940 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7941
e9edcee0 7942 /* Front Pin: output 0 (0x0c) */
05acb863 7943 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7944 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7945 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7946 /* Rear Pin: output 1 (0x0d) */
05acb863 7947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7948 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7949 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7950 /* CLFE Pin: output 2 (0x0e) */
05acb863 7951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7952 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7953 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7954 /* Side Pin: output 3 (0x0f) */
05acb863 7955 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7956 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7957 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7958 /* Mic (rear) pin: input vref at 80% */
16ded525 7959 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7960 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7961 /* Front Mic pin: input vref at 80% */
16ded525 7962 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7963 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7964 /* Line In pin: input */
05acb863 7965 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7966 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7967 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7968 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7969 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7970 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7971 /* CD pin widget for input */
05acb863 7972 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7973
7974 /* FIXME: use matrix-type input source selection */
7975 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7976 /* Input mixer2 */
05acb863 7977 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7978 /* Input mixer3 */
05acb863 7979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7980 /* ADC2: mute amp left and right */
7981 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7982 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7983 /* ADC3: mute amp left and right */
7984 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7985 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7986
7987 { }
7988};
7989
4953550a
TI
7990static struct hda_verb alc882_adc1_init_verbs[] = {
7991 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7996 /* ADC1: mute amp left and right */
7997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7998 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7999 { }
8000};
8001
4b146cb0
TI
8002static struct hda_verb alc882_eapd_verbs[] = {
8003 /* change to EAPD mode */
8004 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8005 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8006 { }
4b146cb0
TI
8007};
8008
87a8c370
JK
8009static struct hda_verb alc889_eapd_verbs[] = {
8010 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8011 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8012 { }
8013};
8014
6732bd0d
WF
8015static struct hda_verb alc_hp15_unsol_verbs[] = {
8016 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8018 {}
8019};
87a8c370
JK
8020
8021static struct hda_verb alc885_init_verbs[] = {
8022 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8025 /* Rear mixer */
88102f3f
KY
8026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8028 /* CLFE mixer */
88102f3f
KY
8029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8030 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8031 /* Side mixer */
88102f3f
KY
8032 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8033 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8034
8035 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8036 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8037 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8038 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8039 /* Front Pin: output 0 (0x0c) */
8040 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8041 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8042 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8043 /* Rear Pin: output 1 (0x0d) */
8044 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8045 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8046 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8047 /* CLFE Pin: output 2 (0x0e) */
8048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8049 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8050 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8051 /* Side Pin: output 3 (0x0f) */
8052 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8053 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8054 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8055 /* Mic (rear) pin: input vref at 80% */
8056 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8057 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8058 /* Front Mic pin: input vref at 80% */
8059 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8060 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8061 /* Line In pin: input */
8062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8063 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8064
8065 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8066 /* Input mixer1 */
88102f3f 8067 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8068 /* Input mixer2 */
8069 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8070 /* Input mixer3 */
88102f3f 8071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8072 /* ADC2: mute amp left and right */
8073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8074 /* ADC3: mute amp left and right */
8075 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8076
8077 { }
8078};
8079
8080static struct hda_verb alc885_init_input_verbs[] = {
8081 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8082 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8083 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8084 { }
8085};
8086
8087
8088/* Unmute Selector 24h and set the default input to front mic */
8089static struct hda_verb alc889_init_input_verbs[] = {
8090 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8091 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8092 { }
8093};
8094
8095
4953550a
TI
8096#define alc883_init_verbs alc882_base_init_verbs
8097
9102cd1c
TD
8098/* Mac Pro test */
8099static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8100 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8101 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8102 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8103 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8104 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8105 /* FIXME: this looks suspicious...
d355c82a
JK
8106 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8107 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8108 */
9102cd1c
TD
8109 { } /* end */
8110};
8111
8112static struct hda_verb alc882_macpro_init_verbs[] = {
8113 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8117 /* Front Pin: output 0 (0x0c) */
8118 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8119 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8120 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8121 /* Front Mic pin: input vref at 80% */
8122 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8123 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8124 /* Speaker: output */
8125 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8126 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8127 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8128 /* Headphone output (output 0 - 0x0c) */
8129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8130 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8131 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8132
8133 /* FIXME: use matrix-type input source selection */
8134 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8135 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8136 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8138 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8139 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8140 /* Input mixer2 */
8141 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8142 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8143 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8144 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8145 /* Input mixer3 */
8146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8148 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8149 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8150 /* ADC1: mute amp left and right */
8151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8152 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8153 /* ADC2: mute amp left and right */
8154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8155 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8156 /* ADC3: mute amp left and right */
8157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8158 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8159
8160 { }
8161};
f12ab1e0 8162
41d5545d
KS
8163/* Macbook 5,1 */
8164static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8165 /* DACs */
8166 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8167 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8168 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8169 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8170 /* Front mixer */
41d5545d
KS
8171 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8172 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8173 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8174 /* Surround mixer */
8175 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8176 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8178 /* LFE mixer */
8179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8180 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8182 /* HP mixer */
8183 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8184 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8185 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8186 /* Front Pin (0x0c) */
41d5545d
KS
8187 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8188 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8189 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8190 /* LFE Pin (0x0e) */
8191 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8192 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8193 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8194 /* HP Pin (0x0f) */
41d5545d
KS
8195 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8196 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8197 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8198 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8199 /* Front Mic pin: input vref at 80% */
8200 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8202 /* Line In pin */
8203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8205
b8f171e7
AM
8206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8209 { }
8210};
8211
e458b1fa
LY
8212/* Macmini 3,1 */
8213static struct hda_verb alc885_macmini3_init_verbs[] = {
8214 /* DACs */
8215 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8216 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8217 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8218 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8219 /* Front mixer */
8220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8222 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8223 /* Surround mixer */
8224 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8225 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8226 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8227 /* LFE mixer */
8228 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8229 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8230 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8231 /* HP mixer */
8232 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8234 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8235 /* Front Pin (0x0c) */
8236 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8237 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8238 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8239 /* LFE Pin (0x0e) */
8240 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8241 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8242 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8243 /* HP Pin (0x0f) */
8244 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8245 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8246 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8247 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8248 /* Line In pin */
8249 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8250 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8251
8252 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8253 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8254 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8255 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8256 { }
8257};
8258
76e6f5a9
RH
8259
8260static struct hda_verb alc885_mba21_init_verbs[] = {
8261 /*Internal and HP Speaker Mixer*/
8262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8265 /*Internal Speaker Pin (0x0c)*/
8266 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8267 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8268 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8269 /* HP Pin: output 0 (0x0e) */
8270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8271 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8272 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8273 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8274 /* Line in (is hp when jack connected)*/
8275 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8276 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8277
8278 { }
8279 };
8280
8281
87350ad0
TI
8282/* Macbook Pro rev3 */
8283static struct hda_verb alc885_mbp3_init_verbs[] = {
8284 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8285 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8288 /* Rear mixer */
8289 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8290 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8291 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8292 /* HP mixer */
8293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8294 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8295 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8296 /* Front Pin: output 0 (0x0c) */
8297 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8298 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8299 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8300 /* HP Pin: output 0 (0x0e) */
87350ad0 8301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8303 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8305 /* Mic (rear) pin: input vref at 80% */
8306 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8307 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8308 /* Front Mic pin: input vref at 80% */
8309 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8310 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8311 /* Line In pin: use output 1 when in LineOut mode */
8312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8313 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8314 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8315
8316 /* FIXME: use matrix-type input source selection */
8317 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8318 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8319 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8321 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8322 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8323 /* Input mixer2 */
8324 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8325 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8326 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8327 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8328 /* Input mixer3 */
8329 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8330 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8332 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8333 /* ADC1: mute amp left and right */
8334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8335 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8336 /* ADC2: mute amp left and right */
8337 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8338 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8339 /* ADC3: mute amp left and right */
8340 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8341 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8342
8343 { }
8344};
8345
4b7e1803
JM
8346/* iMac 9,1 */
8347static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8348 /* Internal Speaker Pin (0x0c) */
8349 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8350 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8351 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8352 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8353 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8354 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8355 /* HP Pin: Rear */
4b7e1803
JM
8356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8358 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8359 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8360 /* Line in Rear */
8361 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8362 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8363 /* Front Mic pin: input vref at 80% */
8364 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8365 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8366 /* Rear mixer */
8367 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8368 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8370 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8374 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8379 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8384 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8389 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8390 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8392 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8393 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8394 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8395 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8397 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8398 { }
8399};
8400
c54728d8
NF
8401/* iMac 24 mixer. */
8402static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8403 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8404 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8405 { } /* end */
8406};
8407
8408/* iMac 24 init verbs. */
8409static struct hda_verb alc885_imac24_init_verbs[] = {
8410 /* Internal speakers: output 0 (0x0c) */
8411 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8412 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8413 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8414 /* Internal speakers: output 0 (0x0c) */
8415 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8416 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8417 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8418 /* Headphone: output 0 (0x0c) */
8419 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8420 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8421 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8422 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8423 /* Front Mic: input vref at 80% */
8424 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8425 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8426 { }
8427};
8428
8429/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8430static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8431{
a9fd4f3f 8432 struct alc_spec *spec = codec->spec;
c54728d8 8433
a9fd4f3f
TI
8434 spec->autocfg.hp_pins[0] = 0x14;
8435 spec->autocfg.speaker_pins[0] = 0x18;
8436 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8437}
8438
9d54f08b
TI
8439#define alc885_mb5_setup alc885_imac24_setup
8440#define alc885_macmini3_setup alc885_imac24_setup
8441
76e6f5a9
RH
8442/* Macbook Air 2,1 */
8443static void alc885_mba21_setup(struct hda_codec *codec)
8444{
8445 struct alc_spec *spec = codec->spec;
8446
8447 spec->autocfg.hp_pins[0] = 0x14;
8448 spec->autocfg.speaker_pins[0] = 0x18;
8449}
8450
8451
8452
4f5d1706 8453static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8454{
a9fd4f3f 8455 struct alc_spec *spec = codec->spec;
87350ad0 8456
a9fd4f3f
TI
8457 spec->autocfg.hp_pins[0] = 0x15;
8458 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8459}
8460
9d54f08b 8461static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8462{
9d54f08b 8463 struct alc_spec *spec = codec->spec;
4b7e1803 8464
9d54f08b 8465 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8466 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8467 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8468}
87350ad0 8469
272a527c
KY
8470static struct hda_verb alc882_targa_verbs[] = {
8471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8472 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8473
8474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8475 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8476
272a527c
KY
8477 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8478 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8479 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8480
8481 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8482 { } /* end */
8483};
8484
8485/* toggle speaker-output according to the hp-jack state */
8486static void alc882_targa_automute(struct hda_codec *codec)
8487{
a9fd4f3f
TI
8488 struct alc_spec *spec = codec->spec;
8489 alc_automute_amp(codec);
82beb8fd 8490 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8491 spec->jack_present ? 1 : 3);
8492}
8493
4f5d1706 8494static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8495{
8496 struct alc_spec *spec = codec->spec;
8497
8498 spec->autocfg.hp_pins[0] = 0x14;
8499 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8500}
8501
8502static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8503{
a9fd4f3f 8504 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8505 alc882_targa_automute(codec);
272a527c
KY
8506}
8507
8508static struct hda_verb alc882_asus_a7j_verbs[] = {
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8511
8512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8514 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8515
272a527c
KY
8516 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8518 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8519
8520 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8521 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8522 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8523 { } /* end */
8524};
8525
914759b7
TI
8526static struct hda_verb alc882_asus_a7m_verbs[] = {
8527 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8529
8530 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8531 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8532 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8533
914759b7
TI
8534 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8535 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8536 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8537
8538 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8539 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8540 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8541 { } /* end */
8542};
8543
9102cd1c
TD
8544static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8545{
8546 unsigned int gpiostate, gpiomask, gpiodir;
8547
8548 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8549 AC_VERB_GET_GPIO_DATA, 0);
8550
8551 if (!muted)
8552 gpiostate |= (1 << pin);
8553 else
8554 gpiostate &= ~(1 << pin);
8555
8556 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8557 AC_VERB_GET_GPIO_MASK, 0);
8558 gpiomask |= (1 << pin);
8559
8560 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8561 AC_VERB_GET_GPIO_DIRECTION, 0);
8562 gpiodir |= (1 << pin);
8563
8564
8565 snd_hda_codec_write(codec, codec->afg, 0,
8566 AC_VERB_SET_GPIO_MASK, gpiomask);
8567 snd_hda_codec_write(codec, codec->afg, 0,
8568 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8569
8570 msleep(1);
8571
8572 snd_hda_codec_write(codec, codec->afg, 0,
8573 AC_VERB_SET_GPIO_DATA, gpiostate);
8574}
8575
7debbe51
TI
8576/* set up GPIO at initialization */
8577static void alc885_macpro_init_hook(struct hda_codec *codec)
8578{
8579 alc882_gpio_mute(codec, 0, 0);
8580 alc882_gpio_mute(codec, 1, 0);
8581}
8582
8583/* set up GPIO and update auto-muting at initialization */
8584static void alc885_imac24_init_hook(struct hda_codec *codec)
8585{
8586 alc885_macpro_init_hook(codec);
4f5d1706 8587 alc_automute_amp(codec);
7debbe51
TI
8588}
8589
df694daa
KY
8590/*
8591 * generic initialization of ADC, input mixers and output mixers
8592 */
4953550a 8593static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8594 /*
8595 * Unmute ADC0-2 and set the default input to mic-in
8596 */
4953550a
TI
8597 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8598 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8599 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8600 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8601
4953550a
TI
8602 /*
8603 * Set up output mixers (0x0c - 0x0f)
8604 */
8605 /* set vol=0 to output mixers */
8606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8608 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8609 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8610 /* set up input amps for analog loopback */
8611 /* Amp Indices: DAC = 0, mixer = 1 */
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8614 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8616 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8617 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8618 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8619 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8620 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8621 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8622
4953550a
TI
8623 /* FIXME: use matrix-type input source selection */
8624 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8625 /* Input mixer2 */
88102f3f 8626 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8627 /* Input mixer3 */
88102f3f 8628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8629 { }
9c7f852e
TI
8630};
8631
eb4c41d3
TS
8632/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8633static struct hda_verb alc889A_mb31_ch2_init[] = {
8634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8635 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8636 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8638 { } /* end */
8639};
8640
8641/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8642static struct hda_verb alc889A_mb31_ch4_init[] = {
8643 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8644 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8645 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8647 { } /* end */
8648};
8649
8650/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8651static struct hda_verb alc889A_mb31_ch5_init[] = {
8652 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8653 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8654 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8655 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8656 { } /* end */
8657};
8658
8659/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8660static struct hda_verb alc889A_mb31_ch6_init[] = {
8661 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8662 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8663 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8664 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8665 { } /* end */
8666};
8667
8668static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8669 { 2, alc889A_mb31_ch2_init },
8670 { 4, alc889A_mb31_ch4_init },
8671 { 5, alc889A_mb31_ch5_init },
8672 { 6, alc889A_mb31_ch6_init },
8673};
8674
b373bdeb
AN
8675static struct hda_verb alc883_medion_eapd_verbs[] = {
8676 /* eanable EAPD on medion laptop */
8677 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8678 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8679 { }
8680};
8681
4953550a 8682#define alc883_base_mixer alc882_base_mixer
834be88d 8683
a8848bd6
AS
8684static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8685 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8686 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8687 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8688 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8689 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8690 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8693 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8695 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8696 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8697 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8698 { } /* end */
8699};
8700
0c4cc443 8701static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8702 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8703 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8704 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8705 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8707 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8709 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8710 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8711 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8712 { } /* end */
8713};
8714
fb97dc67
J
8715static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8716 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8717 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8718 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8719 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8721 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8722 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8723 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8724 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8725 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8726 { } /* end */
8727};
8728
9c7f852e
TI
8729static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8730 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8731 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8732 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8733 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8734 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8735 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8736 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8737 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8738 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8740 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8741 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8742 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8743 { } /* end */
8744};
df694daa 8745
9c7f852e
TI
8746static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8747 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8748 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8749 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8750 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8751 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8752 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8753 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8754 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8756 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8757 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8758 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8759 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8761 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8762 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8763 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8764 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8765 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8766 { } /* end */
8767};
8768
17bba1b7
J
8769static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8770 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8771 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8772 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8773 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8774 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8775 HDA_OUTPUT),
8776 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8777 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8778 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8780 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8781 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8782 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8783 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8785 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8786 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8787 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8788 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8789 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8790 { } /* end */
8791};
8792
87a8c370
JK
8793static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8794 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8795 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8796 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8797 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8798 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8799 HDA_OUTPUT),
8800 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8801 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8802 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8803 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8804 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8805 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8806 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8807 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8808 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8809 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8811 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8812 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8813 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8814 { } /* end */
8815};
8816
d1d985f0 8817static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8818 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8819 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8820 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8821 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8822 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8823 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8824 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8825 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8826 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8827 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8828 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8829 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8830 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8831 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8832 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8834 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8835 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8836 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8837 { } /* end */
8838};
8839
c259249f 8840static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8841 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8842 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8844 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8845 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8846 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8847 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8848 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8849 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8850 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8851 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8852 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8853 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8854 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8856 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8858 { } /* end */
f12ab1e0 8859};
ccc656ce 8860
c259249f 8861static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8862 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8863 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8864 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8865 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8866 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8867 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8869 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8870 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8871 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8872 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8873 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8874 { } /* end */
f12ab1e0 8875};
ccc656ce 8876
b99dba34
TI
8877static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8878 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8879 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8880 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8881 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8882 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8883 { } /* end */
8884};
8885
bc9f98a9
KY
8886static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8888 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8889 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8890 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8891 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8892 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8893 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8894 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8895 { } /* end */
f12ab1e0 8896};
bc9f98a9 8897
272a527c
KY
8898static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8899 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8900 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8901 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8902 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8903 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
150b432f
DH
8906 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8907 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8908 { } /* end */
8909};
8910
8911static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8912 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8914 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8915 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8916 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8917 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8919 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8920 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8921 { } /* end */
ea1fb29a 8922};
272a527c 8923
7ad7b218
MC
8924static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8926 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8927 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8929 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8930 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8931 { } /* end */
8932};
8933
8934static struct hda_verb alc883_medion_wim2160_verbs[] = {
8935 /* Unmute front mixer */
8936 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8937 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8938
8939 /* Set speaker pin to front mixer */
8940 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8941
8942 /* Init headphone pin */
8943 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8944 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8945 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8946 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8947
8948 { } /* end */
8949};
8950
8951/* toggle speaker-output according to the hp-jack state */
8952static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8953{
8954 struct alc_spec *spec = codec->spec;
8955
8956 spec->autocfg.hp_pins[0] = 0x1a;
8957 spec->autocfg.speaker_pins[0] = 0x15;
8958}
8959
2880a867 8960static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8962 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8963 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8964 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8965 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8966 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8967 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8968 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8969 { } /* end */
d1a991a6 8970};
2880a867 8971
d2fd4b09
TV
8972static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8973 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 8974 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
8975 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8976 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8977 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8978 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8980 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8981 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8982 { } /* end */
8983};
8984
e2757d5e
KY
8985static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8988 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8989 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8990 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8991 0x0d, 1, 0x0, HDA_OUTPUT),
8992 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8993 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8994 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8995 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8996 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8997 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8998 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8999 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9000 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9001 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9002 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9003 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9004 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9005 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9006 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9007 { } /* end */
9008};
9009
eb4c41d3
TS
9010static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9011 /* Output mixers */
9012 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9013 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9014 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9015 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9016 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9017 HDA_OUTPUT),
9018 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9019 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9020 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9021 /* Output switches */
9022 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9023 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9024 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9025 /* Boost mixers */
9026 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
9027 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
9028 /* Input mixers */
9029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9030 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9032 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9033 { } /* end */
9034};
9035
3e1647c5
GG
9036static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9037 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9038 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9039 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9041 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9043 { } /* end */
9044};
9045
e2757d5e
KY
9046static struct hda_bind_ctls alc883_bind_cap_vol = {
9047 .ops = &snd_hda_bind_vol,
9048 .values = {
9049 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9050 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9051 0
9052 },
9053};
9054
9055static struct hda_bind_ctls alc883_bind_cap_switch = {
9056 .ops = &snd_hda_bind_sw,
9057 .values = {
9058 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9059 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9060 0
9061 },
9062};
9063
9064static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9065 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9066 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9068 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9069 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9070 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
9071 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9072 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9073 { } /* end */
9074};
df694daa 9075
4953550a
TI
9076static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9077 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9078 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9079 {
9080 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9081 /* .name = "Capture Source", */
9082 .name = "Input Source",
9083 .count = 1,
9084 .info = alc_mux_enum_info,
9085 .get = alc_mux_enum_get,
9086 .put = alc_mux_enum_put,
9087 },
9088 { } /* end */
9089};
9c7f852e 9090
4953550a
TI
9091static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9092 {
9093 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9094 .name = "Channel Mode",
9095 .info = alc_ch_mode_info,
9096 .get = alc_ch_mode_get,
9097 .put = alc_ch_mode_put,
9098 },
9099 { } /* end */
9c7f852e
TI
9100};
9101
a8848bd6 9102/* toggle speaker-output according to the hp-jack state */
4f5d1706 9103static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9104{
a9fd4f3f 9105 struct alc_spec *spec = codec->spec;
a8848bd6 9106
a9fd4f3f
TI
9107 spec->autocfg.hp_pins[0] = 0x15;
9108 spec->autocfg.speaker_pins[0] = 0x14;
9109 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9110}
9111
9112/* auto-toggle front mic */
9113/*
9114static void alc883_mitac_mic_automute(struct hda_codec *codec)
9115{
864f92be 9116 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 9117
a8848bd6
AS
9118 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
9119}
9120*/
9121
a8848bd6
AS
9122static struct hda_verb alc883_mitac_verbs[] = {
9123 /* HP */
9124 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9125 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9126 /* Subwoofer */
9127 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9128 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9129
9130 /* enable unsolicited event */
9131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9132 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9133
9134 { } /* end */
9135};
9136
a65cc60f 9137static struct hda_verb alc883_clevo_m540r_verbs[] = {
9138 /* HP */
9139 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9141 /* Int speaker */
9142 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9143
9144 /* enable unsolicited event */
9145 /*
9146 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9147 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9148 */
9149
9150 { } /* end */
9151};
9152
0c4cc443 9153static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9154 /* HP */
9155 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9157 /* Int speaker */
9158 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9159 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9160
9161 /* enable unsolicited event */
9162 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9163 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9164
9165 { } /* end */
9166};
9167
fb97dc67
J
9168static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9169 /* HP */
9170 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9172 /* Subwoofer */
9173 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9175
9176 /* enable unsolicited event */
9177 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9178
9179 { } /* end */
9180};
9181
c259249f 9182static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9185
9186 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9187 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9188
64a8be74
DH
9189/* Connect Line-Out side jack (SPDIF) to Side */
9190 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9191 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9192 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9193/* Connect Mic jack to CLFE */
9194 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9195 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9196 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9197/* Connect Line-in jack to Surround */
9198 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9199 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9200 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9201/* Connect HP out jack to Front */
9202 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9203 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9204 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9205
9206 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9207
9208 { } /* end */
9209};
9210
bc9f98a9
KY
9211static struct hda_verb alc883_lenovo_101e_verbs[] = {
9212 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9213 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9214 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9215 { } /* end */
9216};
9217
272a527c
KY
9218static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9219 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9221 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9222 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9223 { } /* end */
9224};
9225
9226static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9229 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9230 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9231 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9232 { } /* end */
9233};
9234
189609ae
KY
9235static struct hda_verb alc883_haier_w66_verbs[] = {
9236 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9237 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9238
9239 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9240
9241 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9242 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9243 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9244 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9245 { } /* end */
9246};
9247
e2757d5e
KY
9248static struct hda_verb alc888_lenovo_sky_verbs[] = {
9249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9251 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9254 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9255 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9256 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9257 { } /* end */
9258};
9259
8718b700
HRK
9260static struct hda_verb alc888_6st_dell_verbs[] = {
9261 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9262 { }
9263};
9264
3e1647c5
GG
9265static struct hda_verb alc883_vaiott_verbs[] = {
9266 /* HP */
9267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9268 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9269
9270 /* enable unsolicited event */
9271 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9272
9273 { } /* end */
9274};
9275
4f5d1706 9276static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9277{
a9fd4f3f 9278 struct alc_spec *spec = codec->spec;
8718b700 9279
a9fd4f3f
TI
9280 spec->autocfg.hp_pins[0] = 0x1b;
9281 spec->autocfg.speaker_pins[0] = 0x14;
9282 spec->autocfg.speaker_pins[1] = 0x16;
9283 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9284}
9285
4723c022 9286static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9287 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9288 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9289 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9290 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9291 { } /* end */
5795b9e6
CM
9292};
9293
3ea0d7cf
HRK
9294/*
9295 * 2ch mode
9296 */
4723c022 9297static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9298 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9299 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9300 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9301 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9302 { } /* end */
8341de60
CM
9303};
9304
3ea0d7cf
HRK
9305/*
9306 * 4ch mode
9307 */
9308static struct hda_verb alc888_3st_hp_4ch_init[] = {
9309 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9310 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9311 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9312 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9313 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9314 { } /* end */
9315};
9316
9317/*
9318 * 6ch mode
9319 */
4723c022 9320static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9321 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9322 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9323 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9324 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9325 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9326 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9327 { } /* end */
8341de60
CM
9328};
9329
3ea0d7cf 9330static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9331 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9332 { 4, alc888_3st_hp_4ch_init },
4723c022 9333 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9334};
9335
272a527c
KY
9336/* toggle front-jack and RCA according to the hp-jack state */
9337static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9338{
864f92be 9339 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9340
47fd830a
TI
9341 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9342 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9343 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9344 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9345}
9346
9347/* toggle RCA according to the front-jack state */
9348static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9349{
864f92be 9350 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9351
47fd830a
TI
9352 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9353 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9354}
47fd830a 9355
272a527c
KY
9356static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9357 unsigned int res)
9358{
9359 if ((res >> 26) == ALC880_HP_EVENT)
9360 alc888_lenovo_ms7195_front_automute(codec);
9361 if ((res >> 26) == ALC880_FRONT_EVENT)
9362 alc888_lenovo_ms7195_rca_automute(codec);
9363}
9364
9365static struct hda_verb alc883_medion_md2_verbs[] = {
9366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9368
9369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9370
9371 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9372 { } /* end */
9373};
9374
9375/* toggle speaker-output according to the hp-jack state */
4f5d1706 9376static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 9377{
a9fd4f3f 9378 struct alc_spec *spec = codec->spec;
272a527c 9379
a9fd4f3f
TI
9380 spec->autocfg.hp_pins[0] = 0x14;
9381 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9382}
9383
ccc656ce 9384/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9385#define alc883_targa_init_hook alc882_targa_init_hook
9386#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9387
0c4cc443
HRK
9388static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9389{
9390 unsigned int present;
9391
d56757ab 9392 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
9393 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9394 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9395}
9396
4f5d1706 9397static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9398{
a9fd4f3f
TI
9399 struct alc_spec *spec = codec->spec;
9400
9401 spec->autocfg.hp_pins[0] = 0x15;
9402 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9403}
9404
9405static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9406{
a9fd4f3f 9407 alc_automute_amp(codec);
0c4cc443
HRK
9408 alc883_clevo_m720_mic_automute(codec);
9409}
9410
9411static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9412 unsigned int res)
9413{
0c4cc443 9414 switch (res >> 26) {
0c4cc443
HRK
9415 case ALC880_MIC_EVENT:
9416 alc883_clevo_m720_mic_automute(codec);
9417 break;
a9fd4f3f
TI
9418 default:
9419 alc_automute_amp_unsol_event(codec, res);
9420 break;
0c4cc443 9421 }
368c7a95
J
9422}
9423
fb97dc67 9424/* toggle speaker-output according to the hp-jack state */
4f5d1706 9425static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9426{
a9fd4f3f 9427 struct alc_spec *spec = codec->spec;
fb97dc67 9428
a9fd4f3f
TI
9429 spec->autocfg.hp_pins[0] = 0x14;
9430 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9431}
9432
4f5d1706 9433static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9434{
a9fd4f3f 9435 struct alc_spec *spec = codec->spec;
189609ae 9436
a9fd4f3f
TI
9437 spec->autocfg.hp_pins[0] = 0x1b;
9438 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9439}
9440
bc9f98a9
KY
9441static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9442{
864f92be 9443 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9444
47fd830a
TI
9445 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9446 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9447}
9448
9449static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9450{
864f92be 9451 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9452
47fd830a
TI
9453 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9454 HDA_AMP_MUTE, bits);
9455 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9456 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9457}
9458
9459static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9460 unsigned int res)
9461{
9462 if ((res >> 26) == ALC880_HP_EVENT)
9463 alc883_lenovo_101e_all_automute(codec);
9464 if ((res >> 26) == ALC880_FRONT_EVENT)
9465 alc883_lenovo_101e_ispeaker_automute(codec);
9466}
9467
676a9b53 9468/* toggle speaker-output according to the hp-jack state */
4f5d1706 9469static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9470{
a9fd4f3f 9471 struct alc_spec *spec = codec->spec;
676a9b53 9472
a9fd4f3f
TI
9473 spec->autocfg.hp_pins[0] = 0x14;
9474 spec->autocfg.speaker_pins[0] = 0x15;
9475 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9476}
9477
d1a991a6
KY
9478static struct hda_verb alc883_acer_eapd_verbs[] = {
9479 /* HP Pin: output 0 (0x0c) */
9480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9482 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9483 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9484 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9485 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9486 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9487 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9488 /* eanable EAPD on medion laptop */
9489 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9490 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9491 /* enable unsolicited event */
9492 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9493 { }
9494};
9495
fc86f954
DK
9496static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9497 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9498 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9499 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9500 { } /* end */
9501};
9502
4f5d1706 9503static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9504{
a9fd4f3f 9505 struct alc_spec *spec = codec->spec;
5795b9e6 9506
a9fd4f3f
TI
9507 spec->autocfg.hp_pins[0] = 0x1b;
9508 spec->autocfg.speaker_pins[0] = 0x14;
9509 spec->autocfg.speaker_pins[1] = 0x15;
9510 spec->autocfg.speaker_pins[2] = 0x16;
9511 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9512}
9513
4f5d1706 9514static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9515{
a9fd4f3f 9516 struct alc_spec *spec = codec->spec;
e2757d5e 9517
a9fd4f3f
TI
9518 spec->autocfg.hp_pins[0] = 0x1b;
9519 spec->autocfg.speaker_pins[0] = 0x14;
9520 spec->autocfg.speaker_pins[1] = 0x15;
9521 spec->autocfg.speaker_pins[2] = 0x16;
9522 spec->autocfg.speaker_pins[3] = 0x17;
9523 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9524}
9525
4f5d1706 9526static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9527{
9528 struct alc_spec *spec = codec->spec;
9529
9530 spec->autocfg.hp_pins[0] = 0x15;
9531 spec->autocfg.speaker_pins[0] = 0x14;
9532 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9533}
9534
e2757d5e
KY
9535static struct hda_verb alc888_asus_m90v_verbs[] = {
9536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9537 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9538 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9539 /* enable unsolicited event */
9540 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9541 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9542 { } /* end */
9543};
9544
4f5d1706 9545static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9546{
a9fd4f3f 9547 struct alc_spec *spec = codec->spec;
e2757d5e 9548
a9fd4f3f
TI
9549 spec->autocfg.hp_pins[0] = 0x1b;
9550 spec->autocfg.speaker_pins[0] = 0x14;
9551 spec->autocfg.speaker_pins[1] = 0x15;
9552 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9553 spec->ext_mic.pin = 0x18;
9554 spec->int_mic.pin = 0x19;
9555 spec->ext_mic.mux_idx = 0;
9556 spec->int_mic.mux_idx = 1;
9557 spec->auto_mic = 1;
e2757d5e
KY
9558}
9559
9560static struct hda_verb alc888_asus_eee1601_verbs[] = {
9561 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9562 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9566 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9567 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9568 /* enable unsolicited event */
9569 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9570 { } /* end */
9571};
9572
e2757d5e
KY
9573static void alc883_eee1601_inithook(struct hda_codec *codec)
9574{
a9fd4f3f
TI
9575 struct alc_spec *spec = codec->spec;
9576
9577 spec->autocfg.hp_pins[0] = 0x14;
9578 spec->autocfg.speaker_pins[0] = 0x1b;
9579 alc_automute_pin(codec);
e2757d5e
KY
9580}
9581
eb4c41d3
TS
9582static struct hda_verb alc889A_mb31_verbs[] = {
9583 /* Init rear pin (used as headphone output) */
9584 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9585 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9586 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9587 /* Init line pin (used as output in 4ch and 6ch mode) */
9588 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9589 /* Init line 2 pin (used as headphone out by default) */
9590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9591 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9592 { } /* end */
9593};
9594
9595/* Mute speakers according to the headphone jack state */
9596static void alc889A_mb31_automute(struct hda_codec *codec)
9597{
9598 unsigned int present;
9599
9600 /* Mute only in 2ch or 4ch mode */
9601 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9602 == 0x00) {
864f92be 9603 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9604 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9605 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9606 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9607 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9608 }
9609}
9610
9611static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9612{
9613 if ((res >> 26) == ALC880_HP_EVENT)
9614 alc889A_mb31_automute(codec);
9615}
9616
4953550a 9617
cb53c626 9618#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9619#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9620#endif
9621
def319f9 9622/* pcm configuration: identical with ALC880 */
4953550a
TI
9623#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9624#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9625#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9626#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9627
9628static hda_nid_t alc883_slave_dig_outs[] = {
9629 ALC1200_DIGOUT_NID, 0,
9630};
9631
9632static hda_nid_t alc1200_slave_dig_outs[] = {
9633 ALC883_DIGOUT_NID, 0,
9634};
9c7f852e
TI
9635
9636/*
9637 * configuration and preset
9638 */
4953550a
TI
9639static const char *alc882_models[ALC882_MODEL_LAST] = {
9640 [ALC882_3ST_DIG] = "3stack-dig",
9641 [ALC882_6ST_DIG] = "6stack-dig",
9642 [ALC882_ARIMA] = "arima",
9643 [ALC882_W2JC] = "w2jc",
9644 [ALC882_TARGA] = "targa",
9645 [ALC882_ASUS_A7J] = "asus-a7j",
9646 [ALC882_ASUS_A7M] = "asus-a7m",
9647 [ALC885_MACPRO] = "macpro",
9648 [ALC885_MB5] = "mb5",
e458b1fa 9649 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9650 [ALC885_MBA21] = "mba21",
4953550a
TI
9651 [ALC885_MBP3] = "mbp3",
9652 [ALC885_IMAC24] = "imac24",
4b7e1803 9653 [ALC885_IMAC91] = "imac91",
4953550a 9654 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9655 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9656 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9657 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9658 [ALC883_TARGA_DIG] = "targa-dig",
9659 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9660 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9661 [ALC883_ACER] = "acer",
2880a867 9662 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9663 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9664 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9665 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9666 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9667 [ALC883_MEDION] = "medion",
272a527c 9668 [ALC883_MEDION_MD2] = "medion-md2",
7ad7b218 9669 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9670 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9671 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9672 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9673 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9674 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9675 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9676 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9677 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9678 [ALC883_MITAC] = "mitac",
a65cc60f 9679 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9680 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9681 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9682 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9683 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9684 [ALC889A_INTEL] = "intel-alc889a",
9685 [ALC889_INTEL] = "intel-x58",
3ab90935 9686 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9687 [ALC889A_MB31] = "mb31",
3e1647c5 9688 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9689 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9690};
9691
4953550a
TI
9692static struct snd_pci_quirk alc882_cfg_tbl[] = {
9693 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9694
ac3e3741 9695 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9696 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9697 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9698 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9699 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9700 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9701 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9702 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9703 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9704 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9705 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9706 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9707 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9708 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9709 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9710 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9711 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9712 ALC888_ACER_ASPIRE_6530G),
cc374c47 9713 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9714 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9715 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9716 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9717 /* default Acer -- disabled as it causes more problems.
9718 * model=auto should work fine now
9719 */
9720 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9721
5795b9e6 9722 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9723
febe3375 9724 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9725 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9726 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9727 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9728 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9729 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9730
9731 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9732 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9733 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9734 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9735 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9736 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9737 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9738 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9739 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9740 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9741 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9742
9743 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9744 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9745 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9746 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9747 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9748 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9749 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9750 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9751 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9752
6f3bf657 9753 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9754 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9755 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9756 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9757 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9758 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9759 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9760 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9761 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9762 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9763 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9764 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9765 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9766 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9767 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9768 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9769 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9770 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9771 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9772 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9773 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9774 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9775 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9776 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9777 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9778 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9779 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9780 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9781 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9782 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9783 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9784
ac3e3741 9785 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9786 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9787 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9788 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9789 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9790 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9791 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9792 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9793 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9794 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9795 ALC883_FUJITSU_PI2515),
bfb53037 9796 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9797 ALC888_FUJITSU_XA3530),
272a527c 9798 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9799 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9800 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9801 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9802 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9803 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9804 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9805 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9806 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9807
17bba1b7
J
9808 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9809 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9810 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9811 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9812 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9813 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9814 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9815
4953550a 9816 {}
f3cd3f5d
WF
9817};
9818
4953550a
TI
9819/* codec SSID table for Intel Mac */
9820static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9821 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9822 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9823 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9824 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9825 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9826 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9827 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9828 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9829 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9830 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9831 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9832 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9833 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9834 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9835 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9836 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9837 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9838 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9839 * so apparently no perfect solution yet
4953550a
TI
9840 */
9841 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9842 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9843 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9844 {} /* terminator */
b25c9da1
WF
9845};
9846
4953550a
TI
9847static struct alc_config_preset alc882_presets[] = {
9848 [ALC882_3ST_DIG] = {
9849 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9850 .init_verbs = { alc882_base_init_verbs,
9851 alc882_adc1_init_verbs },
4953550a
TI
9852 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9853 .dac_nids = alc882_dac_nids,
9854 .dig_out_nid = ALC882_DIGOUT_NID,
9855 .dig_in_nid = ALC882_DIGIN_NID,
9856 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9857 .channel_mode = alc882_ch_modes,
9858 .need_dac_fix = 1,
9859 .input_mux = &alc882_capture_source,
9860 },
9861 [ALC882_6ST_DIG] = {
9862 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9863 .init_verbs = { alc882_base_init_verbs,
9864 alc882_adc1_init_verbs },
4953550a
TI
9865 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9866 .dac_nids = alc882_dac_nids,
9867 .dig_out_nid = ALC882_DIGOUT_NID,
9868 .dig_in_nid = ALC882_DIGIN_NID,
9869 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9870 .channel_mode = alc882_sixstack_modes,
9871 .input_mux = &alc882_capture_source,
9872 },
9873 [ALC882_ARIMA] = {
9874 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9875 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9876 alc882_eapd_verbs },
4953550a
TI
9877 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9878 .dac_nids = alc882_dac_nids,
9879 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9880 .channel_mode = alc882_sixstack_modes,
9881 .input_mux = &alc882_capture_source,
9882 },
9883 [ALC882_W2JC] = {
9884 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9885 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9886 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9887 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9888 .dac_nids = alc882_dac_nids,
9889 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9890 .channel_mode = alc880_threestack_modes,
9891 .need_dac_fix = 1,
9892 .input_mux = &alc882_capture_source,
9893 .dig_out_nid = ALC882_DIGOUT_NID,
9894 },
76e6f5a9
RH
9895 [ALC885_MBA21] = {
9896 .mixers = { alc885_mba21_mixer },
9897 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9898 .num_dacs = 2,
9899 .dac_nids = alc882_dac_nids,
9900 .channel_mode = alc885_mba21_ch_modes,
9901 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9902 .input_mux = &alc882_capture_source,
9903 .unsol_event = alc_automute_amp_unsol_event,
9904 .setup = alc885_mba21_setup,
9905 .init_hook = alc_automute_amp,
9906 },
4953550a
TI
9907 [ALC885_MBP3] = {
9908 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9909 .init_verbs = { alc885_mbp3_init_verbs,
9910 alc880_gpio1_init_verbs },
be0ae923 9911 .num_dacs = 2,
4953550a 9912 .dac_nids = alc882_dac_nids,
be0ae923
TI
9913 .hp_nid = 0x04,
9914 .channel_mode = alc885_mbp_4ch_modes,
9915 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9916 .input_mux = &alc882_capture_source,
9917 .dig_out_nid = ALC882_DIGOUT_NID,
9918 .dig_in_nid = ALC882_DIGIN_NID,
9919 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9920 .setup = alc885_mbp3_setup,
9921 .init_hook = alc_automute_amp,
4953550a
TI
9922 },
9923 [ALC885_MB5] = {
9924 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9925 .init_verbs = { alc885_mb5_init_verbs,
9926 alc880_gpio1_init_verbs },
9927 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9928 .dac_nids = alc882_dac_nids,
9929 .channel_mode = alc885_mb5_6ch_modes,
9930 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9931 .input_mux = &mb5_capture_source,
9932 .dig_out_nid = ALC882_DIGOUT_NID,
9933 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9934 .unsol_event = alc_automute_amp_unsol_event,
9935 .setup = alc885_mb5_setup,
9936 .init_hook = alc_automute_amp,
4953550a 9937 },
e458b1fa
LY
9938 [ALC885_MACMINI3] = {
9939 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9940 .init_verbs = { alc885_macmini3_init_verbs,
9941 alc880_gpio1_init_verbs },
9942 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9943 .dac_nids = alc882_dac_nids,
9944 .channel_mode = alc885_macmini3_6ch_modes,
9945 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9946 .input_mux = &macmini3_capture_source,
9947 .dig_out_nid = ALC882_DIGOUT_NID,
9948 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9949 .unsol_event = alc_automute_amp_unsol_event,
9950 .setup = alc885_macmini3_setup,
9951 .init_hook = alc_automute_amp,
e458b1fa 9952 },
4953550a
TI
9953 [ALC885_MACPRO] = {
9954 .mixers = { alc882_macpro_mixer },
9955 .init_verbs = { alc882_macpro_init_verbs },
9956 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9957 .dac_nids = alc882_dac_nids,
9958 .dig_out_nid = ALC882_DIGOUT_NID,
9959 .dig_in_nid = ALC882_DIGIN_NID,
9960 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9961 .channel_mode = alc882_ch_modes,
9962 .input_mux = &alc882_capture_source,
9963 .init_hook = alc885_macpro_init_hook,
9964 },
9965 [ALC885_IMAC24] = {
9966 .mixers = { alc885_imac24_mixer },
9967 .init_verbs = { alc885_imac24_init_verbs },
9968 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9969 .dac_nids = alc882_dac_nids,
9970 .dig_out_nid = ALC882_DIGOUT_NID,
9971 .dig_in_nid = ALC882_DIGIN_NID,
9972 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9973 .channel_mode = alc882_ch_modes,
9974 .input_mux = &alc882_capture_source,
9975 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9976 .setup = alc885_imac24_setup,
4953550a
TI
9977 .init_hook = alc885_imac24_init_hook,
9978 },
4b7e1803 9979 [ALC885_IMAC91] = {
b7cccc52 9980 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
9981 .init_verbs = { alc885_imac91_init_verbs,
9982 alc880_gpio1_init_verbs },
9983 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9984 .dac_nids = alc882_dac_nids,
b7cccc52
JM
9985 .channel_mode = alc885_mba21_ch_modes,
9986 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9987 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
9988 .dig_out_nid = ALC882_DIGOUT_NID,
9989 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9990 .unsol_event = alc_automute_amp_unsol_event,
9991 .setup = alc885_imac91_setup,
9992 .init_hook = alc_automute_amp,
4b7e1803 9993 },
4953550a
TI
9994 [ALC882_TARGA] = {
9995 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9996 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9997 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9998 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9999 .dac_nids = alc882_dac_nids,
10000 .dig_out_nid = ALC882_DIGOUT_NID,
10001 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10002 .adc_nids = alc882_adc_nids,
10003 .capsrc_nids = alc882_capsrc_nids,
10004 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10005 .channel_mode = alc882_3ST_6ch_modes,
10006 .need_dac_fix = 1,
10007 .input_mux = &alc882_capture_source,
10008 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10009 .setup = alc882_targa_setup,
10010 .init_hook = alc882_targa_automute,
4953550a
TI
10011 },
10012 [ALC882_ASUS_A7J] = {
10013 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10014 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10015 alc882_asus_a7j_verbs},
4953550a
TI
10016 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10017 .dac_nids = alc882_dac_nids,
10018 .dig_out_nid = ALC882_DIGOUT_NID,
10019 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10020 .adc_nids = alc882_adc_nids,
10021 .capsrc_nids = alc882_capsrc_nids,
10022 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10023 .channel_mode = alc882_3ST_6ch_modes,
10024 .need_dac_fix = 1,
10025 .input_mux = &alc882_capture_source,
10026 },
10027 [ALC882_ASUS_A7M] = {
10028 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10029 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10030 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10031 alc882_asus_a7m_verbs },
10032 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10033 .dac_nids = alc882_dac_nids,
10034 .dig_out_nid = ALC882_DIGOUT_NID,
10035 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10036 .channel_mode = alc880_threestack_modes,
10037 .need_dac_fix = 1,
10038 .input_mux = &alc882_capture_source,
10039 },
9c7f852e
TI
10040 [ALC883_3ST_2ch_DIG] = {
10041 .mixers = { alc883_3ST_2ch_mixer },
10042 .init_verbs = { alc883_init_verbs },
10043 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10044 .dac_nids = alc883_dac_nids,
10045 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10046 .dig_in_nid = ALC883_DIGIN_NID,
10047 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10048 .channel_mode = alc883_3ST_2ch_modes,
10049 .input_mux = &alc883_capture_source,
10050 },
10051 [ALC883_3ST_6ch_DIG] = {
10052 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10053 .init_verbs = { alc883_init_verbs },
10054 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10055 .dac_nids = alc883_dac_nids,
10056 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10057 .dig_in_nid = ALC883_DIGIN_NID,
10058 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10059 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10060 .need_dac_fix = 1,
9c7f852e 10061 .input_mux = &alc883_capture_source,
f12ab1e0 10062 },
9c7f852e
TI
10063 [ALC883_3ST_6ch] = {
10064 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10065 .init_verbs = { alc883_init_verbs },
10066 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10067 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10068 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10069 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10070 .need_dac_fix = 1,
9c7f852e 10071 .input_mux = &alc883_capture_source,
f12ab1e0 10072 },
17bba1b7
J
10073 [ALC883_3ST_6ch_INTEL] = {
10074 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10075 .init_verbs = { alc883_init_verbs },
10076 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10077 .dac_nids = alc883_dac_nids,
10078 .dig_out_nid = ALC883_DIGOUT_NID,
10079 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10080 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10081 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10082 .channel_mode = alc883_3ST_6ch_intel_modes,
10083 .need_dac_fix = 1,
10084 .input_mux = &alc883_3stack_6ch_intel,
10085 },
87a8c370
JK
10086 [ALC889A_INTEL] = {
10087 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10088 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10089 alc_hp15_unsol_verbs },
87a8c370
JK
10090 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10091 .dac_nids = alc883_dac_nids,
10092 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10093 .adc_nids = alc889_adc_nids,
10094 .dig_out_nid = ALC883_DIGOUT_NID,
10095 .dig_in_nid = ALC883_DIGIN_NID,
10096 .slave_dig_outs = alc883_slave_dig_outs,
10097 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10098 .channel_mode = alc889_8ch_intel_modes,
10099 .capsrc_nids = alc889_capsrc_nids,
10100 .input_mux = &alc889_capture_source,
4f5d1706
TI
10101 .setup = alc889_automute_setup,
10102 .init_hook = alc_automute_amp,
6732bd0d 10103 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10104 .need_dac_fix = 1,
10105 },
10106 [ALC889_INTEL] = {
10107 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10108 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10109 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10110 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10111 .dac_nids = alc883_dac_nids,
10112 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10113 .adc_nids = alc889_adc_nids,
10114 .dig_out_nid = ALC883_DIGOUT_NID,
10115 .dig_in_nid = ALC883_DIGIN_NID,
10116 .slave_dig_outs = alc883_slave_dig_outs,
10117 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10118 .channel_mode = alc889_8ch_intel_modes,
10119 .capsrc_nids = alc889_capsrc_nids,
10120 .input_mux = &alc889_capture_source,
4f5d1706 10121 .setup = alc889_automute_setup,
6732bd0d
WF
10122 .init_hook = alc889_intel_init_hook,
10123 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10124 .need_dac_fix = 1,
10125 },
9c7f852e
TI
10126 [ALC883_6ST_DIG] = {
10127 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10128 .init_verbs = { alc883_init_verbs },
10129 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10130 .dac_nids = alc883_dac_nids,
10131 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10132 .dig_in_nid = ALC883_DIGIN_NID,
10133 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10134 .channel_mode = alc883_sixstack_modes,
10135 .input_mux = &alc883_capture_source,
10136 },
ccc656ce 10137 [ALC883_TARGA_DIG] = {
c259249f 10138 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10139 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10140 alc883_targa_verbs},
ccc656ce
KY
10141 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10142 .dac_nids = alc883_dac_nids,
10143 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10144 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10145 .channel_mode = alc883_3ST_6ch_modes,
10146 .need_dac_fix = 1,
10147 .input_mux = &alc883_capture_source,
c259249f 10148 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10149 .setup = alc882_targa_setup,
10150 .init_hook = alc882_targa_automute,
ccc656ce
KY
10151 },
10152 [ALC883_TARGA_2ch_DIG] = {
c259249f 10153 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10154 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10155 alc883_targa_verbs},
ccc656ce
KY
10156 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10157 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10158 .adc_nids = alc883_adc_nids_alt,
10159 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10160 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10161 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10162 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10163 .channel_mode = alc883_3ST_2ch_modes,
10164 .input_mux = &alc883_capture_source,
c259249f 10165 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10166 .setup = alc882_targa_setup,
10167 .init_hook = alc882_targa_automute,
ccc656ce 10168 },
64a8be74 10169 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10170 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10171 alc883_chmode_mixer },
64a8be74 10172 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10173 alc883_targa_verbs },
64a8be74
DH
10174 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10175 .dac_nids = alc883_dac_nids,
10176 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10177 .adc_nids = alc883_adc_nids_rev,
10178 .capsrc_nids = alc883_capsrc_nids_rev,
10179 .dig_out_nid = ALC883_DIGOUT_NID,
10180 .dig_in_nid = ALC883_DIGIN_NID,
10181 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10182 .channel_mode = alc883_4ST_8ch_modes,
10183 .need_dac_fix = 1,
10184 .input_mux = &alc883_capture_source,
c259249f 10185 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10186 .setup = alc882_targa_setup,
10187 .init_hook = alc882_targa_automute,
64a8be74 10188 },
bab282b9 10189 [ALC883_ACER] = {
676a9b53 10190 .mixers = { alc883_base_mixer },
bab282b9
VA
10191 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10192 * and the headphone jack. Turn this on and rely on the
10193 * standard mute methods whenever the user wants to turn
10194 * these outputs off.
10195 */
10196 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10197 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10198 .dac_nids = alc883_dac_nids,
bab282b9
VA
10199 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10200 .channel_mode = alc883_3ST_2ch_modes,
10201 .input_mux = &alc883_capture_source,
10202 },
2880a867 10203 [ALC883_ACER_ASPIRE] = {
676a9b53 10204 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10205 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10206 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10207 .dac_nids = alc883_dac_nids,
10208 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10209 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10210 .channel_mode = alc883_3ST_2ch_modes,
10211 .input_mux = &alc883_capture_source,
a9fd4f3f 10212 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10213 .setup = alc883_acer_aspire_setup,
10214 .init_hook = alc_automute_amp,
d1a991a6 10215 },
5b2d1eca 10216 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10217 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10218 alc883_chmode_mixer },
10219 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10220 alc888_acer_aspire_4930g_verbs },
10221 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10222 .dac_nids = alc883_dac_nids,
10223 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10224 .adc_nids = alc883_adc_nids_rev,
10225 .capsrc_nids = alc883_capsrc_nids_rev,
10226 .dig_out_nid = ALC883_DIGOUT_NID,
10227 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10228 .channel_mode = alc883_3ST_6ch_modes,
10229 .need_dac_fix = 1,
973b8cb0 10230 .const_channel_count = 6,
5b2d1eca 10231 .num_mux_defs =
ef8ef5fb
VP
10232 ARRAY_SIZE(alc888_2_capture_sources),
10233 .input_mux = alc888_2_capture_sources,
d2fd4b09 10234 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10235 .setup = alc888_acer_aspire_4930g_setup,
10236 .init_hook = alc_automute_amp,
d2fd4b09
TV
10237 },
10238 [ALC888_ACER_ASPIRE_6530G] = {
10239 .mixers = { alc888_acer_aspire_6530_mixer },
10240 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10241 alc888_acer_aspire_6530g_verbs },
10242 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10243 .dac_nids = alc883_dac_nids,
10244 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10245 .adc_nids = alc883_adc_nids_rev,
10246 .capsrc_nids = alc883_capsrc_nids_rev,
10247 .dig_out_nid = ALC883_DIGOUT_NID,
10248 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10249 .channel_mode = alc883_3ST_2ch_modes,
10250 .num_mux_defs =
10251 ARRAY_SIZE(alc888_2_capture_sources),
10252 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10253 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10254 .setup = alc888_acer_aspire_6530g_setup,
10255 .init_hook = alc_automute_amp,
5b2d1eca 10256 },
3b315d70 10257 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10258 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10259 alc883_chmode_mixer },
10260 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10261 alc889_acer_aspire_8930g_verbs,
10262 alc889_eapd_verbs},
3b315d70
HM
10263 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10264 .dac_nids = alc883_dac_nids,
018df418
HM
10265 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10266 .adc_nids = alc889_adc_nids,
10267 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10268 .dig_out_nid = ALC883_DIGOUT_NID,
10269 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10270 .channel_mode = alc883_3ST_6ch_modes,
10271 .need_dac_fix = 1,
10272 .const_channel_count = 6,
10273 .num_mux_defs =
018df418
HM
10274 ARRAY_SIZE(alc889_capture_sources),
10275 .input_mux = alc889_capture_sources,
3b315d70 10276 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10277 .setup = alc889_acer_aspire_8930g_setup,
10278 .init_hook = alc_automute_amp,
f5de24b0 10279#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10280 .power_hook = alc_power_eapd,
f5de24b0 10281#endif
3b315d70 10282 },
fc86f954
DK
10283 [ALC888_ACER_ASPIRE_7730G] = {
10284 .mixers = { alc883_3ST_6ch_mixer,
10285 alc883_chmode_mixer },
10286 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10287 alc888_acer_aspire_7730G_verbs },
10288 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10289 .dac_nids = alc883_dac_nids,
10290 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10291 .adc_nids = alc883_adc_nids_rev,
10292 .capsrc_nids = alc883_capsrc_nids_rev,
10293 .dig_out_nid = ALC883_DIGOUT_NID,
10294 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10295 .channel_mode = alc883_3ST_6ch_modes,
10296 .need_dac_fix = 1,
10297 .const_channel_count = 6,
10298 .input_mux = &alc883_capture_source,
10299 .unsol_event = alc_automute_amp_unsol_event,
10300 .setup = alc888_acer_aspire_6530g_setup,
10301 .init_hook = alc_automute_amp,
10302 },
c07584c8
TD
10303 [ALC883_MEDION] = {
10304 .mixers = { alc883_fivestack_mixer,
10305 alc883_chmode_mixer },
10306 .init_verbs = { alc883_init_verbs,
b373bdeb 10307 alc883_medion_eapd_verbs },
c07584c8
TD
10308 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10309 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10310 .adc_nids = alc883_adc_nids_alt,
10311 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10312 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10313 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10314 .channel_mode = alc883_sixstack_modes,
10315 .input_mux = &alc883_capture_source,
b373bdeb 10316 },
272a527c
KY
10317 [ALC883_MEDION_MD2] = {
10318 .mixers = { alc883_medion_md2_mixer},
10319 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10320 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10321 .dac_nids = alc883_dac_nids,
10322 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10323 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10324 .channel_mode = alc883_3ST_2ch_modes,
10325 .input_mux = &alc883_capture_source,
a9fd4f3f 10326 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10327 .setup = alc883_medion_md2_setup,
10328 .init_hook = alc_automute_amp,
ea1fb29a 10329 },
7ad7b218
MC
10330 [ALC883_MEDION_WIM2160] = {
10331 .mixers = { alc883_medion_wim2160_mixer },
10332 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10333 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10334 .dac_nids = alc883_dac_nids,
10335 .dig_out_nid = ALC883_DIGOUT_NID,
10336 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10337 .adc_nids = alc883_adc_nids,
10338 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10339 .channel_mode = alc883_3ST_2ch_modes,
10340 .input_mux = &alc883_capture_source,
10341 .unsol_event = alc_automute_amp_unsol_event,
10342 .setup = alc883_medion_wim2160_setup,
10343 .init_hook = alc_automute_amp,
10344 },
b373bdeb 10345 [ALC883_LAPTOP_EAPD] = {
676a9b53 10346 .mixers = { alc883_base_mixer },
b373bdeb
AN
10347 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10348 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10349 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10350 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10351 .channel_mode = alc883_3ST_2ch_modes,
10352 .input_mux = &alc883_capture_source,
10353 },
a65cc60f 10354 [ALC883_CLEVO_M540R] = {
10355 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10356 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10357 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10358 .dac_nids = alc883_dac_nids,
10359 .dig_out_nid = ALC883_DIGOUT_NID,
10360 .dig_in_nid = ALC883_DIGIN_NID,
10361 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10362 .channel_mode = alc883_3ST_6ch_clevo_modes,
10363 .need_dac_fix = 1,
10364 .input_mux = &alc883_capture_source,
10365 /* This machine has the hardware HP auto-muting, thus
10366 * we need no software mute via unsol event
10367 */
10368 },
0c4cc443
HRK
10369 [ALC883_CLEVO_M720] = {
10370 .mixers = { alc883_clevo_m720_mixer },
10371 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10372 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10373 .dac_nids = alc883_dac_nids,
10374 .dig_out_nid = ALC883_DIGOUT_NID,
10375 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10376 .channel_mode = alc883_3ST_2ch_modes,
10377 .input_mux = &alc883_capture_source,
0c4cc443 10378 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10379 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10380 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10381 },
bc9f98a9
KY
10382 [ALC883_LENOVO_101E_2ch] = {
10383 .mixers = { alc883_lenovo_101e_2ch_mixer},
10384 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10385 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10386 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10387 .adc_nids = alc883_adc_nids_alt,
10388 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10389 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10390 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10391 .channel_mode = alc883_3ST_2ch_modes,
10392 .input_mux = &alc883_lenovo_101e_capture_source,
10393 .unsol_event = alc883_lenovo_101e_unsol_event,
10394 .init_hook = alc883_lenovo_101e_all_automute,
10395 },
272a527c
KY
10396 [ALC883_LENOVO_NB0763] = {
10397 .mixers = { alc883_lenovo_nb0763_mixer },
10398 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10399 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10400 .dac_nids = alc883_dac_nids,
272a527c
KY
10401 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10402 .channel_mode = alc883_3ST_2ch_modes,
10403 .need_dac_fix = 1,
10404 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10405 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10406 .setup = alc883_medion_md2_setup,
10407 .init_hook = alc_automute_amp,
272a527c
KY
10408 },
10409 [ALC888_LENOVO_MS7195_DIG] = {
10410 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10411 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10412 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10413 .dac_nids = alc883_dac_nids,
10414 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10415 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10416 .channel_mode = alc883_3ST_6ch_modes,
10417 .need_dac_fix = 1,
10418 .input_mux = &alc883_capture_source,
10419 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10420 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10421 },
10422 [ALC883_HAIER_W66] = {
c259249f 10423 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10424 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10425 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10426 .dac_nids = alc883_dac_nids,
10427 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10428 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10429 .channel_mode = alc883_3ST_2ch_modes,
10430 .input_mux = &alc883_capture_source,
a9fd4f3f 10431 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10432 .setup = alc883_haier_w66_setup,
10433 .init_hook = alc_automute_amp,
eea6419e 10434 },
4723c022 10435 [ALC888_3ST_HP] = {
eea6419e 10436 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10437 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10438 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10439 .dac_nids = alc883_dac_nids,
4723c022
CM
10440 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10441 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10442 .need_dac_fix = 1,
10443 .input_mux = &alc883_capture_source,
a9fd4f3f 10444 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10445 .setup = alc888_3st_hp_setup,
10446 .init_hook = alc_automute_amp,
8341de60 10447 },
5795b9e6 10448 [ALC888_6ST_DELL] = {
f24dbdc6 10449 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10450 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10451 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10452 .dac_nids = alc883_dac_nids,
10453 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10454 .dig_in_nid = ALC883_DIGIN_NID,
10455 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10456 .channel_mode = alc883_sixstack_modes,
10457 .input_mux = &alc883_capture_source,
a9fd4f3f 10458 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10459 .setup = alc888_6st_dell_setup,
10460 .init_hook = alc_automute_amp,
5795b9e6 10461 },
a8848bd6
AS
10462 [ALC883_MITAC] = {
10463 .mixers = { alc883_mitac_mixer },
10464 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10465 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10466 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10467 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10468 .channel_mode = alc883_3ST_2ch_modes,
10469 .input_mux = &alc883_capture_source,
a9fd4f3f 10470 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10471 .setup = alc883_mitac_setup,
10472 .init_hook = alc_automute_amp,
a8848bd6 10473 },
fb97dc67
J
10474 [ALC883_FUJITSU_PI2515] = {
10475 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10476 .init_verbs = { alc883_init_verbs,
10477 alc883_2ch_fujitsu_pi2515_verbs},
10478 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10479 .dac_nids = alc883_dac_nids,
10480 .dig_out_nid = ALC883_DIGOUT_NID,
10481 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10482 .channel_mode = alc883_3ST_2ch_modes,
10483 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10484 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10485 .setup = alc883_2ch_fujitsu_pi2515_setup,
10486 .init_hook = alc_automute_amp,
fb97dc67 10487 },
ef8ef5fb
VP
10488 [ALC888_FUJITSU_XA3530] = {
10489 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10490 .init_verbs = { alc883_init_verbs,
10491 alc888_fujitsu_xa3530_verbs },
10492 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10493 .dac_nids = alc883_dac_nids,
10494 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10495 .adc_nids = alc883_adc_nids_rev,
10496 .capsrc_nids = alc883_capsrc_nids_rev,
10497 .dig_out_nid = ALC883_DIGOUT_NID,
10498 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10499 .channel_mode = alc888_4ST_8ch_intel_modes,
10500 .num_mux_defs =
10501 ARRAY_SIZE(alc888_2_capture_sources),
10502 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10503 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10504 .setup = alc888_fujitsu_xa3530_setup,
10505 .init_hook = alc_automute_amp,
ef8ef5fb 10506 },
e2757d5e
KY
10507 [ALC888_LENOVO_SKY] = {
10508 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10509 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10510 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10511 .dac_nids = alc883_dac_nids,
10512 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10513 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10514 .channel_mode = alc883_sixstack_modes,
10515 .need_dac_fix = 1,
10516 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10517 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10518 .setup = alc888_lenovo_sky_setup,
10519 .init_hook = alc_automute_amp,
e2757d5e
KY
10520 },
10521 [ALC888_ASUS_M90V] = {
10522 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10523 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525 .dac_nids = alc883_dac_nids,
10526 .dig_out_nid = ALC883_DIGOUT_NID,
10527 .dig_in_nid = ALC883_DIGIN_NID,
10528 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10529 .channel_mode = alc883_3ST_6ch_modes,
10530 .need_dac_fix = 1,
10531 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10532 .unsol_event = alc_sku_unsol_event,
10533 .setup = alc883_mode2_setup,
10534 .init_hook = alc_inithook,
e2757d5e
KY
10535 },
10536 [ALC888_ASUS_EEE1601] = {
10537 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10538 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10539 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10540 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10541 .dac_nids = alc883_dac_nids,
10542 .dig_out_nid = ALC883_DIGOUT_NID,
10543 .dig_in_nid = ALC883_DIGIN_NID,
10544 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10545 .channel_mode = alc883_3ST_2ch_modes,
10546 .need_dac_fix = 1,
10547 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10548 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10549 .init_hook = alc883_eee1601_inithook,
10550 },
3ab90935
WF
10551 [ALC1200_ASUS_P5Q] = {
10552 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10553 .init_verbs = { alc883_init_verbs },
10554 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10555 .dac_nids = alc883_dac_nids,
10556 .dig_out_nid = ALC1200_DIGOUT_NID,
10557 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10558 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10559 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10560 .channel_mode = alc883_sixstack_modes,
10561 .input_mux = &alc883_capture_source,
10562 },
eb4c41d3
TS
10563 [ALC889A_MB31] = {
10564 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10565 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10566 alc880_gpio1_init_verbs },
10567 .adc_nids = alc883_adc_nids,
10568 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10569 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10570 .dac_nids = alc883_dac_nids,
10571 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10572 .channel_mode = alc889A_mb31_6ch_modes,
10573 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10574 .input_mux = &alc889A_mb31_capture_source,
10575 .dig_out_nid = ALC883_DIGOUT_NID,
10576 .unsol_event = alc889A_mb31_unsol_event,
10577 .init_hook = alc889A_mb31_automute,
10578 },
3e1647c5
GG
10579 [ALC883_SONY_VAIO_TT] = {
10580 .mixers = { alc883_vaiott_mixer },
10581 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10582 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10583 .dac_nids = alc883_dac_nids,
10584 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10585 .channel_mode = alc883_3ST_2ch_modes,
10586 .input_mux = &alc883_capture_source,
10587 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10588 .setup = alc883_vaiott_setup,
10589 .init_hook = alc_automute_amp,
3e1647c5 10590 },
9c7f852e
TI
10591};
10592
10593
4953550a
TI
10594/*
10595 * Pin config fixes
10596 */
10597enum {
954a29c8
TI
10598 PINFIX_ABIT_AW9D_MAX,
10599 PINFIX_PB_M5210,
4953550a
TI
10600};
10601
f8f25ba3
TI
10602static const struct alc_fixup alc882_fixups[] = {
10603 [PINFIX_ABIT_AW9D_MAX] = {
73413b12
TI
10604 .pins = (const struct alc_pincfg[]) {
10605 { 0x15, 0x01080104 }, /* side */
10606 { 0x16, 0x01011012 }, /* rear */
10607 { 0x17, 0x01016011 }, /* clfe */
10608 { }
10609 }
f8f25ba3 10610 },
954a29c8 10611 [PINFIX_PB_M5210] = {
73413b12
TI
10612 .verbs = (const struct hda_verb[]) {
10613 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10614 {}
10615 }
954a29c8 10616 },
4953550a
TI
10617};
10618
f8f25ba3 10619static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10620 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a
TI
10621 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10622 {}
10623};
10624
9c7f852e
TI
10625/*
10626 * BIOS auto configuration
10627 */
05f5f477
TI
10628static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10629 const struct auto_pin_cfg *cfg)
10630{
10631 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10632}
10633
4953550a 10634static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10635 hda_nid_t nid, int pin_type,
489008cd 10636 hda_nid_t dac)
9c7f852e 10637{
f12ab1e0
TI
10638 int idx;
10639
489008cd 10640 /* set as output */
f6c7e546 10641 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10642
10643 if (dac == 0x25)
9c7f852e 10644 idx = 4;
489008cd
TI
10645 else if (dac >= 0x02 && dac <= 0x05)
10646 idx = dac - 2;
f9700d5a 10647 else
489008cd 10648 return;
9c7f852e 10649 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10650}
10651
4953550a 10652static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10653{
10654 struct alc_spec *spec = codec->spec;
10655 int i;
10656
10657 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10658 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10659 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10660 if (nid)
4953550a 10661 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10662 spec->multiout.dac_nids[i]);
9c7f852e
TI
10663 }
10664}
10665
4953550a 10666static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10667{
10668 struct alc_spec *spec = codec->spec;
489008cd 10669 hda_nid_t pin, dac;
5855fb80 10670 int i;
9c7f852e 10671
5855fb80
TI
10672 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10673 pin = spec->autocfg.hp_pins[i];
10674 if (!pin)
10675 break;
489008cd
TI
10676 dac = spec->multiout.hp_nid;
10677 if (!dac)
10678 dac = spec->multiout.dac_nids[0]; /* to front */
10679 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10680 }
5855fb80
TI
10681 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10682 pin = spec->autocfg.speaker_pins[i];
10683 if (!pin)
10684 break;
489008cd
TI
10685 dac = spec->multiout.extra_out_nid[0];
10686 if (!dac)
10687 dac = spec->multiout.dac_nids[0]; /* to front */
10688 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10689 }
9c7f852e
TI
10690}
10691
4953550a 10692static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10693{
10694 struct alc_spec *spec = codec->spec;
66ceeb6b 10695 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10696 int i;
10697
66ceeb6b
TI
10698 for (i = 0; i < cfg->num_inputs; i++) {
10699 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10700 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10701 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10702 snd_hda_codec_write(codec, nid, 0,
10703 AC_VERB_SET_AMP_GAIN_MUTE,
10704 AMP_OUT_MUTE);
10705 }
10706}
10707
10708static void alc882_auto_init_input_src(struct hda_codec *codec)
10709{
10710 struct alc_spec *spec = codec->spec;
10711 int c;
10712
10713 for (c = 0; c < spec->num_adc_nids; c++) {
10714 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10715 hda_nid_t nid = spec->capsrc_nids[c];
10716 unsigned int mux_idx;
10717 const struct hda_input_mux *imux;
10718 int conns, mute, idx, item;
10719
10720 conns = snd_hda_get_connections(codec, nid, conn_list,
10721 ARRAY_SIZE(conn_list));
10722 if (conns < 0)
10723 continue;
10724 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10725 imux = &spec->input_mux[mux_idx];
5311114d
TI
10726 if (!imux->num_items && mux_idx > 0)
10727 imux = &spec->input_mux[0];
4953550a
TI
10728 for (idx = 0; idx < conns; idx++) {
10729 /* if the current connection is the selected one,
10730 * unmute it as default - otherwise mute it
10731 */
10732 mute = AMP_IN_MUTE(idx);
10733 for (item = 0; item < imux->num_items; item++) {
10734 if (imux->items[item].index == idx) {
10735 if (spec->cur_mux[c] == item)
10736 mute = AMP_IN_UNMUTE(idx);
10737 break;
10738 }
10739 }
10740 /* check if we have a selector or mixer
10741 * we could check for the widget type instead, but
10742 * just check for Amp-In presence (in case of mixer
10743 * without amp-in there is something wrong, this
10744 * function shouldn't be used or capsrc nid is wrong)
10745 */
10746 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10747 snd_hda_codec_write(codec, nid, 0,
10748 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10749 mute);
10750 else if (mute != AMP_IN_MUTE(idx))
10751 snd_hda_codec_write(codec, nid, 0,
10752 AC_VERB_SET_CONNECT_SEL,
10753 idx);
9c7f852e
TI
10754 }
10755 }
10756}
10757
4953550a
TI
10758/* add mic boosts if needed */
10759static int alc_auto_add_mic_boost(struct hda_codec *codec)
10760{
10761 struct alc_spec *spec = codec->spec;
66ceeb6b
TI
10762 struct auto_pin_cfg *cfg = &spec->autocfg;
10763 int i, err;
4953550a
TI
10764 hda_nid_t nid;
10765
66ceeb6b 10766 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10767 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10768 break;
10769 nid = cfg->inputs[i].pin;
10770 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10a20af7
TI
10771 char label[32];
10772 snprintf(label, sizeof(label), "%s Boost",
10773 hda_get_autocfg_input_label(codec, cfg, i));
66ceeb6b 10774 err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0,
4953550a 10775 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10776 if (err < 0)
10777 return err;
10778 }
4953550a
TI
10779 }
10780 return 0;
10781}
f511b01c 10782
9c7f852e 10783/* almost identical with ALC880 parser... */
4953550a 10784static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10785{
10786 struct alc_spec *spec = codec->spec;
05f5f477 10787 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10788 int err;
9c7f852e 10789
05f5f477
TI
10790 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10791 alc882_ignore);
9c7f852e
TI
10792 if (err < 0)
10793 return err;
05f5f477
TI
10794 if (!spec->autocfg.line_outs)
10795 return 0; /* can't find valid BIOS pin config */
776e184e 10796
05f5f477
TI
10797 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10798 if (err < 0)
10799 return err;
10800 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10801 if (err < 0)
10802 return err;
10803 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10804 "Headphone");
05f5f477
TI
10805 if (err < 0)
10806 return err;
10807 err = alc880_auto_create_extra_out(spec,
10808 spec->autocfg.speaker_pins[0],
10809 "Speaker");
10810 if (err < 0)
10811 return err;
05f5f477 10812 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10813 if (err < 0)
10814 return err;
10815
05f5f477
TI
10816 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10817
757899ac 10818 alc_auto_parse_digital(codec);
05f5f477
TI
10819
10820 if (spec->kctls.list)
10821 add_mixer(spec, spec->kctls.list);
10822
10823 add_verb(spec, alc883_auto_init_verbs);
4953550a 10824 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10825 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10826 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10827
05f5f477
TI
10828 spec->num_mux_defs = 1;
10829 spec->input_mux = &spec->private_imux[0];
10830
6227cdce 10831 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10832
10833 err = alc_auto_add_mic_boost(codec);
10834 if (err < 0)
10835 return err;
61b9b9b1 10836
776e184e 10837 return 1; /* config found */
9c7f852e
TI
10838}
10839
10840/* additional initialization for auto-configuration model */
4953550a 10841static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10842{
f6c7e546 10843 struct alc_spec *spec = codec->spec;
4953550a
TI
10844 alc882_auto_init_multi_out(codec);
10845 alc882_auto_init_hp_out(codec);
10846 alc882_auto_init_analog_input(codec);
10847 alc882_auto_init_input_src(codec);
757899ac 10848 alc_auto_init_digital(codec);
f6c7e546 10849 if (spec->unsol_event)
7fb0d78f 10850 alc_inithook(codec);
9c7f852e
TI
10851}
10852
4953550a 10853static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10854{
10855 struct alc_spec *spec;
10856 int err, board_config;
10857
10858 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10859 if (spec == NULL)
10860 return -ENOMEM;
10861
10862 codec->spec = spec;
10863
da00c244
KY
10864 alc_auto_parse_customize_define(codec);
10865
4953550a
TI
10866 switch (codec->vendor_id) {
10867 case 0x10ec0882:
10868 case 0x10ec0885:
10869 break;
10870 default:
10871 /* ALC883 and variants */
10872 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10873 break;
10874 }
2c3bf9ab 10875
4953550a
TI
10876 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10877 alc882_models,
10878 alc882_cfg_tbl);
10879
10880 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10881 board_config = snd_hda_check_board_codec_sid_config(codec,
10882 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10883
10884 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10885 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10886 codec->chip_name);
10887 board_config = ALC882_AUTO;
9c7f852e
TI
10888 }
10889
7fa90e87
TI
10890 if (board_config == ALC882_AUTO)
10891 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a
TI
10892
10893 if (board_config == ALC882_AUTO) {
9c7f852e 10894 /* automatic parse from the BIOS config */
4953550a 10895 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10896 if (err < 0) {
10897 alc_free(codec);
10898 return err;
f12ab1e0 10899 } else if (!err) {
9c7f852e
TI
10900 printk(KERN_INFO
10901 "hda_codec: Cannot set up configuration "
10902 "from BIOS. Using base mode...\n");
4953550a 10903 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10904 }
10905 }
10906
dc1eae25 10907 if (has_cdefine_beep(codec)) {
8af2591d
TI
10908 err = snd_hda_attach_beep_device(codec, 0x1);
10909 if (err < 0) {
10910 alc_free(codec);
10911 return err;
10912 }
680cd536
KK
10913 }
10914
4953550a 10915 if (board_config != ALC882_AUTO)
e9c364c0 10916 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10917
4953550a
TI
10918 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10919 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10920 /* FIXME: setup DAC5 */
10921 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10922 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10923
10924 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10925 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10926
4953550a 10927 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10928 int i, j;
4953550a
TI
10929 spec->num_adc_nids = 0;
10930 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10931 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10932 hda_nid_t cap;
d11f74c6 10933 hda_nid_t items[16];
4953550a
TI
10934 hda_nid_t nid = alc882_adc_nids[i];
10935 unsigned int wcap = get_wcaps(codec, nid);
10936 /* get type */
a22d543a 10937 wcap = get_wcaps_type(wcap);
4953550a
TI
10938 if (wcap != AC_WID_AUD_IN)
10939 continue;
10940 spec->private_adc_nids[spec->num_adc_nids] = nid;
10941 err = snd_hda_get_connections(codec, nid, &cap, 1);
10942 if (err < 0)
10943 continue;
d11f74c6
TI
10944 err = snd_hda_get_connections(codec, cap, items,
10945 ARRAY_SIZE(items));
10946 if (err < 0)
10947 continue;
10948 for (j = 0; j < imux->num_items; j++)
10949 if (imux->items[j].index >= err)
10950 break;
10951 if (j < imux->num_items)
10952 continue;
4953550a
TI
10953 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10954 spec->num_adc_nids++;
61b9b9b1 10955 }
4953550a
TI
10956 spec->adc_nids = spec->private_adc_nids;
10957 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10958 }
10959
b59bdf3b 10960 set_capture_mixer(codec);
da00c244 10961
dc1eae25 10962 if (has_cdefine_beep(codec))
da00c244 10963 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10964
7fa90e87
TI
10965 if (board_config == ALC882_AUTO)
10966 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10967
2134ea4f
TI
10968 spec->vmaster_nid = 0x0c;
10969
9c7f852e 10970 codec->patch_ops = alc_patch_ops;
4953550a
TI
10971 if (board_config == ALC882_AUTO)
10972 spec->init_hook = alc882_auto_init;
cb53c626
TI
10973#ifdef CONFIG_SND_HDA_POWER_SAVE
10974 if (!spec->loopback.amplist)
4953550a 10975 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10976#endif
9c7f852e
TI
10977
10978 return 0;
10979}
10980
4953550a 10981
9c7f852e
TI
10982/*
10983 * ALC262 support
10984 */
10985
10986#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10987#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10988
10989#define alc262_dac_nids alc260_dac_nids
10990#define alc262_adc_nids alc882_adc_nids
10991#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10992#define alc262_capsrc_nids alc882_capsrc_nids
10993#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10994
10995#define alc262_modes alc260_modes
10996#define alc262_capture_source alc882_capture_source
10997
4e555fe5
KY
10998static hda_nid_t alc262_dmic_adc_nids[1] = {
10999 /* ADC0 */
11000 0x09
11001};
11002
11003static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11004
9c7f852e
TI
11005static struct snd_kcontrol_new alc262_base_mixer[] = {
11006 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11007 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11010 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11011 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11012 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11013 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 11014 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11015 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11016 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 11017 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11018 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11019 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11020 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11021 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11022 { } /* end */
11023};
11024
ce875f07
TI
11025/* update HP, line and mono-out pins according to the master switch */
11026static void alc262_hp_master_update(struct hda_codec *codec)
11027{
11028 struct alc_spec *spec = codec->spec;
11029 int val = spec->master_sw;
11030
11031 /* HP & line-out */
11032 snd_hda_codec_write_cache(codec, 0x1b, 0,
11033 AC_VERB_SET_PIN_WIDGET_CONTROL,
11034 val ? PIN_HP : 0);
11035 snd_hda_codec_write_cache(codec, 0x15, 0,
11036 AC_VERB_SET_PIN_WIDGET_CONTROL,
11037 val ? PIN_HP : 0);
11038 /* mono (speaker) depending on the HP jack sense */
11039 val = val && !spec->jack_present;
11040 snd_hda_codec_write_cache(codec, 0x16, 0,
11041 AC_VERB_SET_PIN_WIDGET_CONTROL,
11042 val ? PIN_OUT : 0);
11043}
11044
11045static void alc262_hp_bpc_automute(struct hda_codec *codec)
11046{
11047 struct alc_spec *spec = codec->spec;
864f92be
WF
11048
11049 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11050 alc262_hp_master_update(codec);
11051}
11052
11053static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11054{
11055 if ((res >> 26) != ALC880_HP_EVENT)
11056 return;
11057 alc262_hp_bpc_automute(codec);
11058}
11059
11060static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11061{
11062 struct alc_spec *spec = codec->spec;
864f92be
WF
11063
11064 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11065 alc262_hp_master_update(codec);
11066}
11067
11068static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11069 unsigned int res)
11070{
11071 if ((res >> 26) != ALC880_HP_EVENT)
11072 return;
11073 alc262_hp_wildwest_automute(codec);
11074}
11075
b72519b5 11076#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11077
11078static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11079 struct snd_ctl_elem_value *ucontrol)
11080{
11081 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11082 struct alc_spec *spec = codec->spec;
11083 int val = !!*ucontrol->value.integer.value;
11084
11085 if (val == spec->master_sw)
11086 return 0;
11087 spec->master_sw = val;
11088 alc262_hp_master_update(codec);
11089 return 1;
11090}
11091
b72519b5
TI
11092#define ALC262_HP_MASTER_SWITCH \
11093 { \
11094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11095 .name = "Master Playback Switch", \
11096 .info = snd_ctl_boolean_mono_info, \
11097 .get = alc262_hp_master_sw_get, \
11098 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11099 }, \
11100 { \
11101 .iface = NID_MAPPING, \
11102 .name = "Master Playback Switch", \
11103 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11104 }
11105
5b0cb1d8 11106
9c7f852e 11107static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11108 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11109 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11110 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11111 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11112 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11113 HDA_OUTPUT),
11114 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11115 HDA_OUTPUT),
9c7f852e
TI
11116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11117 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 11118 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11119 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11120 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 11121 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11122 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11123 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11124 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11125 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11126 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11127 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11128 { } /* end */
11129};
11130
cd7509a4 11131static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11132 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11133 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11134 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11135 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11137 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11138 HDA_OUTPUT),
11139 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11140 HDA_OUTPUT),
cd7509a4
KY
11141 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11142 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 11143 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11144 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11145 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11146 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11147 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11148 { } /* end */
11149};
11150
11151static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11152 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11153 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 11154 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11155 { } /* end */
11156};
11157
66d2a9d6 11158/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11159static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11160{
11161 struct alc_spec *spec = codec->spec;
66d2a9d6 11162
a9fd4f3f 11163 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11164 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11165}
11166
66d2a9d6 11167static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11168 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11169 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11170 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11173 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11174 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11175 { } /* end */
11176};
11177
11178static struct hda_verb alc262_hp_t5735_verbs[] = {
11179 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11181
11182 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11183 { }
11184};
11185
8c427226 11186static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11187 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11188 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11189 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11190 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11191 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11192 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11193 { } /* end */
11194};
11195
11196static struct hda_verb alc262_hp_rp5700_verbs[] = {
11197 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11198 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11199 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11200 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11201 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11202 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11203 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11205 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11207 {}
11208};
11209
11210static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11211 .num_items = 1,
11212 .items = {
11213 { "Line", 0x1 },
11214 },
11215};
11216
42171c17
TI
11217/* bind hp and internal speaker mute (with plug check) as master switch */
11218static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11219{
42171c17
TI
11220 struct alc_spec *spec = codec->spec;
11221 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11222 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11223 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11224 unsigned int mute;
0724ea2a 11225
42171c17
TI
11226 /* HP */
11227 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11228 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11229 HDA_AMP_MUTE, mute);
11230 /* mute internal speaker per jack sense */
11231 if (spec->jack_present)
11232 mute = HDA_AMP_MUTE;
11233 if (line_nid)
11234 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11235 HDA_AMP_MUTE, mute);
11236 if (speaker_nid && speaker_nid != line_nid)
11237 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11238 HDA_AMP_MUTE, mute);
42171c17
TI
11239}
11240
11241#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11242
11243static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11244 struct snd_ctl_elem_value *ucontrol)
11245{
11246 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11247 struct alc_spec *spec = codec->spec;
11248 int val = !!*ucontrol->value.integer.value;
11249
11250 if (val == spec->master_sw)
11251 return 0;
11252 spec->master_sw = val;
11253 alc262_hippo_master_update(codec);
11254 return 1;
11255}
11256
11257#define ALC262_HIPPO_MASTER_SWITCH \
11258 { \
11259 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11260 .name = "Master Playback Switch", \
11261 .info = snd_ctl_boolean_mono_info, \
11262 .get = alc262_hippo_master_sw_get, \
11263 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11264 }, \
11265 { \
11266 .iface = NID_MAPPING, \
11267 .name = "Master Playback Switch", \
11268 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11269 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11270 }
42171c17
TI
11271
11272static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11273 ALC262_HIPPO_MASTER_SWITCH,
11274 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11275 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11276 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11277 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11278 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11279 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11280 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11281 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11282 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11283 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11284 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11285 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11286 { } /* end */
11287};
11288
11289static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11290 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11291 ALC262_HIPPO_MASTER_SWITCH,
11292 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11293 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11294 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11295 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11297 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11298 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11299 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11300 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11301 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11302 { } /* end */
11303};
11304
11305/* mute/unmute internal speaker according to the hp jack and mute state */
11306static void alc262_hippo_automute(struct hda_codec *codec)
11307{
11308 struct alc_spec *spec = codec->spec;
11309 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11310
864f92be 11311 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11312 alc262_hippo_master_update(codec);
0724ea2a 11313}
5b31954e 11314
42171c17
TI
11315static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11316{
11317 if ((res >> 26) != ALC880_HP_EVENT)
11318 return;
11319 alc262_hippo_automute(codec);
11320}
11321
4f5d1706 11322static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11323{
11324 struct alc_spec *spec = codec->spec;
11325
11326 spec->autocfg.hp_pins[0] = 0x15;
11327 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11328}
11329
4f5d1706 11330static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11331{
11332 struct alc_spec *spec = codec->spec;
11333
11334 spec->autocfg.hp_pins[0] = 0x1b;
11335 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11336}
11337
11338
272a527c 11339static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11340 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11341 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11343 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11344 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11345 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11346 { } /* end */
11347};
11348
83c34218 11349static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11350 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11351 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11354 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11355 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11356 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11357 { } /* end */
11358};
272a527c 11359
ba340e82
TV
11360static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11361 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11362 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11363 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11364 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11365 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11366 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11367 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11368 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11369 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11370 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11371 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11373 { } /* end */
11374};
11375
11376static struct hda_verb alc262_tyan_verbs[] = {
11377 /* Headphone automute */
11378 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11379 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11380 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11381
11382 /* P11 AUX_IN, white 4-pin connector */
11383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11384 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11385 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11386 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11387
11388 {}
11389};
11390
11391/* unsolicited event for HP jack sensing */
4f5d1706 11392static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11393{
a9fd4f3f 11394 struct alc_spec *spec = codec->spec;
ba340e82 11395
a9fd4f3f
TI
11396 spec->autocfg.hp_pins[0] = 0x1b;
11397 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11398}
11399
ba340e82 11400
9c7f852e
TI
11401#define alc262_capture_mixer alc882_capture_mixer
11402#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11403
11404/*
11405 * generic initialization of ADC, input mixers and output mixers
11406 */
11407static struct hda_verb alc262_init_verbs[] = {
11408 /*
11409 * Unmute ADC0-2 and set the default input to mic-in
11410 */
11411 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11413 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11415 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11417
cb53c626 11418 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11419 * mixer widget
f12ab1e0
TI
11420 * Note: PASD motherboards uses the Line In 2 as the input for
11421 * front panel mic (mic 2)
9c7f852e
TI
11422 */
11423 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11424 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11425 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11426 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11427 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11428 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11429
11430 /*
df694daa
KY
11431 * Set up output mixers (0x0c - 0x0e)
11432 */
11433 /* set vol=0 to output mixers */
11434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11435 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11436 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11437 /* set up input amps for analog loopback */
11438 /* Amp Indices: DAC = 0, mixer = 1 */
11439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11440 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11442 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11445
11446 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11447 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11448 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11449 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11450 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11451 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11452
11453 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11455 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11458
df694daa
KY
11459 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11460 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11461
df694daa
KY
11462 /* FIXME: use matrix-type input source selection */
11463 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11464 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11465 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11466 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11467 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11468 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11469 /* Input mixer2 */
11470 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11471 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11472 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11473 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11474 /* Input mixer3 */
11475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11477 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11479
11480 { }
11481};
1da177e4 11482
4e555fe5
KY
11483static struct hda_verb alc262_eapd_verbs[] = {
11484 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11485 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11486 { }
11487};
11488
ccc656ce
KY
11489static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11490 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11491 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11492 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11493
11494 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11496 {}
11497};
11498
272a527c
KY
11499static struct hda_verb alc262_sony_unsol_verbs[] = {
11500 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11501 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11502 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11503
11504 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11505 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11506 {}
272a527c
KY
11507};
11508
4e555fe5
KY
11509static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11510 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11511 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11515 { } /* end */
11516};
11517
11518static struct hda_verb alc262_toshiba_s06_verbs[] = {
11519 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11522 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11523 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11525 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11526 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11527 {}
11528};
11529
4f5d1706 11530static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11531{
a9fd4f3f
TI
11532 struct alc_spec *spec = codec->spec;
11533
11534 spec->autocfg.hp_pins[0] = 0x15;
11535 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11536 spec->ext_mic.pin = 0x18;
11537 spec->ext_mic.mux_idx = 0;
11538 spec->int_mic.pin = 0x12;
11539 spec->int_mic.mux_idx = 9;
11540 spec->auto_mic = 1;
4e555fe5
KY
11541}
11542
e8f9ae2a
PT
11543/*
11544 * nec model
11545 * 0x15 = headphone
11546 * 0x16 = internal speaker
11547 * 0x18 = external mic
11548 */
11549
11550static struct snd_kcontrol_new alc262_nec_mixer[] = {
11551 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11552 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11553
11554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11556 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11557
11558 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11559 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11560 { } /* end */
11561};
11562
11563static struct hda_verb alc262_nec_verbs[] = {
11564 /* Unmute Speaker */
11565 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11566
11567 /* Headphone */
11568 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11570
11571 /* External mic to headphone */
11572 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11573 /* External mic to speaker */
11574 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11575 {}
11576};
11577
834be88d
TI
11578/*
11579 * fujitsu model
5d9fab2d
TV
11580 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11581 * 0x1b = port replicator headphone out
834be88d
TI
11582 */
11583
11584#define ALC_HP_EVENT 0x37
11585
11586static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11587 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11589 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11591 {}
11592};
11593
0e31daf7
J
11594static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11595 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11596 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11597 {}
11598};
11599
e2595322
DC
11600static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11601 /* Front Mic pin: input vref at 50% */
11602 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11603 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11604 {}
11605};
11606
834be88d 11607static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11608 .num_items = 3,
834be88d
TI
11609 .items = {
11610 { "Mic", 0x0 },
39d3ed38 11611 { "Int Mic", 0x1 },
834be88d
TI
11612 { "CD", 0x4 },
11613 },
11614};
11615
9c7f852e
TI
11616static struct hda_input_mux alc262_HP_capture_source = {
11617 .num_items = 5,
11618 .items = {
11619 { "Mic", 0x0 },
accbe498 11620 { "Front Mic", 0x1 },
9c7f852e
TI
11621 { "Line", 0x2 },
11622 { "CD", 0x4 },
11623 { "AUX IN", 0x6 },
11624 },
11625};
11626
accbe498 11627static struct hda_input_mux alc262_HP_D7000_capture_source = {
11628 .num_items = 4,
11629 .items = {
11630 { "Mic", 0x0 },
11631 { "Front Mic", 0x2 },
11632 { "Line", 0x1 },
11633 { "CD", 0x4 },
11634 },
11635};
11636
ebc7a406 11637/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11638static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11639{
11640 struct alc_spec *spec = codec->spec;
11641 unsigned int mute;
11642
f12ab1e0 11643 if (force || !spec->sense_updated) {
864f92be
WF
11644 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11645 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11646 spec->sense_updated = 1;
11647 }
ebc7a406
TI
11648 /* unmute internal speaker only if both HPs are unplugged and
11649 * master switch is on
11650 */
11651 if (spec->jack_present)
11652 mute = HDA_AMP_MUTE;
11653 else
834be88d 11654 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11655 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11656 HDA_AMP_MUTE, mute);
834be88d
TI
11657}
11658
11659/* unsolicited event for HP jack sensing */
11660static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11661 unsigned int res)
11662{
11663 if ((res >> 26) != ALC_HP_EVENT)
11664 return;
11665 alc262_fujitsu_automute(codec, 1);
11666}
11667
ebc7a406
TI
11668static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11669{
11670 alc262_fujitsu_automute(codec, 1);
11671}
11672
834be88d 11673/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11674static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11675 .ops = &snd_hda_bind_vol,
11676 .values = {
11677 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11678 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11679 0
11680 },
11681};
834be88d 11682
0e31daf7
J
11683/* mute/unmute internal speaker according to the hp jack and mute state */
11684static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11685{
11686 struct alc_spec *spec = codec->spec;
11687 unsigned int mute;
11688
11689 if (force || !spec->sense_updated) {
864f92be 11690 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11691 spec->sense_updated = 1;
11692 }
11693 if (spec->jack_present) {
11694 /* mute internal speaker */
11695 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11696 HDA_AMP_MUTE, HDA_AMP_MUTE);
11697 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11698 HDA_AMP_MUTE, HDA_AMP_MUTE);
11699 } else {
11700 /* unmute internal speaker if necessary */
11701 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11702 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11703 HDA_AMP_MUTE, mute);
11704 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11705 HDA_AMP_MUTE, mute);
11706 }
11707}
11708
11709/* unsolicited event for HP jack sensing */
11710static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11711 unsigned int res)
11712{
11713 if ((res >> 26) != ALC_HP_EVENT)
11714 return;
11715 alc262_lenovo_3000_automute(codec, 1);
11716}
11717
8de56b7d
TI
11718static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11719 int dir, int idx, long *valp)
11720{
11721 int i, change = 0;
11722
11723 for (i = 0; i < 2; i++, valp++)
11724 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11725 HDA_AMP_MUTE,
11726 *valp ? 0 : HDA_AMP_MUTE);
11727 return change;
11728}
11729
834be88d
TI
11730/* bind hp and internal speaker mute (with plug check) */
11731static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11732 struct snd_ctl_elem_value *ucontrol)
11733{
11734 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11735 long *valp = ucontrol->value.integer.value;
11736 int change;
11737
8de56b7d
TI
11738 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11739 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11740 if (change)
11741 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11742 return change;
11743}
11744
11745static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11746 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11747 {
11748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11749 .name = "Master Playback Switch",
5e26dfd0 11750 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11751 .info = snd_hda_mixer_amp_switch_info,
11752 .get = snd_hda_mixer_amp_switch_get,
11753 .put = alc262_fujitsu_master_sw_put,
11754 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11755 },
5b0cb1d8
JK
11756 {
11757 .iface = NID_MAPPING,
11758 .name = "Master Playback Switch",
11759 .private_value = 0x1b,
11760 },
834be88d
TI
11761 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11762 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11763 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11766 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11767 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11768 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11769 { } /* end */
11770};
11771
0e31daf7
J
11772/* bind hp and internal speaker mute (with plug check) */
11773static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11774 struct snd_ctl_elem_value *ucontrol)
11775{
11776 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11777 long *valp = ucontrol->value.integer.value;
11778 int change;
11779
8de56b7d 11780 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11781 if (change)
11782 alc262_lenovo_3000_automute(codec, 0);
11783 return change;
11784}
11785
11786static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11787 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11788 {
11789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11790 .name = "Master Playback Switch",
5e26dfd0 11791 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11792 .info = snd_hda_mixer_amp_switch_info,
11793 .get = snd_hda_mixer_amp_switch_get,
11794 .put = alc262_lenovo_3000_master_sw_put,
11795 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11796 },
11797 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11798 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11799 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11801 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11802 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11803 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11804 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11805 { } /* end */
11806};
11807
9f99a638
HM
11808static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11809 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11810 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11812 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11813 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11814 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11815 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11816 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11817 { } /* end */
11818};
11819
304dcaac
TI
11820/* additional init verbs for Benq laptops */
11821static struct hda_verb alc262_EAPD_verbs[] = {
11822 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11823 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11824 {}
11825};
11826
83c34218
KY
11827static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11829 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11830
11831 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11832 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11833 {}
11834};
11835
f651b50b
TD
11836/* Samsung Q1 Ultra Vista model setup */
11837static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11838 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11839 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11842 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11843 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11844 { } /* end */
11845};
11846
11847static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11848 /* output mixer */
11849 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11850 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11852 /* speaker */
11853 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11854 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11855 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11856 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11857 /* HP */
f651b50b 11858 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11859 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11861 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11862 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11863 /* internal mic */
11864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11865 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11866 /* ADC, choose mic */
11867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11868 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11869 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11870 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11871 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11872 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11873 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11874 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11875 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11876 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11877 {}
11878};
11879
f651b50b
TD
11880/* mute/unmute internal speaker according to the hp jack and mute state */
11881static void alc262_ultra_automute(struct hda_codec *codec)
11882{
11883 struct alc_spec *spec = codec->spec;
11884 unsigned int mute;
f651b50b 11885
bb9f76cd
TI
11886 mute = 0;
11887 /* auto-mute only when HP is used as HP */
11888 if (!spec->cur_mux[0]) {
864f92be 11889 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11890 if (spec->jack_present)
11891 mute = HDA_AMP_MUTE;
f651b50b 11892 }
bb9f76cd
TI
11893 /* mute/unmute internal speaker */
11894 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11895 HDA_AMP_MUTE, mute);
11896 /* mute/unmute HP */
11897 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11898 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11899}
11900
11901/* unsolicited event for HP jack sensing */
11902static void alc262_ultra_unsol_event(struct hda_codec *codec,
11903 unsigned int res)
11904{
11905 if ((res >> 26) != ALC880_HP_EVENT)
11906 return;
11907 alc262_ultra_automute(codec);
11908}
11909
bb9f76cd
TI
11910static struct hda_input_mux alc262_ultra_capture_source = {
11911 .num_items = 2,
11912 .items = {
11913 { "Mic", 0x1 },
11914 { "Headphone", 0x7 },
11915 },
11916};
11917
11918static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11919 struct snd_ctl_elem_value *ucontrol)
11920{
11921 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11922 struct alc_spec *spec = codec->spec;
11923 int ret;
11924
54cbc9ab 11925 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11926 if (!ret)
11927 return 0;
11928 /* reprogram the HP pin as mic or HP according to the input source */
11929 snd_hda_codec_write_cache(codec, 0x15, 0,
11930 AC_VERB_SET_PIN_WIDGET_CONTROL,
11931 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11932 alc262_ultra_automute(codec); /* mute/unmute HP */
11933 return ret;
11934}
11935
11936static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11937 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11938 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11939 {
11940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11941 .name = "Capture Source",
54cbc9ab
TI
11942 .info = alc_mux_enum_info,
11943 .get = alc_mux_enum_get,
bb9f76cd
TI
11944 .put = alc262_ultra_mux_enum_put,
11945 },
5b0cb1d8
JK
11946 {
11947 .iface = NID_MAPPING,
11948 .name = "Capture Source",
11949 .private_value = 0x15,
11950 },
bb9f76cd
TI
11951 { } /* end */
11952};
11953
c3fc1f50
TI
11954/* We use two mixers depending on the output pin; 0x16 is a mono output
11955 * and thus it's bound with a different mixer.
11956 * This function returns which mixer amp should be used.
11957 */
11958static int alc262_check_volbit(hda_nid_t nid)
11959{
11960 if (!nid)
11961 return 0;
11962 else if (nid == 0x16)
11963 return 2;
11964 else
11965 return 1;
11966}
11967
11968static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 11969 const char *pfx, int *vbits, int idx)
c3fc1f50 11970{
c3fc1f50
TI
11971 unsigned long val;
11972 int vbit;
11973
11974 vbit = alc262_check_volbit(nid);
11975 if (!vbit)
11976 return 0;
11977 if (*vbits & vbit) /* a volume control for this mixer already there */
11978 return 0;
11979 *vbits |= vbit;
c3fc1f50
TI
11980 if (vbit == 2)
11981 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11982 else
11983 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 11984 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
11985}
11986
11987static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 11988 const char *pfx, int idx)
c3fc1f50 11989{
c3fc1f50
TI
11990 unsigned long val;
11991
11992 if (!nid)
11993 return 0;
c3fc1f50
TI
11994 if (nid == 0x16)
11995 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11996 else
11997 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 11998 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
11999}
12000
df694daa 12001/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12002static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12003 const struct auto_pin_cfg *cfg)
df694daa 12004{
c3fc1f50
TI
12005 const char *pfx;
12006 int vbits;
033688a5 12007 int i, err;
df694daa
KY
12008
12009 spec->multiout.num_dacs = 1; /* only use one dac */
12010 spec->multiout.dac_nids = spec->private_dac_nids;
12011 spec->multiout.dac_nids[0] = 2;
12012
c3fc1f50
TI
12013 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
12014 pfx = "Master";
12015 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12016 pfx = "Speaker";
033688a5
TI
12017 else if (cfg->line_out_type == AUTO_PIN_HP_OUT)
12018 pfx = "Headphone";
c3fc1f50
TI
12019 else
12020 pfx = "Front";
033688a5
TI
12021 for (i = 0; i < 2; i++) {
12022 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12023 if (err < 0)
12024 return err;
12025 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12026 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12027 "Speaker", i);
12028 if (err < 0)
12029 return err;
12030 }
12031 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12032 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12033 "Headphone", i);
12034 if (err < 0)
12035 return err;
12036 }
12037 }
df694daa 12038
c3fc1f50
TI
12039 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12040 alc262_check_volbit(cfg->speaker_pins[0]) |
12041 alc262_check_volbit(cfg->hp_pins[0]);
12042 if (vbits == 1 || vbits == 2)
12043 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12044 vbits = 0;
033688a5
TI
12045 for (i = 0; i < 2; i++) {
12046 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12047 &vbits, i);
12048 if (err < 0)
12049 return err;
12050 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12051 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12052 "Speaker", &vbits, i);
12053 if (err < 0)
12054 return err;
12055 }
12056 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12057 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12058 "Headphone", &vbits, i);
12059 if (err < 0)
12060 return err;
12061 }
12062 }
f12ab1e0 12063 return 0;
df694daa
KY
12064}
12065
05f5f477 12066#define alc262_auto_create_input_ctls \
eaa9b3a7 12067 alc882_auto_create_input_ctls
df694daa
KY
12068
12069/*
12070 * generic initialization of ADC, input mixers and output mixers
12071 */
12072static struct hda_verb alc262_volume_init_verbs[] = {
12073 /*
12074 * Unmute ADC0-2 and set the default input to mic-in
12075 */
12076 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12077 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12078 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12079 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12080 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12081 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12082
cb53c626 12083 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12084 * mixer widget
f12ab1e0
TI
12085 * Note: PASD motherboards uses the Line In 2 as the input for
12086 * front panel mic (mic 2)
df694daa
KY
12087 */
12088 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12091 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12092 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12093 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12094
12095 /*
12096 * Set up output mixers (0x0c - 0x0f)
12097 */
12098 /* set vol=0 to output mixers */
12099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12102
df694daa
KY
12103 /* set up input amps for analog loopback */
12104 /* Amp Indices: DAC = 0, mixer = 1 */
12105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12111
12112 /* FIXME: use matrix-type input source selection */
12113 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12114 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12115 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12116 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12117 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12118 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12119 /* Input mixer2 */
12120 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12121 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12122 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12123 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12124 /* Input mixer3 */
12125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12128 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12129
12130 { }
12131};
12132
9c7f852e
TI
12133static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12134 /*
12135 * Unmute ADC0-2 and set the default input to mic-in
12136 */
12137 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12139 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12140 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12141 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12142 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12143
cb53c626 12144 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12145 * mixer widget
f12ab1e0
TI
12146 * Note: PASD motherboards uses the Line In 2 as the input for
12147 * front panel mic (mic 2)
9c7f852e
TI
12148 */
12149 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12152 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12153 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12154 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12155 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12156 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12157
9c7f852e
TI
12158 /*
12159 * Set up output mixers (0x0c - 0x0e)
12160 */
12161 /* set vol=0 to output mixers */
12162 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12163 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12164 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12165
12166 /* set up input amps for analog loopback */
12167 /* Amp Indices: DAC = 0, mixer = 1 */
12168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12169 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12170 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12171 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12172 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12173 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12174
ce875f07 12175 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12177 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12178
12179 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12180 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12181
12182 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12183 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12184
12185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12186 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12187 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12188 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12189 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12190
0e4835c1 12191 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12192 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12193 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12194 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12195 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12196 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12197
12198
12199 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12200 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12201 /* Input mixer1: only unmute Mic */
9c7f852e 12202 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12203 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12205 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12211 /* Input mixer2 */
12212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12213 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12217 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12218 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12219 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12220 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12221 /* Input mixer3 */
12222 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12223 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12224 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12225 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12228 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12229 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12230 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12231
ce875f07
TI
12232 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12233
9c7f852e
TI
12234 { }
12235};
12236
cd7509a4
KY
12237static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12238 /*
12239 * Unmute ADC0-2 and set the default input to mic-in
12240 */
12241 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12242 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12243 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12244 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12245 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12246 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12247
cb53c626 12248 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12249 * mixer widget
12250 * Note: PASD motherboards uses the Line In 2 as the input for front
12251 * panel mic (mic 2)
12252 */
12253 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12255 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12256 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12257 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12258 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12259 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12260 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12261 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12262 /*
12263 * Set up output mixers (0x0c - 0x0e)
12264 */
12265 /* set vol=0 to output mixers */
12266 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12267 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12268 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12269
12270 /* set up input amps for analog loopback */
12271 /* Amp Indices: DAC = 0, mixer = 1 */
12272 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12273 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12274 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12275 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12276 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12277 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12278
12279
12280 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12281 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12282 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12283 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12284 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12285 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12286 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12287
12288 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12290
12291 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12292 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12293
12294 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12295 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12296 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12297 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12298 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12299 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12300
12301 /* FIXME: use matrix-type input source selection */
12302 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12303 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12304 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12305 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12306 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12307 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12308 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12309 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12310 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12311 /* Input mixer2 */
12312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12313 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12314 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12315 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12316 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12317 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12318 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12319 /* Input mixer3 */
12320 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12321 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12325 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12327
ce875f07
TI
12328 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12329
cd7509a4
KY
12330 { }
12331};
12332
9f99a638
HM
12333static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12334
12335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12337 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12338
12339 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12340 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12341 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12342 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12343
12344 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12346 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12347 {}
12348};
12349
18675e42
TI
12350/*
12351 * Pin config fixes
12352 */
12353enum {
12354 PINFIX_FSC_H270,
12355};
12356
12357static const struct alc_fixup alc262_fixups[] = {
12358 [PINFIX_FSC_H270] = {
12359 .pins = (const struct alc_pincfg[]) {
12360 { 0x14, 0x99130110 }, /* speaker */
12361 { 0x15, 0x0221142f }, /* front HP */
12362 { 0x1b, 0x0121141f }, /* rear HP */
12363 { }
12364 }
12365 },
12366 [PINFIX_PB_M5210] = {
12367 .verbs = (const struct hda_verb[]) {
12368 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
12369 {}
12370 }
12371 },
12372};
12373
12374static struct snd_pci_quirk alc262_fixup_tbl[] = {
12375 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12376 {}
12377};
12378
9f99a638 12379
cb53c626
TI
12380#ifdef CONFIG_SND_HDA_POWER_SAVE
12381#define alc262_loopbacks alc880_loopbacks
12382#endif
12383
def319f9 12384/* pcm configuration: identical with ALC880 */
df694daa
KY
12385#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12386#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12387#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12388#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12389
12390/*
12391 * BIOS auto configuration
12392 */
12393static int alc262_parse_auto_config(struct hda_codec *codec)
12394{
12395 struct alc_spec *spec = codec->spec;
12396 int err;
12397 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12398
f12ab1e0
TI
12399 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12400 alc262_ignore);
12401 if (err < 0)
df694daa 12402 return err;
e64f14f4 12403 if (!spec->autocfg.line_outs) {
0852d7a6 12404 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12405 spec->multiout.max_channels = 2;
12406 spec->no_analog = 1;
12407 goto dig_only;
12408 }
df694daa 12409 return 0; /* can't find valid BIOS pin config */
e64f14f4 12410 }
f12ab1e0
TI
12411 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12412 if (err < 0)
12413 return err;
05f5f477 12414 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12415 if (err < 0)
df694daa
KY
12416 return err;
12417
12418 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12419
e64f14f4 12420 dig_only:
757899ac 12421 alc_auto_parse_digital(codec);
df694daa 12422
603c4019 12423 if (spec->kctls.list)
d88897ea 12424 add_mixer(spec, spec->kctls.list);
df694daa 12425
d88897ea 12426 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12427 spec->num_mux_defs = 1;
61b9b9b1 12428 spec->input_mux = &spec->private_imux[0];
df694daa 12429
776e184e
TI
12430 err = alc_auto_add_mic_boost(codec);
12431 if (err < 0)
12432 return err;
12433
6227cdce 12434 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12435
df694daa
KY
12436 return 1;
12437}
12438
12439#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12440#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12441#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12442#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12443
12444
12445/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12446static void alc262_auto_init(struct hda_codec *codec)
df694daa 12447{
f6c7e546 12448 struct alc_spec *spec = codec->spec;
df694daa
KY
12449 alc262_auto_init_multi_out(codec);
12450 alc262_auto_init_hp_out(codec);
12451 alc262_auto_init_analog_input(codec);
f511b01c 12452 alc262_auto_init_input_src(codec);
757899ac 12453 alc_auto_init_digital(codec);
f6c7e546 12454 if (spec->unsol_event)
7fb0d78f 12455 alc_inithook(codec);
df694daa
KY
12456}
12457
12458/*
12459 * configuration and preset
12460 */
f5fcc13c
TI
12461static const char *alc262_models[ALC262_MODEL_LAST] = {
12462 [ALC262_BASIC] = "basic",
12463 [ALC262_HIPPO] = "hippo",
12464 [ALC262_HIPPO_1] = "hippo_1",
12465 [ALC262_FUJITSU] = "fujitsu",
12466 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12467 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12468 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12469 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12470 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12471 [ALC262_BENQ_T31] = "benq-t31",
12472 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12473 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12474 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12475 [ALC262_ULTRA] = "ultra",
0e31daf7 12476 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12477 [ALC262_NEC] = "nec",
ba340e82 12478 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12479 [ALC262_AUTO] = "auto",
12480};
12481
12482static struct snd_pci_quirk alc262_cfg_tbl[] = {
12483 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12484 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12485 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12486 ALC262_HP_BPC),
12487 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12488 ALC262_HP_BPC),
53eff7e1
TI
12489 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12490 ALC262_HP_BPC),
cd7509a4 12491 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12492 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12493 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12494 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12495 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12496 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12497 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12498 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12499 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12500 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12501 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12502 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12503 ALC262_HP_TC_T5735),
8c427226 12504 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12505 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12506 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12507 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12508 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12509 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12510 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12511 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12512#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12513 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12514 ALC262_SONY_ASSAMD),
c5b5165c 12515#endif
36ca6e13 12516 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12517 ALC262_TOSHIBA_RX1),
80ffe869 12518 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12519 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12520 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12521 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12522 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12523 ALC262_ULTRA),
3e420e78 12524 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12525 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12526 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12527 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12528 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12529 {}
12530};
12531
12532static struct alc_config_preset alc262_presets[] = {
12533 [ALC262_BASIC] = {
12534 .mixers = { alc262_base_mixer },
12535 .init_verbs = { alc262_init_verbs },
12536 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12537 .dac_nids = alc262_dac_nids,
12538 .hp_nid = 0x03,
12539 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12540 .channel_mode = alc262_modes,
a3bcba38 12541 .input_mux = &alc262_capture_source,
df694daa 12542 },
ccc656ce 12543 [ALC262_HIPPO] = {
42171c17 12544 .mixers = { alc262_hippo_mixer },
6732bd0d 12545 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12546 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12547 .dac_nids = alc262_dac_nids,
12548 .hp_nid = 0x03,
12549 .dig_out_nid = ALC262_DIGOUT_NID,
12550 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12551 .channel_mode = alc262_modes,
12552 .input_mux = &alc262_capture_source,
12553 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12554 .setup = alc262_hippo_setup,
12555 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12556 },
12557 [ALC262_HIPPO_1] = {
12558 .mixers = { alc262_hippo1_mixer },
12559 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12560 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12561 .dac_nids = alc262_dac_nids,
12562 .hp_nid = 0x02,
12563 .dig_out_nid = ALC262_DIGOUT_NID,
12564 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12565 .channel_mode = alc262_modes,
12566 .input_mux = &alc262_capture_source,
42171c17 12567 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12568 .setup = alc262_hippo1_setup,
12569 .init_hook = alc262_hippo_automute,
ccc656ce 12570 },
834be88d
TI
12571 [ALC262_FUJITSU] = {
12572 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12573 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12574 alc262_fujitsu_unsol_verbs },
834be88d
TI
12575 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12576 .dac_nids = alc262_dac_nids,
12577 .hp_nid = 0x03,
12578 .dig_out_nid = ALC262_DIGOUT_NID,
12579 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12580 .channel_mode = alc262_modes,
12581 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12582 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12583 .init_hook = alc262_fujitsu_init_hook,
834be88d 12584 },
9c7f852e
TI
12585 [ALC262_HP_BPC] = {
12586 .mixers = { alc262_HP_BPC_mixer },
12587 .init_verbs = { alc262_HP_BPC_init_verbs },
12588 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12589 .dac_nids = alc262_dac_nids,
12590 .hp_nid = 0x03,
12591 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12592 .channel_mode = alc262_modes,
12593 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12594 .unsol_event = alc262_hp_bpc_unsol_event,
12595 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12596 },
cd7509a4
KY
12597 [ALC262_HP_BPC_D7000_WF] = {
12598 .mixers = { alc262_HP_BPC_WildWest_mixer },
12599 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12600 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12601 .dac_nids = alc262_dac_nids,
12602 .hp_nid = 0x03,
12603 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12604 .channel_mode = alc262_modes,
accbe498 12605 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12606 .unsol_event = alc262_hp_wildwest_unsol_event,
12607 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12608 },
cd7509a4
KY
12609 [ALC262_HP_BPC_D7000_WL] = {
12610 .mixers = { alc262_HP_BPC_WildWest_mixer,
12611 alc262_HP_BPC_WildWest_option_mixer },
12612 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12613 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12614 .dac_nids = alc262_dac_nids,
12615 .hp_nid = 0x03,
12616 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12617 .channel_mode = alc262_modes,
accbe498 12618 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12619 .unsol_event = alc262_hp_wildwest_unsol_event,
12620 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12621 },
66d2a9d6
KY
12622 [ALC262_HP_TC_T5735] = {
12623 .mixers = { alc262_hp_t5735_mixer },
12624 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12625 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12626 .dac_nids = alc262_dac_nids,
12627 .hp_nid = 0x03,
12628 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12629 .channel_mode = alc262_modes,
12630 .input_mux = &alc262_capture_source,
dc99be47 12631 .unsol_event = alc_sku_unsol_event,
4f5d1706 12632 .setup = alc262_hp_t5735_setup,
dc99be47 12633 .init_hook = alc_inithook,
8c427226
KY
12634 },
12635 [ALC262_HP_RP5700] = {
12636 .mixers = { alc262_hp_rp5700_mixer },
12637 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12638 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12639 .dac_nids = alc262_dac_nids,
12640 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12641 .channel_mode = alc262_modes,
12642 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12643 },
304dcaac
TI
12644 [ALC262_BENQ_ED8] = {
12645 .mixers = { alc262_base_mixer },
12646 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12647 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12648 .dac_nids = alc262_dac_nids,
12649 .hp_nid = 0x03,
12650 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12651 .channel_mode = alc262_modes,
12652 .input_mux = &alc262_capture_source,
f12ab1e0 12653 },
272a527c
KY
12654 [ALC262_SONY_ASSAMD] = {
12655 .mixers = { alc262_sony_mixer },
12656 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12657 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12658 .dac_nids = alc262_dac_nids,
12659 .hp_nid = 0x02,
12660 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12661 .channel_mode = alc262_modes,
12662 .input_mux = &alc262_capture_source,
12663 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12664 .setup = alc262_hippo_setup,
12665 .init_hook = alc262_hippo_automute,
83c34218
KY
12666 },
12667 [ALC262_BENQ_T31] = {
12668 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12669 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12670 alc_hp15_unsol_verbs },
83c34218
KY
12671 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12672 .dac_nids = alc262_dac_nids,
12673 .hp_nid = 0x03,
12674 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12675 .channel_mode = alc262_modes,
12676 .input_mux = &alc262_capture_source,
12677 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12678 .setup = alc262_hippo_setup,
12679 .init_hook = alc262_hippo_automute,
ea1fb29a 12680 },
f651b50b 12681 [ALC262_ULTRA] = {
f9e336f6
TI
12682 .mixers = { alc262_ultra_mixer },
12683 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12684 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12685 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12686 .dac_nids = alc262_dac_nids,
f651b50b
TD
12687 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12688 .channel_mode = alc262_modes,
12689 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12690 .adc_nids = alc262_adc_nids, /* ADC0 */
12691 .capsrc_nids = alc262_capsrc_nids,
12692 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12693 .unsol_event = alc262_ultra_unsol_event,
12694 .init_hook = alc262_ultra_automute,
12695 },
0e31daf7
J
12696 [ALC262_LENOVO_3000] = {
12697 .mixers = { alc262_lenovo_3000_mixer },
12698 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12699 alc262_lenovo_3000_unsol_verbs,
12700 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12701 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12702 .dac_nids = alc262_dac_nids,
12703 .hp_nid = 0x03,
12704 .dig_out_nid = ALC262_DIGOUT_NID,
12705 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12706 .channel_mode = alc262_modes,
12707 .input_mux = &alc262_fujitsu_capture_source,
12708 .unsol_event = alc262_lenovo_3000_unsol_event,
12709 },
e8f9ae2a
PT
12710 [ALC262_NEC] = {
12711 .mixers = { alc262_nec_mixer },
12712 .init_verbs = { alc262_nec_verbs },
12713 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12714 .dac_nids = alc262_dac_nids,
12715 .hp_nid = 0x03,
12716 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12717 .channel_mode = alc262_modes,
12718 .input_mux = &alc262_capture_source,
12719 },
4e555fe5
KY
12720 [ALC262_TOSHIBA_S06] = {
12721 .mixers = { alc262_toshiba_s06_mixer },
12722 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12723 alc262_eapd_verbs },
12724 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12725 .capsrc_nids = alc262_dmic_capsrc_nids,
12726 .dac_nids = alc262_dac_nids,
12727 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12728 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12729 .dig_out_nid = ALC262_DIGOUT_NID,
12730 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12731 .channel_mode = alc262_modes,
4f5d1706
TI
12732 .unsol_event = alc_sku_unsol_event,
12733 .setup = alc262_toshiba_s06_setup,
12734 .init_hook = alc_inithook,
4e555fe5 12735 },
9f99a638
HM
12736 [ALC262_TOSHIBA_RX1] = {
12737 .mixers = { alc262_toshiba_rx1_mixer },
12738 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12739 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12740 .dac_nids = alc262_dac_nids,
12741 .hp_nid = 0x03,
12742 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12743 .channel_mode = alc262_modes,
12744 .input_mux = &alc262_capture_source,
12745 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12746 .setup = alc262_hippo_setup,
12747 .init_hook = alc262_hippo_automute,
9f99a638 12748 },
ba340e82
TV
12749 [ALC262_TYAN] = {
12750 .mixers = { alc262_tyan_mixer },
12751 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12752 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12753 .dac_nids = alc262_dac_nids,
12754 .hp_nid = 0x02,
12755 .dig_out_nid = ALC262_DIGOUT_NID,
12756 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12757 .channel_mode = alc262_modes,
12758 .input_mux = &alc262_capture_source,
a9fd4f3f 12759 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12760 .setup = alc262_tyan_setup,
12761 .init_hook = alc_automute_amp,
ba340e82 12762 },
df694daa
KY
12763};
12764
12765static int patch_alc262(struct hda_codec *codec)
12766{
12767 struct alc_spec *spec;
12768 int board_config;
12769 int err;
12770
dc041e0b 12771 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12772 if (spec == NULL)
12773 return -ENOMEM;
12774
12775 codec->spec = spec;
12776#if 0
f12ab1e0
TI
12777 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12778 * under-run
12779 */
df694daa
KY
12780 {
12781 int tmp;
12782 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12783 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12784 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12785 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12786 }
12787#endif
da00c244 12788 alc_auto_parse_customize_define(codec);
df694daa 12789
2c3bf9ab
TI
12790 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12791
f5fcc13c
TI
12792 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12793 alc262_models,
12794 alc262_cfg_tbl);
cd7509a4 12795
f5fcc13c 12796 if (board_config < 0) {
9a11f1aa
TI
12797 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12798 codec->chip_name);
df694daa
KY
12799 board_config = ALC262_AUTO;
12800 }
12801
18675e42
TI
12802 if (board_config == ALC262_AUTO)
12803 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1);
12804
df694daa
KY
12805 if (board_config == ALC262_AUTO) {
12806 /* automatic parse from the BIOS config */
12807 err = alc262_parse_auto_config(codec);
12808 if (err < 0) {
12809 alc_free(codec);
12810 return err;
f12ab1e0 12811 } else if (!err) {
9c7f852e
TI
12812 printk(KERN_INFO
12813 "hda_codec: Cannot set up configuration "
12814 "from BIOS. Using base mode...\n");
df694daa
KY
12815 board_config = ALC262_BASIC;
12816 }
12817 }
12818
dc1eae25 12819 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12820 err = snd_hda_attach_beep_device(codec, 0x1);
12821 if (err < 0) {
12822 alc_free(codec);
12823 return err;
12824 }
680cd536
KK
12825 }
12826
df694daa 12827 if (board_config != ALC262_AUTO)
e9c364c0 12828 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12829
df694daa
KY
12830 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12831 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12832
df694daa
KY
12833 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12834 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12835
f12ab1e0 12836 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12837 int i;
12838 /* check whether the digital-mic has to be supported */
12839 for (i = 0; i < spec->input_mux->num_items; i++) {
12840 if (spec->input_mux->items[i].index >= 9)
12841 break;
12842 }
12843 if (i < spec->input_mux->num_items) {
12844 /* use only ADC0 */
12845 spec->adc_nids = alc262_dmic_adc_nids;
12846 spec->num_adc_nids = 1;
12847 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12848 } else {
8c927b4a
TI
12849 /* all analog inputs */
12850 /* check whether NID 0x07 is valid */
12851 unsigned int wcap = get_wcaps(codec, 0x07);
12852
12853 /* get type */
a22d543a 12854 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12855 if (wcap != AC_WID_AUD_IN) {
12856 spec->adc_nids = alc262_adc_nids_alt;
12857 spec->num_adc_nids =
12858 ARRAY_SIZE(alc262_adc_nids_alt);
12859 spec->capsrc_nids = alc262_capsrc_nids_alt;
12860 } else {
12861 spec->adc_nids = alc262_adc_nids;
12862 spec->num_adc_nids =
12863 ARRAY_SIZE(alc262_adc_nids);
12864 spec->capsrc_nids = alc262_capsrc_nids;
12865 }
df694daa
KY
12866 }
12867 }
e64f14f4 12868 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12869 set_capture_mixer(codec);
dc1eae25 12870 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12871 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12872
18675e42
TI
12873 if (board_config == ALC262_AUTO)
12874 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0);
12875
2134ea4f
TI
12876 spec->vmaster_nid = 0x0c;
12877
df694daa
KY
12878 codec->patch_ops = alc_patch_ops;
12879 if (board_config == ALC262_AUTO)
ae6b813a 12880 spec->init_hook = alc262_auto_init;
cb53c626
TI
12881#ifdef CONFIG_SND_HDA_POWER_SAVE
12882 if (!spec->loopback.amplist)
12883 spec->loopback.amplist = alc262_loopbacks;
12884#endif
ea1fb29a 12885
df694daa
KY
12886 return 0;
12887}
12888
a361d84b
KY
12889/*
12890 * ALC268 channel source setting (2 channel)
12891 */
12892#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12893#define alc268_modes alc260_modes
ea1fb29a 12894
a361d84b
KY
12895static hda_nid_t alc268_dac_nids[2] = {
12896 /* front, hp */
12897 0x02, 0x03
12898};
12899
12900static hda_nid_t alc268_adc_nids[2] = {
12901 /* ADC0-1 */
12902 0x08, 0x07
12903};
12904
12905static hda_nid_t alc268_adc_nids_alt[1] = {
12906 /* ADC0 */
12907 0x08
12908};
12909
e1406348
TI
12910static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12911
a361d84b
KY
12912static struct snd_kcontrol_new alc268_base_mixer[] = {
12913 /* output mixer control */
12914 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12915 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12918 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12919 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12920 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12921 { }
12922};
12923
42171c17
TI
12924static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12925 /* output mixer control */
12926 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12927 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12928 ALC262_HIPPO_MASTER_SWITCH,
12929 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12930 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12931 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12932 { }
12933};
12934
aef9d318
TI
12935/* bind Beep switches of both NID 0x0f and 0x10 */
12936static struct hda_bind_ctls alc268_bind_beep_sw = {
12937 .ops = &snd_hda_bind_sw,
12938 .values = {
12939 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12940 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12941 0
12942 },
12943};
12944
12945static struct snd_kcontrol_new alc268_beep_mixer[] = {
12946 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12947 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12948 { }
12949};
12950
d1a991a6
KY
12951static struct hda_verb alc268_eapd_verbs[] = {
12952 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12953 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12954 { }
12955};
12956
d273809e 12957/* Toshiba specific */
d273809e
TI
12958static struct hda_verb alc268_toshiba_verbs[] = {
12959 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12960 { } /* end */
12961};
12962
12963/* Acer specific */
889c4395 12964/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12965static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12966 .ops = &snd_hda_bind_vol,
12967 .values = {
12968 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12969 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12970 0
12971 },
12972};
12973
889c4395
TI
12974/* mute/unmute internal speaker according to the hp jack and mute state */
12975static void alc268_acer_automute(struct hda_codec *codec, int force)
12976{
12977 struct alc_spec *spec = codec->spec;
12978 unsigned int mute;
12979
12980 if (force || !spec->sense_updated) {
864f92be 12981 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12982 spec->sense_updated = 1;
12983 }
12984 if (spec->jack_present)
12985 mute = HDA_AMP_MUTE; /* mute internal speaker */
12986 else /* unmute internal speaker if necessary */
12987 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12988 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12989 HDA_AMP_MUTE, mute);
12990}
12991
12992
12993/* bind hp and internal speaker mute (with plug check) */
12994static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12995 struct snd_ctl_elem_value *ucontrol)
12996{
12997 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12998 long *valp = ucontrol->value.integer.value;
12999 int change;
13000
8de56b7d 13001 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13002 if (change)
13003 alc268_acer_automute(codec, 0);
13004 return change;
13005}
d273809e 13006
8ef355da
KY
13007static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13008 /* output mixer control */
13009 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13010 {
13011 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13012 .name = "Master Playback Switch",
5e26dfd0 13013 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13014 .info = snd_hda_mixer_amp_switch_info,
13015 .get = snd_hda_mixer_amp_switch_get,
13016 .put = alc268_acer_master_sw_put,
13017 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13018 },
13019 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13020 { }
13021};
13022
d273809e
TI
13023static struct snd_kcontrol_new alc268_acer_mixer[] = {
13024 /* output mixer control */
13025 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13026 {
13027 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13028 .name = "Master Playback Switch",
5e26dfd0 13029 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13030 .info = snd_hda_mixer_amp_switch_info,
13031 .get = snd_hda_mixer_amp_switch_get,
13032 .put = alc268_acer_master_sw_put,
13033 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13034 },
33bf17ab
TI
13035 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13036 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13037 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
13038 { }
13039};
13040
c238b4f4
TI
13041static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13042 /* output mixer control */
13043 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13044 {
13045 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13046 .name = "Master Playback Switch",
5e26dfd0 13047 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13048 .info = snd_hda_mixer_amp_switch_info,
13049 .get = snd_hda_mixer_amp_switch_get,
13050 .put = alc268_acer_master_sw_put,
13051 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13052 },
13053 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13054 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
13055 { }
13056};
13057
8ef355da
KY
13058static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13059 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13060 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13061 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13062 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13063 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13064 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13065 { }
13066};
13067
d273809e 13068static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13069 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13070 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13072 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13073 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13074 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13075 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13076 { }
13077};
13078
13079/* unsolicited event for HP jack sensing */
42171c17 13080#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13081#define alc268_toshiba_setup alc262_hippo_setup
13082#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13083
13084static void alc268_acer_unsol_event(struct hda_codec *codec,
13085 unsigned int res)
13086{
889c4395 13087 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13088 return;
13089 alc268_acer_automute(codec, 1);
13090}
13091
889c4395
TI
13092static void alc268_acer_init_hook(struct hda_codec *codec)
13093{
13094 alc268_acer_automute(codec, 1);
13095}
13096
8ef355da
KY
13097/* toggle speaker-output according to the hp-jack state */
13098static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13099{
13100 unsigned int present;
13101 unsigned char bits;
13102
864f92be 13103 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13104 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13105 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13106 HDA_AMP_MUTE, bits);
8ef355da 13107 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13108 HDA_AMP_MUTE, bits);
8ef355da
KY
13109}
13110
8ef355da
KY
13111static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13112 unsigned int res)
13113{
4f5d1706
TI
13114 switch (res >> 26) {
13115 case ALC880_HP_EVENT:
8ef355da 13116 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13117 break;
13118 case ALC880_MIC_EVENT:
13119 alc_mic_automute(codec);
13120 break;
13121 }
13122}
13123
13124static void alc268_acer_lc_setup(struct hda_codec *codec)
13125{
13126 struct alc_spec *spec = codec->spec;
13127 spec->ext_mic.pin = 0x18;
13128 spec->ext_mic.mux_idx = 0;
13129 spec->int_mic.pin = 0x12;
13130 spec->int_mic.mux_idx = 6;
13131 spec->auto_mic = 1;
8ef355da
KY
13132}
13133
13134static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13135{
13136 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13137 alc_mic_automute(codec);
8ef355da
KY
13138}
13139
3866f0b0
TI
13140static struct snd_kcontrol_new alc268_dell_mixer[] = {
13141 /* output mixer control */
13142 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13143 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13144 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13145 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13146 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13147 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13148 { }
13149};
13150
13151static struct hda_verb alc268_dell_verbs[] = {
13152 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13153 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13154 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13155 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13156 { }
13157};
13158
13159/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13160static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13161{
a9fd4f3f 13162 struct alc_spec *spec = codec->spec;
3866f0b0 13163
a9fd4f3f
TI
13164 spec->autocfg.hp_pins[0] = 0x15;
13165 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13166 spec->ext_mic.pin = 0x18;
13167 spec->ext_mic.mux_idx = 0;
13168 spec->int_mic.pin = 0x19;
13169 spec->int_mic.mux_idx = 1;
13170 spec->auto_mic = 1;
3866f0b0
TI
13171}
13172
eb5a6621
HRK
13173static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13174 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13175 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13176 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13177 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13178 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13179 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13180 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13181 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13182 { }
13183};
13184
13185static struct hda_verb alc267_quanta_il1_verbs[] = {
13186 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13187 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13188 { }
13189};
13190
4f5d1706 13191static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13192{
a9fd4f3f 13193 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13194 spec->autocfg.hp_pins[0] = 0x15;
13195 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13196 spec->ext_mic.pin = 0x18;
13197 spec->ext_mic.mux_idx = 0;
13198 spec->int_mic.pin = 0x19;
13199 spec->int_mic.mux_idx = 1;
13200 spec->auto_mic = 1;
eb5a6621
HRK
13201}
13202
a361d84b
KY
13203/*
13204 * generic initialization of ADC, input mixers and output mixers
13205 */
13206static struct hda_verb alc268_base_init_verbs[] = {
13207 /* Unmute DAC0-1 and set vol = 0 */
13208 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13209 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13210
13211 /*
13212 * Set up output mixers (0x0c - 0x0e)
13213 */
13214 /* set vol=0 to output mixers */
13215 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13216 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13217
13218 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13219 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13220
13221 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13222 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13223 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13224 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13225 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13226 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13227 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13228 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13229
13230 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13231 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13232 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13233 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13234 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13235
13236 /* set PCBEEP vol = 0, mute connections */
13237 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13238 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13239 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13240
a9b3aa8a 13241 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13242
a9b3aa8a
JZ
13243 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13244 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13245 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13247
a361d84b
KY
13248 { }
13249};
13250
13251/*
13252 * generic initialization of ADC, input mixers and output mixers
13253 */
13254static struct hda_verb alc268_volume_init_verbs[] = {
13255 /* set output DAC */
4cfb91c6
TI
13256 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13257 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13258
13259 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13260 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13261 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13262 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13263 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13264
a361d84b 13265 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13267 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13268
13269 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13270 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13271
aef9d318
TI
13272 /* set PCBEEP vol = 0, mute connections */
13273 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13274 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13275 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13276
13277 { }
13278};
13279
fdbc6626
TI
13280static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13281 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13282 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13283 { } /* end */
13284};
13285
a361d84b
KY
13286static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13287 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13288 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13289 _DEFINE_CAPSRC(1),
a361d84b
KY
13290 { } /* end */
13291};
13292
13293static struct snd_kcontrol_new alc268_capture_mixer[] = {
13294 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13295 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13296 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13297 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13298 _DEFINE_CAPSRC(2),
a361d84b
KY
13299 { } /* end */
13300};
13301
13302static struct hda_input_mux alc268_capture_source = {
13303 .num_items = 4,
13304 .items = {
13305 { "Mic", 0x0 },
13306 { "Front Mic", 0x1 },
13307 { "Line", 0x2 },
13308 { "CD", 0x3 },
13309 },
13310};
13311
0ccb541c 13312static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13313 .num_items = 3,
13314 .items = {
13315 { "Mic", 0x0 },
13316 { "Internal Mic", 0x1 },
13317 { "Line", 0x2 },
13318 },
13319};
13320
13321static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13322 .num_items = 3,
13323 .items = {
13324 { "Mic", 0x0 },
13325 { "Internal Mic", 0x6 },
13326 { "Line", 0x2 },
13327 },
13328};
13329
86c53bd2
JW
13330#ifdef CONFIG_SND_DEBUG
13331static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13332 /* Volume widgets */
13333 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13334 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13335 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13336 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13337 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13338 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13339 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13340 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13341 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13342 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13343 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13344 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13345 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13346 /* The below appears problematic on some hardwares */
13347 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13348 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13349 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13350 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13351 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13352
13353 /* Modes for retasking pin widgets */
13354 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13355 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13356 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13357 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13358
13359 /* Controls for GPIO pins, assuming they are configured as outputs */
13360 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13361 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13362 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13363 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13364
13365 /* Switches to allow the digital SPDIF output pin to be enabled.
13366 * The ALC268 does not have an SPDIF input.
13367 */
13368 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13369
13370 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13371 * this output to turn on an external amplifier.
13372 */
13373 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13374 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13375
13376 { } /* end */
13377};
13378#endif
13379
a361d84b
KY
13380/* create input playback/capture controls for the given pin */
13381static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13382 const char *ctlname, int idx)
13383{
3f3b7c1a 13384 hda_nid_t dac;
a361d84b
KY
13385 int err;
13386
3f3b7c1a
TI
13387 switch (nid) {
13388 case 0x14:
13389 case 0x16:
13390 dac = 0x02;
13391 break;
13392 case 0x15:
b08b1637
TI
13393 case 0x1a: /* ALC259/269 only */
13394 case 0x1b: /* ALC259/269 only */
531d8791 13395 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13396 dac = 0x03;
13397 break;
13398 default:
c7a9434d
TI
13399 snd_printd(KERN_WARNING "hda_codec: "
13400 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13401 return 0;
13402 }
13403 if (spec->multiout.dac_nids[0] != dac &&
13404 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13405 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13406 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13407 HDA_OUTPUT));
13408 if (err < 0)
13409 return err;
3f3b7c1a
TI
13410 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13411 }
13412
3f3b7c1a 13413 if (nid != 0x16)
0afe5f89 13414 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13415 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13416 else /* mono */
0afe5f89 13417 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13418 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13419 if (err < 0)
13420 return err;
13421 return 0;
13422}
13423
13424/* add playback controls from the parsed DAC table */
13425static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13426 const struct auto_pin_cfg *cfg)
13427{
13428 hda_nid_t nid;
13429 int err;
13430
a361d84b 13431 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13432
13433 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13434 if (nid) {
13435 const char *name;
13436 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13437 name = "Speaker";
13438 else
13439 name = "Front";
13440 err = alc268_new_analog_output(spec, nid, name, 0);
13441 if (err < 0)
13442 return err;
13443 }
a361d84b
KY
13444
13445 nid = cfg->speaker_pins[0];
13446 if (nid == 0x1d) {
0afe5f89 13447 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13448 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13449 if (err < 0)
13450 return err;
7bfb9c03 13451 } else if (nid) {
3f3b7c1a
TI
13452 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13453 if (err < 0)
13454 return err;
a361d84b
KY
13455 }
13456 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13457 if (nid) {
13458 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13459 if (err < 0)
13460 return err;
13461 }
a361d84b
KY
13462
13463 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13464 if (nid == 0x16) {
0afe5f89 13465 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13466 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13467 if (err < 0)
13468 return err;
13469 }
ea1fb29a 13470 return 0;
a361d84b
KY
13471}
13472
13473/* create playback/capture controls for input pins */
05f5f477 13474static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13475 const struct auto_pin_cfg *cfg)
13476{
05f5f477 13477 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13478}
13479
e9af4f36
TI
13480static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13481 hda_nid_t nid, int pin_type)
13482{
13483 int idx;
13484
13485 alc_set_pin_output(codec, nid, pin_type);
13486 if (nid == 0x14 || nid == 0x16)
13487 idx = 0;
13488 else
13489 idx = 1;
13490 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13491}
13492
13493static void alc268_auto_init_multi_out(struct hda_codec *codec)
13494{
13495 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13496 int i;
13497
13498 for (i = 0; i < spec->autocfg.line_outs; i++) {
13499 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13500 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13501 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13502 }
13503}
13504
13505static void alc268_auto_init_hp_out(struct hda_codec *codec)
13506{
13507 struct alc_spec *spec = codec->spec;
13508 hda_nid_t pin;
e1ca7b4e 13509 int i;
e9af4f36 13510
e1ca7b4e
TI
13511 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13512 pin = spec->autocfg.hp_pins[i];
e9af4f36 13513 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13514 }
13515 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13516 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13517 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13518 }
13519 if (spec->autocfg.mono_out_pin)
13520 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13521 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13522}
13523
a361d84b
KY
13524static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13525{
13526 struct alc_spec *spec = codec->spec;
13527 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13528 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13529 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13530 unsigned int dac_vol1, dac_vol2;
13531
e9af4f36 13532 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13533 snd_hda_codec_write(codec, speaker_nid, 0,
13534 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13535 /* mute mixer inputs from 0x1d */
a361d84b
KY
13536 snd_hda_codec_write(codec, 0x0f, 0,
13537 AC_VERB_SET_AMP_GAIN_MUTE,
13538 AMP_IN_UNMUTE(1));
13539 snd_hda_codec_write(codec, 0x10, 0,
13540 AC_VERB_SET_AMP_GAIN_MUTE,
13541 AMP_IN_UNMUTE(1));
13542 } else {
e9af4f36 13543 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13544 snd_hda_codec_write(codec, 0x0f, 0,
13545 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13546 snd_hda_codec_write(codec, 0x10, 0,
13547 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13548 }
13549
13550 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13551 if (line_nid == 0x14)
a361d84b
KY
13552 dac_vol2 = AMP_OUT_ZERO;
13553 else if (line_nid == 0x15)
13554 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13555 if (hp_nid == 0x14)
a361d84b
KY
13556 dac_vol2 = AMP_OUT_ZERO;
13557 else if (hp_nid == 0x15)
13558 dac_vol1 = AMP_OUT_ZERO;
13559 if (line_nid != 0x16 || hp_nid != 0x16 ||
13560 spec->autocfg.line_out_pins[1] != 0x16 ||
13561 spec->autocfg.line_out_pins[2] != 0x16)
13562 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13563
13564 snd_hda_codec_write(codec, 0x02, 0,
13565 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13566 snd_hda_codec_write(codec, 0x03, 0,
13567 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13568}
13569
def319f9 13570/* pcm configuration: identical with ALC880 */
a361d84b
KY
13571#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13572#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13573#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13574#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13575
13576/*
13577 * BIOS auto configuration
13578 */
13579static int alc268_parse_auto_config(struct hda_codec *codec)
13580{
13581 struct alc_spec *spec = codec->spec;
13582 int err;
13583 static hda_nid_t alc268_ignore[] = { 0 };
13584
13585 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13586 alc268_ignore);
13587 if (err < 0)
13588 return err;
7e0e44d4
TI
13589 if (!spec->autocfg.line_outs) {
13590 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13591 spec->multiout.max_channels = 2;
13592 spec->no_analog = 1;
13593 goto dig_only;
13594 }
a361d84b 13595 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13596 }
a361d84b
KY
13597 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13598 if (err < 0)
13599 return err;
05f5f477 13600 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13601 if (err < 0)
13602 return err;
13603
13604 spec->multiout.max_channels = 2;
13605
7e0e44d4 13606 dig_only:
a361d84b 13607 /* digital only support output */
757899ac 13608 alc_auto_parse_digital(codec);
603c4019 13609 if (spec->kctls.list)
d88897ea 13610 add_mixer(spec, spec->kctls.list);
a361d84b 13611
892981ff 13612 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13613 add_mixer(spec, alc268_beep_mixer);
aef9d318 13614
d88897ea 13615 add_verb(spec, alc268_volume_init_verbs);
5908589f 13616 spec->num_mux_defs = 2;
61b9b9b1 13617 spec->input_mux = &spec->private_imux[0];
a361d84b 13618
776e184e
TI
13619 err = alc_auto_add_mic_boost(codec);
13620 if (err < 0)
13621 return err;
13622
6227cdce 13623 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13624
a361d84b
KY
13625 return 1;
13626}
13627
a361d84b
KY
13628#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13629
13630/* init callback for auto-configuration model -- overriding the default init */
13631static void alc268_auto_init(struct hda_codec *codec)
13632{
f6c7e546 13633 struct alc_spec *spec = codec->spec;
a361d84b
KY
13634 alc268_auto_init_multi_out(codec);
13635 alc268_auto_init_hp_out(codec);
13636 alc268_auto_init_mono_speaker_out(codec);
13637 alc268_auto_init_analog_input(codec);
757899ac 13638 alc_auto_init_digital(codec);
f6c7e546 13639 if (spec->unsol_event)
7fb0d78f 13640 alc_inithook(codec);
a361d84b
KY
13641}
13642
13643/*
13644 * configuration and preset
13645 */
13646static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13647 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13648 [ALC268_3ST] = "3stack",
983f8ae4 13649 [ALC268_TOSHIBA] = "toshiba",
d273809e 13650 [ALC268_ACER] = "acer",
c238b4f4 13651 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13652 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13653 [ALC268_DELL] = "dell",
f12462c5 13654 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13655#ifdef CONFIG_SND_DEBUG
13656 [ALC268_TEST] = "test",
13657#endif
a361d84b
KY
13658 [ALC268_AUTO] = "auto",
13659};
13660
13661static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13662 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13663 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13664 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13665 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13666 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13667 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13668 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13669 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13670 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13671 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13672 /* almost compatible with toshiba but with optional digital outs;
13673 * auto-probing seems working fine
13674 */
8871e5b9 13675 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13676 ALC268_AUTO),
a361d84b 13677 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13678 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13679 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13680 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13681 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13682 {}
13683};
13684
3abf2f36
TI
13685/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13686static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13687 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13688 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13689 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13690 ALC268_TOSHIBA),
13691 {}
13692};
13693
a361d84b 13694static struct alc_config_preset alc268_presets[] = {
eb5a6621 13695 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13696 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13697 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13698 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13699 alc267_quanta_il1_verbs },
13700 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13701 .dac_nids = alc268_dac_nids,
13702 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13703 .adc_nids = alc268_adc_nids_alt,
13704 .hp_nid = 0x03,
13705 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13706 .channel_mode = alc268_modes,
4f5d1706
TI
13707 .unsol_event = alc_sku_unsol_event,
13708 .setup = alc267_quanta_il1_setup,
13709 .init_hook = alc_inithook,
eb5a6621 13710 },
a361d84b 13711 [ALC268_3ST] = {
aef9d318
TI
13712 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13713 alc268_beep_mixer },
a361d84b
KY
13714 .init_verbs = { alc268_base_init_verbs },
13715 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13716 .dac_nids = alc268_dac_nids,
13717 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13718 .adc_nids = alc268_adc_nids_alt,
e1406348 13719 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13720 .hp_nid = 0x03,
13721 .dig_out_nid = ALC268_DIGOUT_NID,
13722 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13723 .channel_mode = alc268_modes,
13724 .input_mux = &alc268_capture_source,
13725 },
d1a991a6 13726 [ALC268_TOSHIBA] = {
42171c17 13727 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13728 alc268_beep_mixer },
d273809e
TI
13729 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13730 alc268_toshiba_verbs },
d1a991a6
KY
13731 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13732 .dac_nids = alc268_dac_nids,
13733 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13734 .adc_nids = alc268_adc_nids_alt,
e1406348 13735 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13736 .hp_nid = 0x03,
13737 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13738 .channel_mode = alc268_modes,
13739 .input_mux = &alc268_capture_source,
d273809e 13740 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13741 .setup = alc268_toshiba_setup,
13742 .init_hook = alc268_toshiba_automute,
d273809e
TI
13743 },
13744 [ALC268_ACER] = {
432fd133 13745 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13746 alc268_beep_mixer },
d273809e
TI
13747 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13748 alc268_acer_verbs },
13749 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13750 .dac_nids = alc268_dac_nids,
13751 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13752 .adc_nids = alc268_adc_nids_alt,
e1406348 13753 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13754 .hp_nid = 0x02,
13755 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13756 .channel_mode = alc268_modes,
0ccb541c 13757 .input_mux = &alc268_acer_capture_source,
d273809e 13758 .unsol_event = alc268_acer_unsol_event,
889c4395 13759 .init_hook = alc268_acer_init_hook,
d1a991a6 13760 },
c238b4f4
TI
13761 [ALC268_ACER_DMIC] = {
13762 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13763 alc268_beep_mixer },
13764 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13765 alc268_acer_verbs },
13766 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13767 .dac_nids = alc268_dac_nids,
13768 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13769 .adc_nids = alc268_adc_nids_alt,
13770 .capsrc_nids = alc268_capsrc_nids,
13771 .hp_nid = 0x02,
13772 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13773 .channel_mode = alc268_modes,
13774 .input_mux = &alc268_acer_dmic_capture_source,
13775 .unsol_event = alc268_acer_unsol_event,
13776 .init_hook = alc268_acer_init_hook,
13777 },
8ef355da
KY
13778 [ALC268_ACER_ASPIRE_ONE] = {
13779 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13780 alc268_beep_mixer,
fdbc6626 13781 alc268_capture_nosrc_mixer },
8ef355da
KY
13782 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13783 alc268_acer_aspire_one_verbs },
13784 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13785 .dac_nids = alc268_dac_nids,
13786 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13787 .adc_nids = alc268_adc_nids_alt,
13788 .capsrc_nids = alc268_capsrc_nids,
13789 .hp_nid = 0x03,
13790 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13791 .channel_mode = alc268_modes,
8ef355da 13792 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13793 .setup = alc268_acer_lc_setup,
8ef355da
KY
13794 .init_hook = alc268_acer_lc_init_hook,
13795 },
3866f0b0 13796 [ALC268_DELL] = {
fdbc6626
TI
13797 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13798 alc268_capture_nosrc_mixer },
3866f0b0
TI
13799 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13800 alc268_dell_verbs },
13801 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13802 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13803 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13804 .adc_nids = alc268_adc_nids_alt,
13805 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13806 .hp_nid = 0x02,
13807 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13808 .channel_mode = alc268_modes,
a9fd4f3f 13809 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13810 .setup = alc268_dell_setup,
13811 .init_hook = alc_inithook,
3866f0b0 13812 },
f12462c5 13813 [ALC268_ZEPTO] = {
aef9d318
TI
13814 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13815 alc268_beep_mixer },
f12462c5
MT
13816 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13817 alc268_toshiba_verbs },
13818 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13819 .dac_nids = alc268_dac_nids,
13820 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13821 .adc_nids = alc268_adc_nids_alt,
e1406348 13822 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13823 .hp_nid = 0x03,
13824 .dig_out_nid = ALC268_DIGOUT_NID,
13825 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13826 .channel_mode = alc268_modes,
13827 .input_mux = &alc268_capture_source,
4f5d1706
TI
13828 .setup = alc268_toshiba_setup,
13829 .init_hook = alc268_toshiba_automute,
f12462c5 13830 },
86c53bd2
JW
13831#ifdef CONFIG_SND_DEBUG
13832 [ALC268_TEST] = {
13833 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13834 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13835 alc268_volume_init_verbs },
13836 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13837 .dac_nids = alc268_dac_nids,
13838 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13839 .adc_nids = alc268_adc_nids_alt,
e1406348 13840 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13841 .hp_nid = 0x03,
13842 .dig_out_nid = ALC268_DIGOUT_NID,
13843 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13844 .channel_mode = alc268_modes,
13845 .input_mux = &alc268_capture_source,
13846 },
13847#endif
a361d84b
KY
13848};
13849
13850static int patch_alc268(struct hda_codec *codec)
13851{
13852 struct alc_spec *spec;
13853 int board_config;
22971e3a 13854 int i, has_beep, err;
a361d84b 13855
ef86f581 13856 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13857 if (spec == NULL)
13858 return -ENOMEM;
13859
13860 codec->spec = spec;
13861
13862 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13863 alc268_models,
13864 alc268_cfg_tbl);
13865
3abf2f36
TI
13866 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13867 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13868 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13869
a361d84b 13870 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13871 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13872 codec->chip_name);
a361d84b
KY
13873 board_config = ALC268_AUTO;
13874 }
13875
13876 if (board_config == ALC268_AUTO) {
13877 /* automatic parse from the BIOS config */
13878 err = alc268_parse_auto_config(codec);
13879 if (err < 0) {
13880 alc_free(codec);
13881 return err;
13882 } else if (!err) {
13883 printk(KERN_INFO
13884 "hda_codec: Cannot set up configuration "
13885 "from BIOS. Using base mode...\n");
13886 board_config = ALC268_3ST;
13887 }
13888 }
13889
13890 if (board_config != ALC268_AUTO)
e9c364c0 13891 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13892
a361d84b
KY
13893 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13894 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13895 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13896
a361d84b
KY
13897 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13898
22971e3a
TI
13899 has_beep = 0;
13900 for (i = 0; i < spec->num_mixers; i++) {
13901 if (spec->mixers[i] == alc268_beep_mixer) {
13902 has_beep = 1;
13903 break;
13904 }
13905 }
13906
13907 if (has_beep) {
13908 err = snd_hda_attach_beep_device(codec, 0x1);
13909 if (err < 0) {
13910 alc_free(codec);
13911 return err;
13912 }
13913 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13914 /* override the amp caps for beep generator */
13915 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13916 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13917 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13918 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13919 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13920 }
aef9d318 13921
7e0e44d4 13922 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13923 /* check whether NID 0x07 is valid */
13924 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13925 int i;
3866f0b0 13926
defb5ab2 13927 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13928 /* get type */
a22d543a 13929 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13930 if (spec->auto_mic ||
13931 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13932 spec->adc_nids = alc268_adc_nids_alt;
13933 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13934 if (spec->auto_mic)
13935 fixup_automic_adc(codec);
fdbc6626
TI
13936 if (spec->auto_mic || spec->input_mux->num_items == 1)
13937 add_mixer(spec, alc268_capture_nosrc_mixer);
13938 else
13939 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13940 } else {
13941 spec->adc_nids = alc268_adc_nids;
13942 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13943 add_mixer(spec, alc268_capture_mixer);
a361d84b 13944 }
85860c06
TI
13945 /* set default input source */
13946 for (i = 0; i < spec->num_adc_nids; i++)
13947 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13948 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13949 i < spec->num_mux_defs ?
13950 spec->input_mux[i].items[0].index :
85860c06 13951 spec->input_mux->items[0].index);
a361d84b 13952 }
2134ea4f
TI
13953
13954 spec->vmaster_nid = 0x02;
13955
a361d84b
KY
13956 codec->patch_ops = alc_patch_ops;
13957 if (board_config == ALC268_AUTO)
13958 spec->init_hook = alc268_auto_init;
ea1fb29a 13959
a361d84b
KY
13960 return 0;
13961}
13962
f6a92248
KY
13963/*
13964 * ALC269 channel source setting (2 channel)
13965 */
13966#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13967
13968#define alc269_dac_nids alc260_dac_nids
13969
13970static hda_nid_t alc269_adc_nids[1] = {
13971 /* ADC1 */
f53281e6
KY
13972 0x08,
13973};
13974
e01bf509
TI
13975static hda_nid_t alc269_capsrc_nids[1] = {
13976 0x23,
13977};
13978
84898e87
KY
13979static hda_nid_t alc269vb_adc_nids[1] = {
13980 /* ADC1 */
13981 0x09,
13982};
13983
13984static hda_nid_t alc269vb_capsrc_nids[1] = {
13985 0x22,
13986};
13987
6694635d
TI
13988static hda_nid_t alc269_adc_candidates[] = {
13989 0x08, 0x09, 0x07,
13990};
e01bf509 13991
f6a92248
KY
13992#define alc269_modes alc260_modes
13993#define alc269_capture_source alc880_lg_lw_capture_source
13994
13995static struct snd_kcontrol_new alc269_base_mixer[] = {
13996 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13997 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14002 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14003 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14004 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14005 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14006 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14007 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14008 { } /* end */
14009};
14010
60db6b53
KY
14011static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14012 /* output mixer control */
14013 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14014 {
14015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14016 .name = "Master Playback Switch",
5e26dfd0 14017 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14018 .info = snd_hda_mixer_amp_switch_info,
14019 .get = snd_hda_mixer_amp_switch_get,
14020 .put = alc268_acer_master_sw_put,
14021 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14022 },
14023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14024 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14025 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14026 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14027 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14028 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
14029 { }
14030};
14031
64154835
TV
14032static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14033 /* output mixer control */
14034 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14035 {
14036 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14037 .name = "Master Playback Switch",
5e26dfd0 14038 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14039 .info = snd_hda_mixer_amp_switch_info,
14040 .get = snd_hda_mixer_amp_switch_get,
14041 .put = alc268_acer_master_sw_put,
14042 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14043 },
14044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14046 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14047 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14048 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14049 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
14050 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14051 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14052 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
14053 { }
14054};
14055
84898e87 14056static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14057 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14058 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14060 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14061 { } /* end */
14062};
14063
84898e87
KY
14064static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14065 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14066 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14068 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14069 { } /* end */
14070};
14071
fe3eb0a7
KY
14072static struct snd_kcontrol_new alc269_asus_mixer[] = {
14073 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14074 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14075 { } /* end */
14076};
14077
f53281e6 14078/* capture mixer elements */
84898e87
KY
14079static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14080 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14081 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14082 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14083 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
14084 { } /* end */
14085};
14086
14087static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14088 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14089 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
14090 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14091 { } /* end */
14092};
14093
84898e87
KY
14094static struct snd_kcontrol_new alc269vb_laptop_analog_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 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
14099 { } /* end */
14100};
14101
14102static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14103 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14104 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14105 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14106 { } /* end */
14107};
14108
26f5df26 14109/* FSC amilo */
84898e87 14110#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14111
60db6b53
KY
14112static struct hda_verb alc269_quanta_fl1_verbs[] = {
14113 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14114 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14116 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14117 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14118 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14119 { }
14120};
f6a92248 14121
64154835
TV
14122static struct hda_verb alc269_lifebook_verbs[] = {
14123 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14124 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14125 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14126 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14127 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14128 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14129 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14130 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14131 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14132 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14133 { }
14134};
14135
60db6b53
KY
14136/* toggle speaker-output according to the hp-jack state */
14137static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14138{
14139 unsigned int present;
14140 unsigned char bits;
f6a92248 14141
864f92be 14142 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14143 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14144 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14145 HDA_AMP_MUTE, bits);
60db6b53 14146 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14147 HDA_AMP_MUTE, bits);
f6a92248 14148
60db6b53
KY
14149 snd_hda_codec_write(codec, 0x20, 0,
14150 AC_VERB_SET_COEF_INDEX, 0x0c);
14151 snd_hda_codec_write(codec, 0x20, 0,
14152 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14153
60db6b53
KY
14154 snd_hda_codec_write(codec, 0x20, 0,
14155 AC_VERB_SET_COEF_INDEX, 0x0c);
14156 snd_hda_codec_write(codec, 0x20, 0,
14157 AC_VERB_SET_PROC_COEF, 0x480);
14158}
f6a92248 14159
64154835
TV
14160/* toggle speaker-output according to the hp-jacks state */
14161static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14162{
14163 unsigned int present;
14164 unsigned char bits;
14165
14166 /* Check laptop headphone socket */
864f92be 14167 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14168
14169 /* Check port replicator headphone socket */
864f92be 14170 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14171
5dbd5ec6 14172 bits = present ? HDA_AMP_MUTE : 0;
64154835 14173 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14174 HDA_AMP_MUTE, bits);
64154835 14175 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14176 HDA_AMP_MUTE, bits);
64154835
TV
14177
14178 snd_hda_codec_write(codec, 0x20, 0,
14179 AC_VERB_SET_COEF_INDEX, 0x0c);
14180 snd_hda_codec_write(codec, 0x20, 0,
14181 AC_VERB_SET_PROC_COEF, 0x680);
14182
14183 snd_hda_codec_write(codec, 0x20, 0,
14184 AC_VERB_SET_COEF_INDEX, 0x0c);
14185 snd_hda_codec_write(codec, 0x20, 0,
14186 AC_VERB_SET_PROC_COEF, 0x480);
14187}
14188
64154835
TV
14189static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14190{
14191 unsigned int present_laptop;
14192 unsigned int present_dock;
14193
864f92be
WF
14194 present_laptop = snd_hda_jack_detect(codec, 0x18);
14195 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14196
14197 /* Laptop mic port overrides dock mic port, design decision */
14198 if (present_dock)
14199 snd_hda_codec_write(codec, 0x23, 0,
14200 AC_VERB_SET_CONNECT_SEL, 0x3);
14201 if (present_laptop)
14202 snd_hda_codec_write(codec, 0x23, 0,
14203 AC_VERB_SET_CONNECT_SEL, 0x0);
14204 if (!present_dock && !present_laptop)
14205 snd_hda_codec_write(codec, 0x23, 0,
14206 AC_VERB_SET_CONNECT_SEL, 0x1);
14207}
14208
60db6b53
KY
14209static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14210 unsigned int res)
14211{
4f5d1706
TI
14212 switch (res >> 26) {
14213 case ALC880_HP_EVENT:
60db6b53 14214 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14215 break;
14216 case ALC880_MIC_EVENT:
14217 alc_mic_automute(codec);
14218 break;
14219 }
60db6b53 14220}
f6a92248 14221
64154835
TV
14222static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14223 unsigned int res)
14224{
14225 if ((res >> 26) == ALC880_HP_EVENT)
14226 alc269_lifebook_speaker_automute(codec);
14227 if ((res >> 26) == ALC880_MIC_EVENT)
14228 alc269_lifebook_mic_autoswitch(codec);
14229}
14230
4f5d1706
TI
14231static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14232{
14233 struct alc_spec *spec = codec->spec;
20645d70
TI
14234 spec->autocfg.hp_pins[0] = 0x15;
14235 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14236 spec->ext_mic.pin = 0x18;
14237 spec->ext_mic.mux_idx = 0;
14238 spec->int_mic.pin = 0x19;
14239 spec->int_mic.mux_idx = 1;
14240 spec->auto_mic = 1;
14241}
14242
60db6b53
KY
14243static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14244{
14245 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14246 alc_mic_automute(codec);
60db6b53 14247}
f6a92248 14248
64154835
TV
14249static void alc269_lifebook_init_hook(struct hda_codec *codec)
14250{
14251 alc269_lifebook_speaker_automute(codec);
14252 alc269_lifebook_mic_autoswitch(codec);
14253}
14254
84898e87 14255static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14256 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14257 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14258 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14259 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14260 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14261 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14262 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14263 {}
14264};
14265
84898e87 14266static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14268 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14269 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14270 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14271 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14272 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14273 {}
14274};
14275
84898e87
KY
14276static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14277 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14278 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14279 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14280 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14281 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14282 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14283 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14284 {}
14285};
14286
14287static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14288 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14289 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14290 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14292 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14293 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14294 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14295 {}
14296};
14297
fe3eb0a7
KY
14298static struct hda_verb alc271_acer_dmic_verbs[] = {
14299 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14300 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14301 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14303 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14304 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14305 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14306 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14307 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14308 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14309 { }
14310};
14311
f53281e6
KY
14312/* toggle speaker-output according to the hp-jack state */
14313static void alc269_speaker_automute(struct hda_codec *codec)
14314{
ebb83eeb
KY
14315 struct alc_spec *spec = codec->spec;
14316 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14317 unsigned int present;
60db6b53 14318 unsigned char bits;
f53281e6 14319
ebb83eeb 14320 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14321 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14322 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14323 HDA_AMP_MUTE, bits);
f53281e6 14324 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14325 HDA_AMP_MUTE, bits);
f53281e6
KY
14326}
14327
f53281e6 14328/* unsolicited event for HP jack sensing */
84898e87 14329static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14330 unsigned int res)
f53281e6 14331{
4f5d1706
TI
14332 switch (res >> 26) {
14333 case ALC880_HP_EVENT:
f53281e6 14334 alc269_speaker_automute(codec);
4f5d1706
TI
14335 break;
14336 case ALC880_MIC_EVENT:
14337 alc_mic_automute(codec);
14338 break;
14339 }
f53281e6
KY
14340}
14341
226b1ec8 14342static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14343{
4f5d1706 14344 struct alc_spec *spec = codec->spec;
20645d70
TI
14345 spec->autocfg.hp_pins[0] = 0x15;
14346 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14347 spec->ext_mic.pin = 0x18;
14348 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14349 spec->int_mic.pin = 0x19;
14350 spec->int_mic.mux_idx = 1;
4f5d1706 14351 spec->auto_mic = 1;
f53281e6
KY
14352}
14353
226b1ec8 14354static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14355{
14356 struct alc_spec *spec = codec->spec;
20645d70
TI
14357 spec->autocfg.hp_pins[0] = 0x15;
14358 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14359 spec->ext_mic.pin = 0x18;
14360 spec->ext_mic.mux_idx = 0;
14361 spec->int_mic.pin = 0x12;
226b1ec8 14362 spec->int_mic.mux_idx = 5;
84898e87
KY
14363 spec->auto_mic = 1;
14364}
14365
226b1ec8 14366static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14367{
4f5d1706 14368 struct alc_spec *spec = codec->spec;
226b1ec8 14369 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14370 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14371 spec->ext_mic.pin = 0x18;
14372 spec->ext_mic.mux_idx = 0;
14373 spec->int_mic.pin = 0x19;
14374 spec->int_mic.mux_idx = 1;
14375 spec->auto_mic = 1;
f53281e6
KY
14376}
14377
226b1ec8
KY
14378static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14379{
14380 struct alc_spec *spec = codec->spec;
14381 spec->autocfg.hp_pins[0] = 0x21;
14382 spec->autocfg.speaker_pins[0] = 0x14;
14383 spec->ext_mic.pin = 0x18;
14384 spec->ext_mic.mux_idx = 0;
14385 spec->int_mic.pin = 0x12;
14386 spec->int_mic.mux_idx = 6;
14387 spec->auto_mic = 1;
14388}
14389
84898e87 14390static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14391{
14392 alc269_speaker_automute(codec);
4f5d1706 14393 alc_mic_automute(codec);
f53281e6
KY
14394}
14395
60db6b53
KY
14396/*
14397 * generic initialization of ADC, input mixers and output mixers
14398 */
14399static struct hda_verb alc269_init_verbs[] = {
14400 /*
14401 * Unmute ADC0 and set the default input to mic-in
14402 */
84898e87 14403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14404
14405 /*
84898e87 14406 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14407 */
14408 /* set vol=0 to output mixers */
14409 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14410 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14411
14412 /* set up input amps for analog loopback */
14413 /* Amp Indices: DAC = 0, mixer = 1 */
14414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14420
14421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14427 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14428
14429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14431
84898e87
KY
14432 /* FIXME: use Mux-type input source selection */
14433 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14434 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14435 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14436
84898e87
KY
14437 /* set EAPD */
14438 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14439 { }
14440};
14441
14442static struct hda_verb alc269vb_init_verbs[] = {
14443 /*
14444 * Unmute ADC0 and set the default input to mic-in
14445 */
14446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14447
14448 /*
14449 * Set up output mixers (0x02 - 0x03)
14450 */
14451 /* set vol=0 to output mixers */
14452 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14453 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14454
14455 /* set up input amps for analog loopback */
14456 /* Amp Indices: DAC = 0, mixer = 1 */
14457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14463
14464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14465 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14467 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14471
14472 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14473 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14474
14475 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14476 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14477 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14478 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14479
14480 /* set EAPD */
14481 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14482 { }
14483};
14484
9d0b71b1
TI
14485#define alc269_auto_create_multi_out_ctls \
14486 alc268_auto_create_multi_out_ctls
05f5f477
TI
14487#define alc269_auto_create_input_ctls \
14488 alc268_auto_create_input_ctls
f6a92248
KY
14489
14490#ifdef CONFIG_SND_HDA_POWER_SAVE
14491#define alc269_loopbacks alc880_loopbacks
14492#endif
14493
def319f9 14494/* pcm configuration: identical with ALC880 */
f6a92248
KY
14495#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14496#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14497#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14498#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14499
f03d3115
TI
14500static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14501 .substreams = 1,
14502 .channels_min = 2,
14503 .channels_max = 8,
14504 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14505 /* NID is set in alc_build_pcms */
14506 .ops = {
14507 .open = alc880_playback_pcm_open,
14508 .prepare = alc880_playback_pcm_prepare,
14509 .cleanup = alc880_playback_pcm_cleanup
14510 },
14511};
14512
14513static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14514 .substreams = 1,
14515 .channels_min = 2,
14516 .channels_max = 2,
14517 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14518 /* NID is set in alc_build_pcms */
14519};
14520
ad35879a
TI
14521#ifdef CONFIG_SND_HDA_POWER_SAVE
14522static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14523{
14524 switch (codec->subsystem_id) {
14525 case 0x103c1586:
14526 return 1;
14527 }
14528 return 0;
14529}
14530
14531static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14532{
14533 /* update mute-LED according to the speaker mute state */
14534 if (nid == 0x01 || nid == 0x14) {
14535 int pinval;
14536 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14537 HDA_AMP_MUTE)
14538 pinval = 0x24;
14539 else
14540 pinval = 0x20;
14541 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14542 snd_hda_codec_update_cache(codec, 0x19, 0,
14543 AC_VERB_SET_PIN_WIDGET_CONTROL,
14544 pinval);
ad35879a
TI
14545 }
14546 return alc_check_power_status(codec, nid);
14547}
14548#endif /* CONFIG_SND_HDA_POWER_SAVE */
14549
840b64c0
TI
14550static int alc275_setup_dual_adc(struct hda_codec *codec)
14551{
14552 struct alc_spec *spec = codec->spec;
14553
14554 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14555 return 0;
14556 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14557 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14558 if (spec->ext_mic.pin <= 0x12) {
14559 spec->private_adc_nids[0] = 0x08;
14560 spec->private_adc_nids[1] = 0x11;
14561 spec->private_capsrc_nids[0] = 0x23;
14562 spec->private_capsrc_nids[1] = 0x22;
14563 } else {
14564 spec->private_adc_nids[0] = 0x11;
14565 spec->private_adc_nids[1] = 0x08;
14566 spec->private_capsrc_nids[0] = 0x22;
14567 spec->private_capsrc_nids[1] = 0x23;
14568 }
14569 spec->adc_nids = spec->private_adc_nids;
14570 spec->capsrc_nids = spec->private_capsrc_nids;
14571 spec->num_adc_nids = 2;
14572 spec->dual_adc_switch = 1;
14573 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14574 spec->adc_nids[0], spec->adc_nids[1]);
14575 return 1;
14576 }
14577 return 0;
14578}
14579
d433a678
TI
14580/* different alc269-variants */
14581enum {
14582 ALC269_TYPE_NORMAL,
14583 ALC269_TYPE_ALC259,
14584 ALC269_TYPE_ALC271X,
14585};
14586
f6a92248
KY
14587/*
14588 * BIOS auto configuration
14589 */
14590static int alc269_parse_auto_config(struct hda_codec *codec)
14591{
14592 struct alc_spec *spec = codec->spec;
cfb9fb55 14593 int err;
f6a92248
KY
14594 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14595
14596 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14597 alc269_ignore);
14598 if (err < 0)
14599 return err;
14600
14601 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14602 if (err < 0)
14603 return err;
f3550d1b
TI
14604 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14605 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14606 else
14607 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14608 0x22, 0);
f6a92248
KY
14609 if (err < 0)
14610 return err;
14611
14612 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14613
757899ac 14614 alc_auto_parse_digital(codec);
f6a92248 14615
603c4019 14616 if (spec->kctls.list)
d88897ea 14617 add_mixer(spec, spec->kctls.list);
f6a92248 14618
d433a678 14619 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14620 add_verb(spec, alc269vb_init_verbs);
6227cdce 14621 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14622 } else {
14623 add_verb(spec, alc269_init_verbs);
6227cdce 14624 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14625 }
14626
f6a92248 14627 spec->num_mux_defs = 1;
61b9b9b1 14628 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14629
14630 if (!alc275_setup_dual_adc(codec))
14631 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14632 sizeof(alc269_adc_candidates));
6694635d 14633
e01bf509 14634 /* set default input source */
840b64c0 14635 if (!spec->dual_adc_switch)
748cce43
TI
14636 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14637 spec->input_mux->items[0].index);
f6a92248
KY
14638
14639 err = alc_auto_add_mic_boost(codec);
14640 if (err < 0)
14641 return err;
14642
7e0e44d4 14643 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14644 set_capture_mixer(codec);
f53281e6 14645
f6a92248
KY
14646 return 1;
14647}
14648
e9af4f36
TI
14649#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14650#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14651#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14652
14653
14654/* init callback for auto-configuration model -- overriding the default init */
14655static void alc269_auto_init(struct hda_codec *codec)
14656{
f6c7e546 14657 struct alc_spec *spec = codec->spec;
f6a92248
KY
14658 alc269_auto_init_multi_out(codec);
14659 alc269_auto_init_hp_out(codec);
14660 alc269_auto_init_analog_input(codec);
757899ac 14661 alc_auto_init_digital(codec);
9ad0e496 14662 alc_init_jacks(codec);
f6c7e546 14663 if (spec->unsol_event)
7fb0d78f 14664 alc_inithook(codec);
f6a92248
KY
14665}
14666
0ec33d1f
TI
14667#ifdef SND_HDA_NEEDS_RESUME
14668static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14669{
14670 int val = alc_read_coef_idx(codec, 0x04);
14671 if (power_up)
14672 val |= 1 << 11;
14673 else
14674 val &= ~(1 << 11);
14675 alc_write_coef_idx(codec, 0x04, val);
14676}
14677
977ddd6b
KY
14678#ifdef CONFIG_SND_HDA_POWER_SAVE
14679static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14680{
14681 struct alc_spec *spec = codec->spec;
977ddd6b 14682
0ec33d1f
TI
14683 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14684 alc269_toggle_power_output(codec, 0);
977ddd6b 14685 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14686 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14687 msleep(150);
14688 }
14689
14690 alc_shutup(codec);
14691 if (spec && spec->power_hook)
14692 spec->power_hook(codec);
14693 return 0;
14694}
0ec33d1f
TI
14695#endif /* CONFIG_SND_HDA_POWER_SAVE */
14696
977ddd6b
KY
14697static int alc269_resume(struct hda_codec *codec)
14698{
977ddd6b 14699 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14700 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14701 msleep(150);
14702 }
14703
14704 codec->patch_ops.init(codec);
14705
14706 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14707 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14708 msleep(200);
14709 }
14710
0ec33d1f
TI
14711 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14712 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14713
14714 snd_hda_codec_resume_amp(codec);
14715 snd_hda_codec_resume_cache(codec);
9e5341b9 14716 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14717 return 0;
14718}
0ec33d1f 14719#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14720
ff818c24
TI
14721enum {
14722 ALC269_FIXUP_SONY_VAIO,
145a902b 14723 ALC269_FIXUP_DELL_M101Z,
ff818c24
TI
14724};
14725
ff818c24
TI
14726static const struct alc_fixup alc269_fixups[] = {
14727 [ALC269_FIXUP_SONY_VAIO] = {
73413b12
TI
14728 .verbs = (const struct hda_verb[]) {
14729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14730 {}
14731 }
ff818c24 14732 },
145a902b
DH
14733 [ALC269_FIXUP_DELL_M101Z] = {
14734 .verbs = (const struct hda_verb[]) {
14735 /* Enables internal speaker */
14736 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14737 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14738 {}
14739 }
14740 },
ff818c24
TI
14741};
14742
14743static struct snd_pci_quirk alc269_fixup_tbl[] = {
abdd8f51 14744 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14745 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
ff818c24
TI
14746 {}
14747};
14748
14749
f6a92248
KY
14750/*
14751 * configuration and preset
14752 */
14753static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14754 [ALC269_BASIC] = "basic",
2922c9af 14755 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14756 [ALC269_AMIC] = "laptop-amic",
14757 [ALC269_DMIC] = "laptop-dmic",
64154835 14758 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14759 [ALC269_LIFEBOOK] = "lifebook",
14760 [ALC269_AUTO] = "auto",
f6a92248
KY
14761};
14762
14763static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14764 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14765 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14766 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14767 ALC269_AMIC),
14768 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14769 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14770 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14771 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14772 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14773 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14774 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14775 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14776 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14777 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14778 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14779 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14780 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14781 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14782 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14783 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14784 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14785 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14786 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14787 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14788 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14789 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14790 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14791 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14792 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14793 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14794 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14795 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14796 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14797 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14798 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14799 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14800 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14801 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14802 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14803 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14804 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14805 ALC269_DMIC),
60db6b53 14806 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14807 ALC269_DMIC),
14808 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14809 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14810 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14811 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14812 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14813 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14814 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14815 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14816 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14817 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14818 {}
14819};
14820
14821static struct alc_config_preset alc269_presets[] = {
14822 [ALC269_BASIC] = {
f9e336f6 14823 .mixers = { alc269_base_mixer },
f6a92248
KY
14824 .init_verbs = { alc269_init_verbs },
14825 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14826 .dac_nids = alc269_dac_nids,
14827 .hp_nid = 0x03,
14828 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14829 .channel_mode = alc269_modes,
14830 .input_mux = &alc269_capture_source,
14831 },
60db6b53
KY
14832 [ALC269_QUANTA_FL1] = {
14833 .mixers = { alc269_quanta_fl1_mixer },
14834 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14835 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14836 .dac_nids = alc269_dac_nids,
14837 .hp_nid = 0x03,
14838 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14839 .channel_mode = alc269_modes,
14840 .input_mux = &alc269_capture_source,
14841 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14842 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14843 .init_hook = alc269_quanta_fl1_init_hook,
14844 },
84898e87
KY
14845 [ALC269_AMIC] = {
14846 .mixers = { alc269_laptop_mixer },
14847 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14848 .init_verbs = { alc269_init_verbs,
84898e87 14849 alc269_laptop_amic_init_verbs },
f53281e6
KY
14850 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14851 .dac_nids = alc269_dac_nids,
14852 .hp_nid = 0x03,
14853 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14854 .channel_mode = alc269_modes,
84898e87
KY
14855 .unsol_event = alc269_laptop_unsol_event,
14856 .setup = alc269_laptop_amic_setup,
14857 .init_hook = alc269_laptop_inithook,
f53281e6 14858 },
84898e87
KY
14859 [ALC269_DMIC] = {
14860 .mixers = { alc269_laptop_mixer },
14861 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14862 .init_verbs = { alc269_init_verbs,
84898e87
KY
14863 alc269_laptop_dmic_init_verbs },
14864 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14865 .dac_nids = alc269_dac_nids,
14866 .hp_nid = 0x03,
14867 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14868 .channel_mode = alc269_modes,
14869 .unsol_event = alc269_laptop_unsol_event,
14870 .setup = alc269_laptop_dmic_setup,
14871 .init_hook = alc269_laptop_inithook,
14872 },
14873 [ALC269VB_AMIC] = {
14874 .mixers = { alc269vb_laptop_mixer },
14875 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14876 .init_verbs = { alc269vb_init_verbs,
14877 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14878 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14879 .dac_nids = alc269_dac_nids,
14880 .hp_nid = 0x03,
14881 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14882 .channel_mode = alc269_modes,
84898e87 14883 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 14884 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
14885 .init_hook = alc269_laptop_inithook,
14886 },
14887 [ALC269VB_DMIC] = {
14888 .mixers = { alc269vb_laptop_mixer },
14889 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14890 .init_verbs = { alc269vb_init_verbs,
14891 alc269vb_laptop_dmic_init_verbs },
14892 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14893 .dac_nids = alc269_dac_nids,
14894 .hp_nid = 0x03,
14895 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14896 .channel_mode = alc269_modes,
14897 .unsol_event = alc269_laptop_unsol_event,
14898 .setup = alc269vb_laptop_dmic_setup,
14899 .init_hook = alc269_laptop_inithook,
f53281e6 14900 },
26f5df26 14901 [ALC269_FUJITSU] = {
45bdd1c1 14902 .mixers = { alc269_fujitsu_mixer },
84898e87 14903 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14904 .init_verbs = { alc269_init_verbs,
84898e87 14905 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14906 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14907 .dac_nids = alc269_dac_nids,
14908 .hp_nid = 0x03,
14909 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14910 .channel_mode = alc269_modes,
84898e87
KY
14911 .unsol_event = alc269_laptop_unsol_event,
14912 .setup = alc269_laptop_dmic_setup,
14913 .init_hook = alc269_laptop_inithook,
26f5df26 14914 },
64154835
TV
14915 [ALC269_LIFEBOOK] = {
14916 .mixers = { alc269_lifebook_mixer },
14917 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14918 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14919 .dac_nids = alc269_dac_nids,
14920 .hp_nid = 0x03,
14921 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14922 .channel_mode = alc269_modes,
14923 .input_mux = &alc269_capture_source,
14924 .unsol_event = alc269_lifebook_unsol_event,
14925 .init_hook = alc269_lifebook_init_hook,
14926 },
fe3eb0a7
KY
14927 [ALC271_ACER] = {
14928 .mixers = { alc269_asus_mixer },
14929 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14930 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14931 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14932 .dac_nids = alc269_dac_nids,
14933 .adc_nids = alc262_dmic_adc_nids,
14934 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14935 .capsrc_nids = alc262_dmic_capsrc_nids,
14936 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14937 .channel_mode = alc269_modes,
14938 .input_mux = &alc269_capture_source,
14939 .dig_out_nid = ALC880_DIGOUT_NID,
14940 .unsol_event = alc_sku_unsol_event,
14941 .setup = alc269vb_laptop_dmic_setup,
14942 .init_hook = alc_inithook,
14943 },
f6a92248
KY
14944};
14945
977ddd6b
KY
14946static int alc269_fill_coef(struct hda_codec *codec)
14947{
14948 int val;
14949
14950 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
14951 alc_write_coef_idx(codec, 0xf, 0x960b);
14952 alc_write_coef_idx(codec, 0xe, 0x8817);
14953 }
14954
14955 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
14956 alc_write_coef_idx(codec, 0xf, 0x960b);
14957 alc_write_coef_idx(codec, 0xe, 0x8814);
14958 }
14959
14960 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14961 val = alc_read_coef_idx(codec, 0x04);
14962 /* Power up output pin */
14963 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14964 }
14965
14966 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14967 val = alc_read_coef_idx(codec, 0xd);
14968 if ((val & 0x0c00) >> 10 != 0x1) {
14969 /* Capless ramp up clock control */
14970 alc_write_coef_idx(codec, 0xd, val | 1<<10);
14971 }
14972 val = alc_read_coef_idx(codec, 0x17);
14973 if ((val & 0x01c0) >> 6 != 0x4) {
14974 /* Class D power on reset */
14975 alc_write_coef_idx(codec, 0x17, val | 1<<7);
14976 }
14977 }
14978 return 0;
14979}
14980
f6a92248
KY
14981static int patch_alc269(struct hda_codec *codec)
14982{
14983 struct alc_spec *spec;
14984 int board_config;
14985 int err;
14986
14987 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14988 if (spec == NULL)
14989 return -ENOMEM;
14990
14991 codec->spec = spec;
14992
da00c244
KY
14993 alc_auto_parse_customize_define(codec);
14994
274693f3 14995 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd 14996 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
d433a678 14997 spec->cdefine.platform_type == 1) {
c027ddcd 14998 alc_codec_rename(codec, "ALC271X");
d433a678
TI
14999 spec->codec_variant = ALC269_TYPE_ALC271X;
15000 } else {
c027ddcd 15001 alc_codec_rename(codec, "ALC259");
d433a678
TI
15002 spec->codec_variant = ALC269_TYPE_ALC259;
15003 }
c027ddcd
KY
15004 } else
15005 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 15006
977ddd6b
KY
15007 alc269_fill_coef(codec);
15008
f6a92248
KY
15009 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15010 alc269_models,
15011 alc269_cfg_tbl);
15012
15013 if (board_config < 0) {
9a11f1aa
TI
15014 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15015 codec->chip_name);
f6a92248
KY
15016 board_config = ALC269_AUTO;
15017 }
15018
ff818c24
TI
15019 if (board_config == ALC269_AUTO)
15020 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
15021
f6a92248
KY
15022 if (board_config == ALC269_AUTO) {
15023 /* automatic parse from the BIOS config */
15024 err = alc269_parse_auto_config(codec);
15025 if (err < 0) {
15026 alc_free(codec);
15027 return err;
15028 } else if (!err) {
15029 printk(KERN_INFO
15030 "hda_codec: Cannot set up configuration "
15031 "from BIOS. Using base mode...\n");
15032 board_config = ALC269_BASIC;
15033 }
15034 }
15035
dc1eae25 15036 if (has_cdefine_beep(codec)) {
8af2591d
TI
15037 err = snd_hda_attach_beep_device(codec, 0x1);
15038 if (err < 0) {
15039 alc_free(codec);
15040 return err;
15041 }
680cd536
KK
15042 }
15043
f6a92248 15044 if (board_config != ALC269_AUTO)
e9c364c0 15045 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15046
84898e87 15047 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15048 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15049 * fix the sample rate of analog I/O to 44.1kHz
15050 */
15051 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15052 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15053 } else if (spec->dual_adc_switch) {
15054 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15055 /* switch ADC dynamically */
15056 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15057 } else {
15058 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15059 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15060 }
f6a92248
KY
15061 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15062 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15063
6694635d 15064 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
d433a678 15065 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
6694635d
TI
15066 spec->adc_nids = alc269_adc_nids;
15067 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15068 spec->capsrc_nids = alc269_capsrc_nids;
15069 } else {
15070 spec->adc_nids = alc269vb_adc_nids;
15071 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15072 spec->capsrc_nids = alc269vb_capsrc_nids;
15073 }
84898e87
KY
15074 }
15075
f9e336f6 15076 if (!spec->cap_mixer)
b59bdf3b 15077 set_capture_mixer(codec);
dc1eae25 15078 if (has_cdefine_beep(codec))
da00c244 15079 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15080
ff818c24
TI
15081 if (board_config == ALC269_AUTO)
15082 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
15083
100d5eb3
TI
15084 spec->vmaster_nid = 0x02;
15085
f6a92248 15086 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15087#ifdef CONFIG_SND_HDA_POWER_SAVE
15088 codec->patch_ops.suspend = alc269_suspend;
15089#endif
15090#ifdef SND_HDA_NEEDS_RESUME
15091 codec->patch_ops.resume = alc269_resume;
15092#endif
f6a92248
KY
15093 if (board_config == ALC269_AUTO)
15094 spec->init_hook = alc269_auto_init;
15095#ifdef CONFIG_SND_HDA_POWER_SAVE
15096 if (!spec->loopback.amplist)
15097 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15098 if (alc269_mic2_for_mute_led(codec))
15099 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15100#endif
15101
15102 return 0;
15103}
15104
df694daa
KY
15105/*
15106 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15107 */
15108
15109/*
15110 * set the path ways for 2 channel output
15111 * need to set the codec line out and mic 1 pin widgets to inputs
15112 */
15113static struct hda_verb alc861_threestack_ch2_init[] = {
15114 /* set pin widget 1Ah (line in) for input */
15115 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15116 /* set pin widget 18h (mic1/2) for input, for mic also enable
15117 * the vref
15118 */
df694daa
KY
15119 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15120
9c7f852e
TI
15121 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15122#if 0
15123 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15124 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15125#endif
df694daa
KY
15126 { } /* end */
15127};
15128/*
15129 * 6ch mode
15130 * need to set the codec line out and mic 1 pin widgets to outputs
15131 */
15132static struct hda_verb alc861_threestack_ch6_init[] = {
15133 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15134 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15135 /* set pin widget 18h (mic1) for output (CLFE)*/
15136 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15137
15138 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15139 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15140
9c7f852e
TI
15141 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15142#if 0
15143 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15144 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15145#endif
df694daa
KY
15146 { } /* end */
15147};
15148
15149static struct hda_channel_mode alc861_threestack_modes[2] = {
15150 { 2, alc861_threestack_ch2_init },
15151 { 6, alc861_threestack_ch6_init },
15152};
22309c3e
TI
15153/* Set mic1 as input and unmute the mixer */
15154static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15155 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15156 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15157 { } /* end */
15158};
15159/* Set mic1 as output and mute mixer */
15160static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15161 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15162 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15163 { } /* end */
15164};
15165
15166static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15167 { 2, alc861_uniwill_m31_ch2_init },
15168 { 4, alc861_uniwill_m31_ch4_init },
15169};
df694daa 15170
7cdbff94
MD
15171/* Set mic1 and line-in as input and unmute the mixer */
15172static struct hda_verb alc861_asus_ch2_init[] = {
15173 /* set pin widget 1Ah (line in) for input */
15174 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15175 /* set pin widget 18h (mic1/2) for input, for mic also enable
15176 * the vref
15177 */
7cdbff94
MD
15178 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15179
15180 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15181#if 0
15182 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15183 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15184#endif
15185 { } /* end */
15186};
15187/* Set mic1 nad line-in as output and mute mixer */
15188static struct hda_verb alc861_asus_ch6_init[] = {
15189 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15190 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15191 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15192 /* set pin widget 18h (mic1) for output (CLFE)*/
15193 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15194 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15195 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15196 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15197
15198 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15199#if 0
15200 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15201 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15202#endif
15203 { } /* end */
15204};
15205
15206static struct hda_channel_mode alc861_asus_modes[2] = {
15207 { 2, alc861_asus_ch2_init },
15208 { 6, alc861_asus_ch6_init },
15209};
15210
df694daa
KY
15211/* patch-ALC861 */
15212
15213static struct snd_kcontrol_new alc861_base_mixer[] = {
15214 /* output mixer control */
15215 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15216 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15217 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15218 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15219 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15220
15221 /*Input mixer control */
15222 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15223 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15224 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15225 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15226 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15227 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15229 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15230 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15232
df694daa
KY
15233 { } /* end */
15234};
15235
15236static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15237 /* output mixer control */
15238 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15239 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15240 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15241 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15242 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15243
15244 /* Input mixer control */
15245 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15246 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15247 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15248 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15249 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15250 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15252 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15255
df694daa
KY
15256 {
15257 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15258 .name = "Channel Mode",
15259 .info = alc_ch_mode_info,
15260 .get = alc_ch_mode_get,
15261 .put = alc_ch_mode_put,
15262 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15263 },
15264 { } /* end */
a53d1aec
TD
15265};
15266
d1d985f0 15267static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15268 /* output mixer control */
15269 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15270 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15271 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15272
a53d1aec 15273 { } /* end */
f12ab1e0 15274};
a53d1aec 15275
22309c3e
TI
15276static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15277 /* output mixer control */
15278 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15279 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15280 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15281 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15282 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15283
15284 /* Input mixer control */
15285 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15286 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15287 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15288 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15289 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15290 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15291 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15292 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15293 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15294 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15295
22309c3e
TI
15296 {
15297 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15298 .name = "Channel Mode",
15299 .info = alc_ch_mode_info,
15300 .get = alc_ch_mode_get,
15301 .put = alc_ch_mode_put,
15302 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15303 },
15304 { } /* end */
f12ab1e0 15305};
7cdbff94
MD
15306
15307static struct snd_kcontrol_new alc861_asus_mixer[] = {
15308 /* output mixer control */
15309 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15310 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15311 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15312 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15313 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15314
15315 /* Input mixer control */
15316 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15317 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15318 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15319 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15320 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15321 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15322 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15323 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15324 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15325 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15326
7cdbff94
MD
15327 {
15328 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15329 .name = "Channel Mode",
15330 .info = alc_ch_mode_info,
15331 .get = alc_ch_mode_get,
15332 .put = alc_ch_mode_put,
15333 .private_value = ARRAY_SIZE(alc861_asus_modes),
15334 },
15335 { }
56bb0cab
TI
15336};
15337
15338/* additional mixer */
d1d985f0 15339static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15340 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15341 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15342 { }
15343};
7cdbff94 15344
df694daa
KY
15345/*
15346 * generic initialization of ADC, input mixers and output mixers
15347 */
15348static struct hda_verb alc861_base_init_verbs[] = {
15349 /*
15350 * Unmute ADC0 and set the default input to mic-in
15351 */
15352 /* port-A for surround (rear panel) */
15353 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15354 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15355 /* port-B for mic-in (rear panel) with vref */
15356 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15357 /* port-C for line-in (rear panel) */
15358 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15359 /* port-D for Front */
15360 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15361 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15362 /* port-E for HP out (front panel) */
15363 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15364 /* route front PCM to HP */
9dece1d7 15365 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15366 /* port-F for mic-in (front panel) with vref */
15367 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15368 /* port-G for CLFE (rear panel) */
15369 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15370 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15371 /* port-H for side (rear panel) */
15372 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15373 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15374 /* CD-in */
15375 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15376 /* route front mic to ADC1*/
15377 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15378 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15379
df694daa
KY
15380 /* Unmute DAC0~3 & spdif out*/
15381 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15382 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15383 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15384 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15385 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15386
df694daa
KY
15387 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15388 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15389 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15390 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15391 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15392
df694daa
KY
15393 /* Unmute Stereo Mixer 15 */
15394 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15395 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15397 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15398
15399 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15400 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15401 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15402 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15403 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15404 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15405 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15406 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15407 /* hp used DAC 3 (Front) */
15408 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15409 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15410
15411 { }
15412};
15413
15414static struct hda_verb alc861_threestack_init_verbs[] = {
15415 /*
15416 * Unmute ADC0 and set the default input to mic-in
15417 */
15418 /* port-A for surround (rear panel) */
15419 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15420 /* port-B for mic-in (rear panel) with vref */
15421 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15422 /* port-C for line-in (rear panel) */
15423 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15424 /* port-D for Front */
15425 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15426 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15427 /* port-E for HP out (front panel) */
15428 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15429 /* route front PCM to HP */
9dece1d7 15430 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15431 /* port-F for mic-in (front panel) with vref */
15432 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15433 /* port-G for CLFE (rear panel) */
15434 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15435 /* port-H for side (rear panel) */
15436 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15437 /* CD-in */
15438 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15439 /* route front mic to ADC1*/
15440 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15442 /* Unmute DAC0~3 & spdif out*/
15443 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15444 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15445 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15446 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15447 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15448
df694daa
KY
15449 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15450 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15451 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15452 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15453 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15454
df694daa
KY
15455 /* Unmute Stereo Mixer 15 */
15456 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15457 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15458 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15459 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15460
15461 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15462 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15463 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15464 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15465 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15466 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15467 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15468 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15469 /* hp used DAC 3 (Front) */
15470 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15471 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15472 { }
15473};
22309c3e
TI
15474
15475static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15476 /*
15477 * Unmute ADC0 and set the default input to mic-in
15478 */
15479 /* port-A for surround (rear panel) */
15480 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15481 /* port-B for mic-in (rear panel) with vref */
15482 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15483 /* port-C for line-in (rear panel) */
15484 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15485 /* port-D for Front */
15486 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15487 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15488 /* port-E for HP out (front panel) */
f12ab1e0
TI
15489 /* this has to be set to VREF80 */
15490 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15491 /* route front PCM to HP */
9dece1d7 15492 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15493 /* port-F for mic-in (front panel) with vref */
15494 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15495 /* port-G for CLFE (rear panel) */
15496 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15497 /* port-H for side (rear panel) */
15498 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15499 /* CD-in */
15500 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15501 /* route front mic to ADC1*/
15502 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15503 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15504 /* Unmute DAC0~3 & spdif out*/
15505 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15506 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15507 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15508 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15510
22309c3e
TI
15511 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15512 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15513 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15514 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15515 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15516
22309c3e
TI
15517 /* Unmute Stereo Mixer 15 */
15518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15519 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15520 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15521 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15522
15523 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15524 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15525 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15526 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15527 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15528 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15529 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15530 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15531 /* hp used DAC 3 (Front) */
15532 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15533 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15534 { }
15535};
15536
7cdbff94
MD
15537static struct hda_verb alc861_asus_init_verbs[] = {
15538 /*
15539 * Unmute ADC0 and set the default input to mic-in
15540 */
f12ab1e0
TI
15541 /* port-A for surround (rear panel)
15542 * according to codec#0 this is the HP jack
15543 */
7cdbff94
MD
15544 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15545 /* route front PCM to HP */
15546 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15547 /* port-B for mic-in (rear panel) with vref */
15548 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15549 /* port-C for line-in (rear panel) */
15550 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15551 /* port-D for Front */
15552 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15553 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15554 /* port-E for HP out (front panel) */
f12ab1e0
TI
15555 /* this has to be set to VREF80 */
15556 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15557 /* route front PCM to HP */
9dece1d7 15558 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15559 /* port-F for mic-in (front panel) with vref */
15560 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15561 /* port-G for CLFE (rear panel) */
15562 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15563 /* port-H for side (rear panel) */
15564 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15565 /* CD-in */
15566 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15567 /* route front mic to ADC1*/
15568 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15570 /* Unmute DAC0~3 & spdif out*/
15571 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15572 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15573 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15574 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15576 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15577 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15578 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15579 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15580 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15581
7cdbff94
MD
15582 /* Unmute Stereo Mixer 15 */
15583 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15584 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15585 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15587
15588 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15589 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15590 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15591 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15592 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15593 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15594 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15595 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15596 /* hp used DAC 3 (Front) */
15597 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15598 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15599 { }
15600};
15601
56bb0cab
TI
15602/* additional init verbs for ASUS laptops */
15603static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15604 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15605 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15606 { }
15607};
7cdbff94 15608
df694daa
KY
15609/*
15610 * generic initialization of ADC, input mixers and output mixers
15611 */
15612static struct hda_verb alc861_auto_init_verbs[] = {
15613 /*
15614 * Unmute ADC0 and set the default input to mic-in
15615 */
f12ab1e0 15616 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15617 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15618
df694daa
KY
15619 /* Unmute DAC0~3 & spdif out*/
15620 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15621 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15622 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15623 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15625
df694daa
KY
15626 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15627 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15628 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15629 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15630 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15631
df694daa
KY
15632 /* Unmute Stereo Mixer 15 */
15633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15635 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15636 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15637
1c20930a
TI
15638 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15639 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15640 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15641 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15643 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15644 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15645 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15646
15647 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15648 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15649 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15650 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15651 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15652 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15653 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15654 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15655
f12ab1e0 15656 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15657
15658 { }
15659};
15660
a53d1aec
TD
15661static struct hda_verb alc861_toshiba_init_verbs[] = {
15662 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15663
a53d1aec
TD
15664 { }
15665};
15666
15667/* toggle speaker-output according to the hp-jack state */
15668static void alc861_toshiba_automute(struct hda_codec *codec)
15669{
864f92be 15670 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15671
47fd830a
TI
15672 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15673 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15674 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15675 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15676}
15677
15678static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15679 unsigned int res)
15680{
a53d1aec
TD
15681 if ((res >> 26) == ALC880_HP_EVENT)
15682 alc861_toshiba_automute(codec);
15683}
15684
def319f9 15685/* pcm configuration: identical with ALC880 */
df694daa
KY
15686#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15687#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15688#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15689#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15690
15691
15692#define ALC861_DIGOUT_NID 0x07
15693
15694static struct hda_channel_mode alc861_8ch_modes[1] = {
15695 { 8, NULL }
15696};
15697
15698static hda_nid_t alc861_dac_nids[4] = {
15699 /* front, surround, clfe, side */
15700 0x03, 0x06, 0x05, 0x04
15701};
15702
9c7f852e
TI
15703static hda_nid_t alc660_dac_nids[3] = {
15704 /* front, clfe, surround */
15705 0x03, 0x05, 0x06
15706};
15707
df694daa
KY
15708static hda_nid_t alc861_adc_nids[1] = {
15709 /* ADC0-2 */
15710 0x08,
15711};
15712
15713static struct hda_input_mux alc861_capture_source = {
15714 .num_items = 5,
15715 .items = {
15716 { "Mic", 0x0 },
15717 { "Front Mic", 0x3 },
15718 { "Line", 0x1 },
15719 { "CD", 0x4 },
15720 { "Mixer", 0x5 },
15721 },
15722};
15723
1c20930a
TI
15724static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15725{
15726 struct alc_spec *spec = codec->spec;
15727 hda_nid_t mix, srcs[5];
15728 int i, j, num;
15729
15730 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15731 return 0;
15732 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15733 if (num < 0)
15734 return 0;
15735 for (i = 0; i < num; i++) {
15736 unsigned int type;
a22d543a 15737 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15738 if (type != AC_WID_AUD_OUT)
15739 continue;
15740 for (j = 0; j < spec->multiout.num_dacs; j++)
15741 if (spec->multiout.dac_nids[j] == srcs[i])
15742 break;
15743 if (j >= spec->multiout.num_dacs)
15744 return srcs[i];
15745 }
15746 return 0;
15747}
15748
df694daa 15749/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15750static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15751 const struct auto_pin_cfg *cfg)
df694daa 15752{
1c20930a 15753 struct alc_spec *spec = codec->spec;
df694daa 15754 int i;
1c20930a 15755 hda_nid_t nid, dac;
df694daa
KY
15756
15757 spec->multiout.dac_nids = spec->private_dac_nids;
15758 for (i = 0; i < cfg->line_outs; i++) {
15759 nid = cfg->line_out_pins[i];
1c20930a
TI
15760 dac = alc861_look_for_dac(codec, nid);
15761 if (!dac)
15762 continue;
15763 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15764 }
df694daa
KY
15765 return 0;
15766}
15767
1c20930a
TI
15768static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15769 hda_nid_t nid, unsigned int chs)
15770{
0afe5f89 15771 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15772 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15773}
15774
df694daa 15775/* add playback controls from the parsed DAC table */
1c20930a 15776static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15777 const struct auto_pin_cfg *cfg)
15778{
1c20930a 15779 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15780 static const char *chname[4] = {
15781 "Front", "Surround", NULL /*CLFE*/, "Side"
15782 };
df694daa 15783 hda_nid_t nid;
1c20930a
TI
15784 int i, err;
15785
15786 if (cfg->line_outs == 1) {
15787 const char *pfx = NULL;
15788 if (!cfg->hp_outs)
15789 pfx = "Master";
15790 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15791 pfx = "Speaker";
15792 if (pfx) {
15793 nid = spec->multiout.dac_nids[0];
15794 return alc861_create_out_sw(codec, pfx, nid, 3);
15795 }
15796 }
df694daa
KY
15797
15798 for (i = 0; i < cfg->line_outs; i++) {
15799 nid = spec->multiout.dac_nids[i];
f12ab1e0 15800 if (!nid)
df694daa 15801 continue;
1c20930a 15802 if (i == 2) {
df694daa 15803 /* Center/LFE */
1c20930a 15804 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15805 if (err < 0)
df694daa 15806 return err;
1c20930a 15807 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15808 if (err < 0)
df694daa
KY
15809 return err;
15810 } else {
1c20930a 15811 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15812 if (err < 0)
df694daa
KY
15813 return err;
15814 }
15815 }
15816 return 0;
15817}
15818
1c20930a 15819static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15820{
1c20930a 15821 struct alc_spec *spec = codec->spec;
df694daa
KY
15822 int err;
15823 hda_nid_t nid;
15824
f12ab1e0 15825 if (!pin)
df694daa
KY
15826 return 0;
15827
15828 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15829 nid = alc861_look_for_dac(codec, pin);
15830 if (nid) {
15831 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15832 if (err < 0)
15833 return err;
15834 spec->multiout.hp_nid = nid;
15835 }
df694daa
KY
15836 }
15837 return 0;
15838}
15839
15840/* create playback/capture controls for input pins */
05f5f477 15841static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15842 const struct auto_pin_cfg *cfg)
df694daa 15843{
05f5f477 15844 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15845}
15846
f12ab1e0
TI
15847static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15848 hda_nid_t nid,
1c20930a 15849 int pin_type, hda_nid_t dac)
df694daa 15850{
1c20930a
TI
15851 hda_nid_t mix, srcs[5];
15852 int i, num;
15853
564c5bea
JL
15854 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15855 pin_type);
1c20930a 15856 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15857 AMP_OUT_UNMUTE);
1c20930a
TI
15858 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15859 return;
15860 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15861 if (num < 0)
15862 return;
15863 for (i = 0; i < num; i++) {
15864 unsigned int mute;
15865 if (srcs[i] == dac || srcs[i] == 0x15)
15866 mute = AMP_IN_UNMUTE(i);
15867 else
15868 mute = AMP_IN_MUTE(i);
15869 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15870 mute);
15871 }
df694daa
KY
15872}
15873
15874static void alc861_auto_init_multi_out(struct hda_codec *codec)
15875{
15876 struct alc_spec *spec = codec->spec;
15877 int i;
15878
15879 for (i = 0; i < spec->autocfg.line_outs; i++) {
15880 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15881 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15882 if (nid)
baba8ee9 15883 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15884 spec->multiout.dac_nids[i]);
df694daa
KY
15885 }
15886}
15887
15888static void alc861_auto_init_hp_out(struct hda_codec *codec)
15889{
15890 struct alc_spec *spec = codec->spec;
df694daa 15891
15870f05
TI
15892 if (spec->autocfg.hp_outs)
15893 alc861_auto_set_output_and_unmute(codec,
15894 spec->autocfg.hp_pins[0],
15895 PIN_HP,
1c20930a 15896 spec->multiout.hp_nid);
15870f05
TI
15897 if (spec->autocfg.speaker_outs)
15898 alc861_auto_set_output_and_unmute(codec,
15899 spec->autocfg.speaker_pins[0],
15900 PIN_OUT,
1c20930a 15901 spec->multiout.dac_nids[0]);
df694daa
KY
15902}
15903
15904static void alc861_auto_init_analog_input(struct hda_codec *codec)
15905{
15906 struct alc_spec *spec = codec->spec;
66ceeb6b 15907 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
15908 int i;
15909
66ceeb6b
TI
15910 for (i = 0; i < cfg->num_inputs; i++) {
15911 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 15912 if (nid >= 0x0c && nid <= 0x11)
30ea098f 15913 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
15914 }
15915}
15916
15917/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15918/* return 1 if successful, 0 if the proper config is not found,
15919 * or a negative error code
15920 */
df694daa
KY
15921static int alc861_parse_auto_config(struct hda_codec *codec)
15922{
15923 struct alc_spec *spec = codec->spec;
15924 int err;
15925 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15926
f12ab1e0
TI
15927 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15928 alc861_ignore);
15929 if (err < 0)
df694daa 15930 return err;
f12ab1e0 15931 if (!spec->autocfg.line_outs)
df694daa
KY
15932 return 0; /* can't find valid BIOS pin config */
15933
1c20930a 15934 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15935 if (err < 0)
15936 return err;
1c20930a 15937 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15938 if (err < 0)
15939 return err;
1c20930a 15940 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15941 if (err < 0)
15942 return err;
05f5f477 15943 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15944 if (err < 0)
df694daa
KY
15945 return err;
15946
15947 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15948
757899ac 15949 alc_auto_parse_digital(codec);
df694daa 15950
603c4019 15951 if (spec->kctls.list)
d88897ea 15952 add_mixer(spec, spec->kctls.list);
df694daa 15953
d88897ea 15954 add_verb(spec, alc861_auto_init_verbs);
df694daa 15955
a1e8d2da 15956 spec->num_mux_defs = 1;
61b9b9b1 15957 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15958
15959 spec->adc_nids = alc861_adc_nids;
15960 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15961 set_capture_mixer(codec);
df694daa 15962
6227cdce 15963 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15964
df694daa
KY
15965 return 1;
15966}
15967
ae6b813a
TI
15968/* additional initialization for auto-configuration model */
15969static void alc861_auto_init(struct hda_codec *codec)
df694daa 15970{
f6c7e546 15971 struct alc_spec *spec = codec->spec;
df694daa
KY
15972 alc861_auto_init_multi_out(codec);
15973 alc861_auto_init_hp_out(codec);
15974 alc861_auto_init_analog_input(codec);
757899ac 15975 alc_auto_init_digital(codec);
f6c7e546 15976 if (spec->unsol_event)
7fb0d78f 15977 alc_inithook(codec);
df694daa
KY
15978}
15979
cb53c626
TI
15980#ifdef CONFIG_SND_HDA_POWER_SAVE
15981static struct hda_amp_list alc861_loopbacks[] = {
15982 { 0x15, HDA_INPUT, 0 },
15983 { 0x15, HDA_INPUT, 1 },
15984 { 0x15, HDA_INPUT, 2 },
15985 { 0x15, HDA_INPUT, 3 },
15986 { } /* end */
15987};
15988#endif
15989
df694daa
KY
15990
15991/*
15992 * configuration and preset
15993 */
f5fcc13c
TI
15994static const char *alc861_models[ALC861_MODEL_LAST] = {
15995 [ALC861_3ST] = "3stack",
15996 [ALC660_3ST] = "3stack-660",
15997 [ALC861_3ST_DIG] = "3stack-dig",
15998 [ALC861_6ST_DIG] = "6stack-dig",
15999 [ALC861_UNIWILL_M31] = "uniwill-m31",
16000 [ALC861_TOSHIBA] = "toshiba",
16001 [ALC861_ASUS] = "asus",
16002 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16003 [ALC861_AUTO] = "auto",
16004};
16005
16006static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16007 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16008 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16009 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16010 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16011 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16012 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16013 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16014 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16015 * Any other models that need this preset?
16016 */
16017 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16018 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16019 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16020 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16021 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16022 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16023 /* FIXME: the below seems conflict */
16024 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16025 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16026 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16027 {}
16028};
16029
16030static struct alc_config_preset alc861_presets[] = {
16031 [ALC861_3ST] = {
16032 .mixers = { alc861_3ST_mixer },
16033 .init_verbs = { alc861_threestack_init_verbs },
16034 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16035 .dac_nids = alc861_dac_nids,
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_3ST_DIG] = {
16044 .mixers = { alc861_base_mixer },
16045 .init_verbs = { alc861_threestack_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_threestack_modes),
16050 .channel_mode = alc861_threestack_modes,
4e195a7b 16051 .need_dac_fix = 1,
df694daa
KY
16052 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16053 .adc_nids = alc861_adc_nids,
16054 .input_mux = &alc861_capture_source,
16055 },
16056 [ALC861_6ST_DIG] = {
16057 .mixers = { alc861_base_mixer },
16058 .init_verbs = { alc861_base_init_verbs },
16059 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16060 .dac_nids = alc861_dac_nids,
16061 .dig_out_nid = ALC861_DIGOUT_NID,
16062 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16063 .channel_mode = alc861_8ch_modes,
16064 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16065 .adc_nids = alc861_adc_nids,
16066 .input_mux = &alc861_capture_source,
16067 },
9c7f852e
TI
16068 [ALC660_3ST] = {
16069 .mixers = { alc861_3ST_mixer },
16070 .init_verbs = { alc861_threestack_init_verbs },
16071 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16072 .dac_nids = alc660_dac_nids,
16073 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16074 .channel_mode = alc861_threestack_modes,
4e195a7b 16075 .need_dac_fix = 1,
9c7f852e
TI
16076 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16077 .adc_nids = alc861_adc_nids,
16078 .input_mux = &alc861_capture_source,
16079 },
22309c3e
TI
16080 [ALC861_UNIWILL_M31] = {
16081 .mixers = { alc861_uniwill_m31_mixer },
16082 .init_verbs = { alc861_uniwill_m31_init_verbs },
16083 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16084 .dac_nids = alc861_dac_nids,
16085 .dig_out_nid = ALC861_DIGOUT_NID,
16086 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16087 .channel_mode = alc861_uniwill_m31_modes,
16088 .need_dac_fix = 1,
16089 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16090 .adc_nids = alc861_adc_nids,
16091 .input_mux = &alc861_capture_source,
16092 },
a53d1aec
TD
16093 [ALC861_TOSHIBA] = {
16094 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16095 .init_verbs = { alc861_base_init_verbs,
16096 alc861_toshiba_init_verbs },
a53d1aec
TD
16097 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16098 .dac_nids = alc861_dac_nids,
16099 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16100 .channel_mode = alc883_3ST_2ch_modes,
16101 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16102 .adc_nids = alc861_adc_nids,
16103 .input_mux = &alc861_capture_source,
16104 .unsol_event = alc861_toshiba_unsol_event,
16105 .init_hook = alc861_toshiba_automute,
16106 },
7cdbff94
MD
16107 [ALC861_ASUS] = {
16108 .mixers = { alc861_asus_mixer },
16109 .init_verbs = { alc861_asus_init_verbs },
16110 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16111 .dac_nids = alc861_dac_nids,
16112 .dig_out_nid = ALC861_DIGOUT_NID,
16113 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16114 .channel_mode = alc861_asus_modes,
16115 .need_dac_fix = 1,
16116 .hp_nid = 0x06,
16117 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16118 .adc_nids = alc861_adc_nids,
16119 .input_mux = &alc861_capture_source,
16120 },
56bb0cab
TI
16121 [ALC861_ASUS_LAPTOP] = {
16122 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16123 .init_verbs = { alc861_asus_init_verbs,
16124 alc861_asus_laptop_init_verbs },
16125 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16126 .dac_nids = alc861_dac_nids,
16127 .dig_out_nid = ALC861_DIGOUT_NID,
16128 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16129 .channel_mode = alc883_3ST_2ch_modes,
16130 .need_dac_fix = 1,
16131 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16132 .adc_nids = alc861_adc_nids,
16133 .input_mux = &alc861_capture_source,
16134 },
16135};
df694daa 16136
cfc9b06f
TI
16137/* Pin config fixes */
16138enum {
16139 PINFIX_FSC_AMILO_PI1505,
16140};
16141
cfc9b06f
TI
16142static const struct alc_fixup alc861_fixups[] = {
16143 [PINFIX_FSC_AMILO_PI1505] = {
73413b12
TI
16144 .pins = (const struct alc_pincfg[]) {
16145 { 0x0b, 0x0221101f }, /* HP */
16146 { 0x0f, 0x90170310 }, /* speaker */
16147 { }
16148 }
cfc9b06f
TI
16149 },
16150};
16151
16152static struct snd_pci_quirk alc861_fixup_tbl[] = {
16153 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16154 {}
16155};
df694daa
KY
16156
16157static int patch_alc861(struct hda_codec *codec)
16158{
16159 struct alc_spec *spec;
16160 int board_config;
16161 int err;
16162
dc041e0b 16163 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16164 if (spec == NULL)
16165 return -ENOMEM;
16166
f12ab1e0 16167 codec->spec = spec;
df694daa 16168
f5fcc13c
TI
16169 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16170 alc861_models,
16171 alc861_cfg_tbl);
9c7f852e 16172
f5fcc13c 16173 if (board_config < 0) {
9a11f1aa
TI
16174 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16175 codec->chip_name);
df694daa
KY
16176 board_config = ALC861_AUTO;
16177 }
16178
7fa90e87
TI
16179 if (board_config == ALC861_AUTO)
16180 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 16181
df694daa
KY
16182 if (board_config == ALC861_AUTO) {
16183 /* automatic parse from the BIOS config */
16184 err = alc861_parse_auto_config(codec);
16185 if (err < 0) {
16186 alc_free(codec);
16187 return err;
f12ab1e0 16188 } else if (!err) {
9c7f852e
TI
16189 printk(KERN_INFO
16190 "hda_codec: Cannot set up configuration "
16191 "from BIOS. Using base mode...\n");
df694daa
KY
16192 board_config = ALC861_3ST_DIG;
16193 }
16194 }
16195
680cd536
KK
16196 err = snd_hda_attach_beep_device(codec, 0x23);
16197 if (err < 0) {
16198 alc_free(codec);
16199 return err;
16200 }
16201
df694daa 16202 if (board_config != ALC861_AUTO)
e9c364c0 16203 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16204
df694daa
KY
16205 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16206 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16207
df694daa
KY
16208 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16209 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16210
c7a8eb10
TI
16211 if (!spec->cap_mixer)
16212 set_capture_mixer(codec);
45bdd1c1
TI
16213 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16214
2134ea4f
TI
16215 spec->vmaster_nid = 0x03;
16216
7fa90e87
TI
16217 if (board_config == ALC861_AUTO)
16218 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
16219
df694daa 16220 codec->patch_ops = alc_patch_ops;
c97259df 16221 if (board_config == ALC861_AUTO) {
ae6b813a 16222 spec->init_hook = alc861_auto_init;
c97259df
DC
16223#ifdef CONFIG_SND_HDA_POWER_SAVE
16224 spec->power_hook = alc_power_eapd;
16225#endif
16226 }
cb53c626
TI
16227#ifdef CONFIG_SND_HDA_POWER_SAVE
16228 if (!spec->loopback.amplist)
16229 spec->loopback.amplist = alc861_loopbacks;
16230#endif
ea1fb29a 16231
1da177e4
LT
16232 return 0;
16233}
16234
f32610ed
JS
16235/*
16236 * ALC861-VD support
16237 *
16238 * Based on ALC882
16239 *
16240 * In addition, an independent DAC
16241 */
16242#define ALC861VD_DIGOUT_NID 0x06
16243
16244static hda_nid_t alc861vd_dac_nids[4] = {
16245 /* front, surr, clfe, side surr */
16246 0x02, 0x03, 0x04, 0x05
16247};
16248
16249/* dac_nids for ALC660vd are in a different order - according to
16250 * Realtek's driver.
def319f9 16251 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16252 * of ALC660vd codecs, but for now there is only 3stack mixer
16253 * - and it is the same as in 861vd.
16254 * adc_nids in ALC660vd are (is) the same as in 861vd
16255 */
16256static hda_nid_t alc660vd_dac_nids[3] = {
16257 /* front, rear, clfe, rear_surr */
16258 0x02, 0x04, 0x03
16259};
16260
16261static hda_nid_t alc861vd_adc_nids[1] = {
16262 /* ADC0 */
16263 0x09,
16264};
16265
e1406348
TI
16266static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16267
f32610ed
JS
16268/* input MUX */
16269/* FIXME: should be a matrix-type input source selection */
16270static struct hda_input_mux alc861vd_capture_source = {
16271 .num_items = 4,
16272 .items = {
16273 { "Mic", 0x0 },
16274 { "Front Mic", 0x1 },
16275 { "Line", 0x2 },
16276 { "CD", 0x4 },
16277 },
16278};
16279
272a527c 16280static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16281 .num_items = 2,
272a527c 16282 .items = {
b419f346
TD
16283 { "Ext Mic", 0x0 },
16284 { "Int Mic", 0x1 },
272a527c
KY
16285 },
16286};
16287
d1a991a6
KY
16288static struct hda_input_mux alc861vd_hp_capture_source = {
16289 .num_items = 2,
16290 .items = {
16291 { "Front Mic", 0x0 },
16292 { "ATAPI Mic", 0x1 },
16293 },
16294};
16295
f32610ed
JS
16296/*
16297 * 2ch mode
16298 */
16299static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16300 { 2, NULL }
16301};
16302
16303/*
16304 * 6ch mode
16305 */
16306static struct hda_verb alc861vd_6stack_ch6_init[] = {
16307 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16308 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16309 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16310 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16311 { } /* end */
16312};
16313
16314/*
16315 * 8ch mode
16316 */
16317static struct hda_verb alc861vd_6stack_ch8_init[] = {
16318 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16319 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16320 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16321 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16322 { } /* end */
16323};
16324
16325static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16326 { 6, alc861vd_6stack_ch6_init },
16327 { 8, alc861vd_6stack_ch8_init },
16328};
16329
16330static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16331 {
16332 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16333 .name = "Channel Mode",
16334 .info = alc_ch_mode_info,
16335 .get = alc_ch_mode_get,
16336 .put = alc_ch_mode_put,
16337 },
16338 { } /* end */
16339};
16340
f32610ed
JS
16341/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16342 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16343 */
16344static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16345 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16346 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16347
16348 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16349 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16350
16351 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16352 HDA_OUTPUT),
16353 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16354 HDA_OUTPUT),
16355 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16356 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16357
16358 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16359 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16360
16361 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16362
16363 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16366
16367 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16368 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16369 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16370
16371 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16372 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16373
16374 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16375 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16376
f32610ed
JS
16377 { } /* end */
16378};
16379
16380static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16381 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16382 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16383
16384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16385
16386 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16389
16390 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16391 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16392 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16393
16394 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16395 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16396
16397 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16398 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16399
f32610ed
JS
16400 { } /* end */
16401};
16402
bdd148a3
KY
16403static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16404 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16405 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16406 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16407
16408 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16409
16410 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16411 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16412 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16413
16414 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16415 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16416 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16417
16418 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16419 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16420
16421 { } /* end */
16422};
16423
b419f346
TD
16424/* Pin assignment: Speaker=0x14, HP = 0x15,
16425 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16426 */
16427static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16428 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16429 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16430 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16431 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
16432 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16433 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16434 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16435 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16436 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16437 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16438 { } /* end */
16439};
16440
d1a991a6
KY
16441/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16442 * Front Mic=0x18, ATAPI Mic = 0x19,
16443 */
16444static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16445 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16446 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16448 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16451 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16452 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16453
d1a991a6
KY
16454 { } /* end */
16455};
16456
f32610ed
JS
16457/*
16458 * generic initialization of ADC, input mixers and output mixers
16459 */
16460static struct hda_verb alc861vd_volume_init_verbs[] = {
16461 /*
16462 * Unmute ADC0 and set the default input to mic-in
16463 */
16464 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16465 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16466
16467 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16468 * the analog-loopback mixer widget
16469 */
16470 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16471 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16472 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16473 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16474 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16475 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16476
16477 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16482
16483 /*
16484 * Set up output mixers (0x02 - 0x05)
16485 */
16486 /* set vol=0 to output mixers */
16487 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16488 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16489 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16490 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16491
16492 /* set up input amps for analog loopback */
16493 /* Amp Indices: DAC = 0, mixer = 1 */
16494 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16495 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16496 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16497 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16498 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16499 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16501 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16502
16503 { }
16504};
16505
16506/*
16507 * 3-stack pin configuration:
16508 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16509 */
16510static struct hda_verb alc861vd_3stack_init_verbs[] = {
16511 /*
16512 * Set pin mode and muting
16513 */
16514 /* set front pin widgets 0x14 for output */
16515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16516 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16517 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16518
16519 /* Mic (rear) pin: input vref at 80% */
16520 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16521 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16522 /* Front Mic pin: input vref at 80% */
16523 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16524 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16525 /* Line In pin: input */
16526 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16527 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16528 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16530 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16531 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16532 /* CD pin widget for input */
16533 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16534
16535 { }
16536};
16537
16538/*
16539 * 6-stack pin configuration:
16540 */
16541static struct hda_verb alc861vd_6stack_init_verbs[] = {
16542 /*
16543 * Set pin mode and muting
16544 */
16545 /* set front pin widgets 0x14 for output */
16546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16547 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16548 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16549
16550 /* Rear Pin: output 1 (0x0d) */
16551 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16553 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16554 /* CLFE Pin: output 2 (0x0e) */
16555 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16556 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16557 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16558 /* Side Pin: output 3 (0x0f) */
16559 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16560 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16561 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16562
16563 /* Mic (rear) pin: input vref at 80% */
16564 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16565 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16566 /* Front Mic pin: input vref at 80% */
16567 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16568 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16569 /* Line In pin: input */
16570 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16571 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16572 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16573 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16574 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16575 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16576 /* CD pin widget for input */
16577 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16578
16579 { }
16580};
16581
bdd148a3
KY
16582static struct hda_verb alc861vd_eapd_verbs[] = {
16583 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16584 { }
16585};
16586
f9423e7a
KY
16587static struct hda_verb alc660vd_eapd_verbs[] = {
16588 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16589 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16590 { }
16591};
16592
bdd148a3
KY
16593static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16594 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16596 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16597 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16598 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16599 {}
16600};
16601
bdd148a3
KY
16602static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16603{
16604 unsigned int present;
16605 unsigned char bits;
16606
864f92be 16607 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 16608 bits = present ? HDA_AMP_MUTE : 0;
864f92be 16609
47fd830a
TI
16610 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16611 HDA_AMP_MUTE, bits);
bdd148a3
KY
16612}
16613
4f5d1706 16614static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16615{
a9fd4f3f 16616 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16617 spec->autocfg.hp_pins[0] = 0x1b;
16618 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16619}
16620
16621static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16622{
a9fd4f3f 16623 alc_automute_amp(codec);
bdd148a3
KY
16624 alc861vd_lenovo_mic_automute(codec);
16625}
16626
16627static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16628 unsigned int res)
16629{
16630 switch (res >> 26) {
bdd148a3
KY
16631 case ALC880_MIC_EVENT:
16632 alc861vd_lenovo_mic_automute(codec);
16633 break;
a9fd4f3f
TI
16634 default:
16635 alc_automute_amp_unsol_event(codec, res);
16636 break;
bdd148a3
KY
16637 }
16638}
16639
272a527c
KY
16640static struct hda_verb alc861vd_dallas_verbs[] = {
16641 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16642 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16643 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16644 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16645
16646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16648 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16649 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16650 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16652 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16653 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16654
272a527c
KY
16655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16656 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16657 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16658 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16659 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16660 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16661 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16662 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16663
16664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16666 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16667 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16668 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16669 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16670 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16671 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16672
16673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16677
16678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16679 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16680 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16681
16682 { } /* end */
16683};
16684
16685/* toggle speaker-output according to the hp-jack state */
4f5d1706 16686static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16687{
a9fd4f3f 16688 struct alc_spec *spec = codec->spec;
272a527c 16689
a9fd4f3f
TI
16690 spec->autocfg.hp_pins[0] = 0x15;
16691 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16692}
16693
cb53c626
TI
16694#ifdef CONFIG_SND_HDA_POWER_SAVE
16695#define alc861vd_loopbacks alc880_loopbacks
16696#endif
16697
def319f9 16698/* pcm configuration: identical with ALC880 */
f32610ed
JS
16699#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16700#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16701#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16702#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16703
16704/*
16705 * configuration and preset
16706 */
16707static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16708 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16709 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16710 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16711 [ALC861VD_3ST] = "3stack",
16712 [ALC861VD_3ST_DIG] = "3stack-digout",
16713 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16714 [ALC861VD_LENOVO] = "lenovo",
272a527c 16715 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16716 [ALC861VD_HP] = "hp",
f32610ed
JS
16717 [ALC861VD_AUTO] = "auto",
16718};
16719
16720static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16721 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16722 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16723 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16724 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16725 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16726 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16727 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16728 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16729 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16730 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16731 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16732 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16733 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16734 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16735 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16736 {}
16737};
16738
16739static struct alc_config_preset alc861vd_presets[] = {
16740 [ALC660VD_3ST] = {
16741 .mixers = { alc861vd_3st_mixer },
16742 .init_verbs = { alc861vd_volume_init_verbs,
16743 alc861vd_3stack_init_verbs },
16744 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16745 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16746 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16747 .channel_mode = alc861vd_3stack_2ch_modes,
16748 .input_mux = &alc861vd_capture_source,
16749 },
6963f84c
MC
16750 [ALC660VD_3ST_DIG] = {
16751 .mixers = { alc861vd_3st_mixer },
16752 .init_verbs = { alc861vd_volume_init_verbs,
16753 alc861vd_3stack_init_verbs },
16754 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16755 .dac_nids = alc660vd_dac_nids,
16756 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16757 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16758 .channel_mode = alc861vd_3stack_2ch_modes,
16759 .input_mux = &alc861vd_capture_source,
16760 },
f32610ed
JS
16761 [ALC861VD_3ST] = {
16762 .mixers = { alc861vd_3st_mixer },
16763 .init_verbs = { alc861vd_volume_init_verbs,
16764 alc861vd_3stack_init_verbs },
16765 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16766 .dac_nids = alc861vd_dac_nids,
16767 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16768 .channel_mode = alc861vd_3stack_2ch_modes,
16769 .input_mux = &alc861vd_capture_source,
16770 },
16771 [ALC861VD_3ST_DIG] = {
16772 .mixers = { alc861vd_3st_mixer },
16773 .init_verbs = { alc861vd_volume_init_verbs,
16774 alc861vd_3stack_init_verbs },
16775 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16776 .dac_nids = alc861vd_dac_nids,
16777 .dig_out_nid = ALC861VD_DIGOUT_NID,
16778 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16779 .channel_mode = alc861vd_3stack_2ch_modes,
16780 .input_mux = &alc861vd_capture_source,
16781 },
16782 [ALC861VD_6ST_DIG] = {
16783 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16784 .init_verbs = { alc861vd_volume_init_verbs,
16785 alc861vd_6stack_init_verbs },
16786 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16787 .dac_nids = alc861vd_dac_nids,
16788 .dig_out_nid = ALC861VD_DIGOUT_NID,
16789 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16790 .channel_mode = alc861vd_6stack_modes,
16791 .input_mux = &alc861vd_capture_source,
16792 },
bdd148a3
KY
16793 [ALC861VD_LENOVO] = {
16794 .mixers = { alc861vd_lenovo_mixer },
16795 .init_verbs = { alc861vd_volume_init_verbs,
16796 alc861vd_3stack_init_verbs,
16797 alc861vd_eapd_verbs,
16798 alc861vd_lenovo_unsol_verbs },
16799 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16800 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16801 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16802 .channel_mode = alc861vd_3stack_2ch_modes,
16803 .input_mux = &alc861vd_capture_source,
16804 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16805 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16806 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16807 },
272a527c
KY
16808 [ALC861VD_DALLAS] = {
16809 .mixers = { alc861vd_dallas_mixer },
16810 .init_verbs = { alc861vd_dallas_verbs },
16811 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16812 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16813 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16814 .channel_mode = alc861vd_3stack_2ch_modes,
16815 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16816 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16817 .setup = alc861vd_dallas_setup,
16818 .init_hook = alc_automute_amp,
d1a991a6
KY
16819 },
16820 [ALC861VD_HP] = {
16821 .mixers = { alc861vd_hp_mixer },
16822 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16823 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16824 .dac_nids = alc861vd_dac_nids,
d1a991a6 16825 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16826 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16827 .channel_mode = alc861vd_3stack_2ch_modes,
16828 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16829 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16830 .setup = alc861vd_dallas_setup,
16831 .init_hook = alc_automute_amp,
ea1fb29a 16832 },
13c94744
TI
16833 [ALC660VD_ASUS_V1S] = {
16834 .mixers = { alc861vd_lenovo_mixer },
16835 .init_verbs = { alc861vd_volume_init_verbs,
16836 alc861vd_3stack_init_verbs,
16837 alc861vd_eapd_verbs,
16838 alc861vd_lenovo_unsol_verbs },
16839 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16840 .dac_nids = alc660vd_dac_nids,
16841 .dig_out_nid = ALC861VD_DIGOUT_NID,
16842 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16843 .channel_mode = alc861vd_3stack_2ch_modes,
16844 .input_mux = &alc861vd_capture_source,
16845 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16846 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16847 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16848 },
f32610ed
JS
16849};
16850
16851/*
16852 * BIOS auto configuration
16853 */
05f5f477
TI
16854static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16855 const struct auto_pin_cfg *cfg)
16856{
6227cdce 16857 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16858}
16859
16860
f32610ed
JS
16861static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16862 hda_nid_t nid, int pin_type, int dac_idx)
16863{
f6c7e546 16864 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16865}
16866
16867static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16868{
16869 struct alc_spec *spec = codec->spec;
16870 int i;
16871
16872 for (i = 0; i <= HDA_SIDE; i++) {
16873 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16874 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16875 if (nid)
16876 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16877 pin_type, i);
f32610ed
JS
16878 }
16879}
16880
16881
16882static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16883{
16884 struct alc_spec *spec = codec->spec;
16885 hda_nid_t pin;
16886
16887 pin = spec->autocfg.hp_pins[0];
def319f9 16888 if (pin) /* connect to front and use dac 0 */
f32610ed 16889 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16890 pin = spec->autocfg.speaker_pins[0];
16891 if (pin)
16892 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16893}
16894
f32610ed
JS
16895#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16896
16897static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16898{
16899 struct alc_spec *spec = codec->spec;
66ceeb6b 16900 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
16901 int i;
16902
66ceeb6b
TI
16903 for (i = 0; i < cfg->num_inputs; i++) {
16904 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 16905 if (alc_is_input_pin(codec, nid)) {
30ea098f 16906 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
16907 if (nid != ALC861VD_PIN_CD_NID &&
16908 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16909 snd_hda_codec_write(codec, nid, 0,
16910 AC_VERB_SET_AMP_GAIN_MUTE,
16911 AMP_OUT_MUTE);
16912 }
16913 }
16914}
16915
f511b01c
TI
16916#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16917
f32610ed
JS
16918#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16919#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16920
16921/* add playback controls from the parsed DAC table */
16922/* Based on ALC880 version. But ALC861VD has separate,
16923 * different NIDs for mute/unmute switch and volume control */
16924static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16925 const struct auto_pin_cfg *cfg)
16926{
f32610ed
JS
16927 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16928 hda_nid_t nid_v, nid_s;
16929 int i, err;
16930
16931 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16932 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16933 continue;
16934 nid_v = alc861vd_idx_to_mixer_vol(
16935 alc880_dac_to_idx(
16936 spec->multiout.dac_nids[i]));
16937 nid_s = alc861vd_idx_to_mixer_switch(
16938 alc880_dac_to_idx(
16939 spec->multiout.dac_nids[i]));
16940
16941 if (i == 2) {
16942 /* Center/LFE */
0afe5f89
TI
16943 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16944 "Center",
f12ab1e0
TI
16945 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16946 HDA_OUTPUT));
16947 if (err < 0)
f32610ed 16948 return err;
0afe5f89
TI
16949 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16950 "LFE",
f12ab1e0
TI
16951 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16952 HDA_OUTPUT));
16953 if (err < 0)
f32610ed 16954 return err;
0afe5f89
TI
16955 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16956 "Center",
f12ab1e0
TI
16957 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16958 HDA_INPUT));
16959 if (err < 0)
f32610ed 16960 return err;
0afe5f89
TI
16961 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16962 "LFE",
f12ab1e0
TI
16963 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16964 HDA_INPUT));
16965 if (err < 0)
f32610ed
JS
16966 return err;
16967 } else {
a4fcd491
TI
16968 const char *pfx;
16969 if (cfg->line_outs == 1 &&
16970 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16971 if (!cfg->hp_pins)
16972 pfx = "Speaker";
16973 else
16974 pfx = "PCM";
16975 } else
16976 pfx = chname[i];
0afe5f89 16977 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16978 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16979 HDA_OUTPUT));
16980 if (err < 0)
f32610ed 16981 return err;
a4fcd491
TI
16982 if (cfg->line_outs == 1 &&
16983 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16984 pfx = "Speaker";
0afe5f89 16985 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16986 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16987 HDA_INPUT));
16988 if (err < 0)
f32610ed
JS
16989 return err;
16990 }
16991 }
16992 return 0;
16993}
16994
16995/* add playback controls for speaker and HP outputs */
16996/* Based on ALC880 version. But ALC861VD has separate,
16997 * different NIDs for mute/unmute switch and volume control */
16998static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16999 hda_nid_t pin, const char *pfx)
17000{
17001 hda_nid_t nid_v, nid_s;
17002 int err;
f32610ed 17003
f12ab1e0 17004 if (!pin)
f32610ed
JS
17005 return 0;
17006
17007 if (alc880_is_fixed_pin(pin)) {
17008 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17009 /* specify the DAC as the extra output */
f12ab1e0 17010 if (!spec->multiout.hp_nid)
f32610ed
JS
17011 spec->multiout.hp_nid = nid_v;
17012 else
17013 spec->multiout.extra_out_nid[0] = nid_v;
17014 /* control HP volume/switch on the output mixer amp */
17015 nid_v = alc861vd_idx_to_mixer_vol(
17016 alc880_fixed_pin_idx(pin));
17017 nid_s = alc861vd_idx_to_mixer_switch(
17018 alc880_fixed_pin_idx(pin));
17019
0afe5f89 17020 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17021 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17022 if (err < 0)
f32610ed 17023 return err;
0afe5f89 17024 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17025 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17026 if (err < 0)
f32610ed
JS
17027 return err;
17028 } else if (alc880_is_multi_pin(pin)) {
17029 /* set manual connection */
17030 /* we have only a switch on HP-out PIN */
0afe5f89 17031 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17032 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17033 if (err < 0)
f32610ed
JS
17034 return err;
17035 }
17036 return 0;
17037}
17038
17039/* parse the BIOS configuration and set up the alc_spec
17040 * return 1 if successful, 0 if the proper config is not found,
17041 * or a negative error code
17042 * Based on ALC880 version - had to change it to override
17043 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17044static int alc861vd_parse_auto_config(struct hda_codec *codec)
17045{
17046 struct alc_spec *spec = codec->spec;
17047 int err;
17048 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17049
f12ab1e0
TI
17050 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17051 alc861vd_ignore);
17052 if (err < 0)
f32610ed 17053 return err;
f12ab1e0 17054 if (!spec->autocfg.line_outs)
f32610ed
JS
17055 return 0; /* can't find valid BIOS pin config */
17056
f12ab1e0
TI
17057 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17058 if (err < 0)
17059 return err;
17060 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17061 if (err < 0)
17062 return err;
17063 err = alc861vd_auto_create_extra_out(spec,
17064 spec->autocfg.speaker_pins[0],
17065 "Speaker");
17066 if (err < 0)
17067 return err;
17068 err = alc861vd_auto_create_extra_out(spec,
17069 spec->autocfg.hp_pins[0],
17070 "Headphone");
17071 if (err < 0)
17072 return err;
05f5f477 17073 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17074 if (err < 0)
f32610ed
JS
17075 return err;
17076
17077 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17078
757899ac 17079 alc_auto_parse_digital(codec);
f32610ed 17080
603c4019 17081 if (spec->kctls.list)
d88897ea 17082 add_mixer(spec, spec->kctls.list);
f32610ed 17083
d88897ea 17084 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17085
17086 spec->num_mux_defs = 1;
61b9b9b1 17087 spec->input_mux = &spec->private_imux[0];
f32610ed 17088
776e184e
TI
17089 err = alc_auto_add_mic_boost(codec);
17090 if (err < 0)
17091 return err;
17092
6227cdce 17093 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17094
f32610ed
JS
17095 return 1;
17096}
17097
17098/* additional initialization for auto-configuration model */
17099static void alc861vd_auto_init(struct hda_codec *codec)
17100{
f6c7e546 17101 struct alc_spec *spec = codec->spec;
f32610ed
JS
17102 alc861vd_auto_init_multi_out(codec);
17103 alc861vd_auto_init_hp_out(codec);
17104 alc861vd_auto_init_analog_input(codec);
f511b01c 17105 alc861vd_auto_init_input_src(codec);
757899ac 17106 alc_auto_init_digital(codec);
f6c7e546 17107 if (spec->unsol_event)
7fb0d78f 17108 alc_inithook(codec);
f32610ed
JS
17109}
17110
f8f25ba3
TI
17111enum {
17112 ALC660VD_FIX_ASUS_GPIO1
17113};
17114
17115/* reset GPIO1 */
f8f25ba3
TI
17116static const struct alc_fixup alc861vd_fixups[] = {
17117 [ALC660VD_FIX_ASUS_GPIO1] = {
73413b12
TI
17118 .verbs = (const struct hda_verb[]) {
17119 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17120 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17121 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17122 { }
17123 }
f8f25ba3
TI
17124 },
17125};
17126
17127static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17128 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17129 {}
17130};
17131
f32610ed
JS
17132static int patch_alc861vd(struct hda_codec *codec)
17133{
17134 struct alc_spec *spec;
17135 int err, board_config;
17136
17137 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17138 if (spec == NULL)
17139 return -ENOMEM;
17140
17141 codec->spec = spec;
17142
17143 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17144 alc861vd_models,
17145 alc861vd_cfg_tbl);
17146
17147 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17148 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17149 codec->chip_name);
f32610ed
JS
17150 board_config = ALC861VD_AUTO;
17151 }
17152
7fa90e87
TI
17153 if (board_config == ALC861VD_AUTO)
17154 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 17155
f32610ed
JS
17156 if (board_config == ALC861VD_AUTO) {
17157 /* automatic parse from the BIOS config */
17158 err = alc861vd_parse_auto_config(codec);
17159 if (err < 0) {
17160 alc_free(codec);
17161 return err;
f12ab1e0 17162 } else if (!err) {
f32610ed
JS
17163 printk(KERN_INFO
17164 "hda_codec: Cannot set up configuration "
17165 "from BIOS. Using base mode...\n");
17166 board_config = ALC861VD_3ST;
17167 }
17168 }
17169
680cd536
KK
17170 err = snd_hda_attach_beep_device(codec, 0x23);
17171 if (err < 0) {
17172 alc_free(codec);
17173 return err;
17174 }
17175
f32610ed 17176 if (board_config != ALC861VD_AUTO)
e9c364c0 17177 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17178
2f893286 17179 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17180 /* always turn on EAPD */
d88897ea 17181 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17182 }
17183
f32610ed
JS
17184 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17185 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17186
f32610ed
JS
17187 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17188 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17189
dd704698
TI
17190 if (!spec->adc_nids) {
17191 spec->adc_nids = alc861vd_adc_nids;
17192 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17193 }
17194 if (!spec->capsrc_nids)
17195 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17196
b59bdf3b 17197 set_capture_mixer(codec);
45bdd1c1 17198 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17199
2134ea4f
TI
17200 spec->vmaster_nid = 0x02;
17201
7fa90e87
TI
17202 if (board_config == ALC861VD_AUTO)
17203 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
17204
f32610ed
JS
17205 codec->patch_ops = alc_patch_ops;
17206
17207 if (board_config == ALC861VD_AUTO)
17208 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17209#ifdef CONFIG_SND_HDA_POWER_SAVE
17210 if (!spec->loopback.amplist)
17211 spec->loopback.amplist = alc861vd_loopbacks;
17212#endif
f32610ed
JS
17213
17214 return 0;
17215}
17216
bc9f98a9
KY
17217/*
17218 * ALC662 support
17219 *
17220 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17221 * configuration. Each pin widget can choose any input DACs and a mixer.
17222 * Each ADC is connected from a mixer of all inputs. This makes possible
17223 * 6-channel independent captures.
17224 *
17225 * In addition, an independent DAC for the multi-playback (not used in this
17226 * driver yet).
17227 */
17228#define ALC662_DIGOUT_NID 0x06
17229#define ALC662_DIGIN_NID 0x0a
17230
17231static hda_nid_t alc662_dac_nids[4] = {
17232 /* front, rear, clfe, rear_surr */
17233 0x02, 0x03, 0x04
17234};
17235
622e84cd
KY
17236static hda_nid_t alc272_dac_nids[2] = {
17237 0x02, 0x03
17238};
17239
b59bdf3b 17240static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17241 /* ADC1-2 */
b59bdf3b 17242 0x09, 0x08
bc9f98a9 17243};
e1406348 17244
622e84cd
KY
17245static hda_nid_t alc272_adc_nids[1] = {
17246 /* ADC1-2 */
17247 0x08,
17248};
17249
b59bdf3b 17250static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17251static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17252
e1406348 17253
bc9f98a9
KY
17254/* input MUX */
17255/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17256static struct hda_input_mux alc662_capture_source = {
17257 .num_items = 4,
17258 .items = {
17259 { "Mic", 0x0 },
17260 { "Front Mic", 0x1 },
17261 { "Line", 0x2 },
17262 { "CD", 0x4 },
17263 },
17264};
17265
17266static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17267 .num_items = 2,
17268 .items = {
17269 { "Mic", 0x1 },
17270 { "Line", 0x2 },
17271 },
17272};
291702f0 17273
6dda9f4a
KY
17274static struct hda_input_mux alc663_capture_source = {
17275 .num_items = 3,
17276 .items = {
17277 { "Mic", 0x0 },
17278 { "Front Mic", 0x1 },
17279 { "Line", 0x2 },
17280 },
17281};
17282
4f5d1706 17283#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17284static struct hda_input_mux alc272_nc10_capture_source = {
17285 .num_items = 16,
17286 .items = {
17287 { "Autoselect Mic", 0x0 },
17288 { "Internal Mic", 0x1 },
17289 { "In-0x02", 0x2 },
17290 { "In-0x03", 0x3 },
17291 { "In-0x04", 0x4 },
17292 { "In-0x05", 0x5 },
17293 { "In-0x06", 0x6 },
17294 { "In-0x07", 0x7 },
17295 { "In-0x08", 0x8 },
17296 { "In-0x09", 0x9 },
17297 { "In-0x0a", 0x0a },
17298 { "In-0x0b", 0x0b },
17299 { "In-0x0c", 0x0c },
17300 { "In-0x0d", 0x0d },
17301 { "In-0x0e", 0x0e },
17302 { "In-0x0f", 0x0f },
17303 },
17304};
17305#endif
17306
bc9f98a9
KY
17307/*
17308 * 2ch mode
17309 */
17310static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17311 { 2, NULL }
17312};
17313
17314/*
17315 * 2ch mode
17316 */
17317static struct hda_verb alc662_3ST_ch2_init[] = {
17318 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17319 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17320 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17321 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17322 { } /* end */
17323};
17324
17325/*
17326 * 6ch mode
17327 */
17328static struct hda_verb alc662_3ST_ch6_init[] = {
17329 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17330 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17331 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17332 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17333 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17334 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17335 { } /* end */
17336};
17337
17338static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17339 { 2, alc662_3ST_ch2_init },
17340 { 6, alc662_3ST_ch6_init },
17341};
17342
17343/*
17344 * 2ch mode
17345 */
17346static struct hda_verb alc662_sixstack_ch6_init[] = {
17347 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17348 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17349 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17350 { } /* end */
17351};
17352
17353/*
17354 * 6ch mode
17355 */
17356static struct hda_verb alc662_sixstack_ch8_init[] = {
17357 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17358 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17359 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17360 { } /* end */
17361};
17362
17363static struct hda_channel_mode alc662_5stack_modes[2] = {
17364 { 2, alc662_sixstack_ch6_init },
17365 { 6, alc662_sixstack_ch8_init },
17366};
17367
17368/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17369 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17370 */
17371
17372static struct snd_kcontrol_new alc662_base_mixer[] = {
17373 /* output mixer control */
17374 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17375 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17376 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17377 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17378 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17379 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17380 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17381 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17383
17384 /*Input mixer control */
17385 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17386 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17387 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17388 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17389 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17390 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17391 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17392 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17393 { } /* end */
17394};
17395
17396static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17397 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17398 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17401 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17402 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17403 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17406 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17407 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17408 { } /* end */
17409};
17410
17411static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17412 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17413 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17414 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17415 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17416 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17417 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17418 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17419 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17421 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17422 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17427 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17428 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17429 { } /* end */
17430};
17431
17432static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17433 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17434 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17435 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17436 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17438 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17439 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17441 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17442 { } /* end */
17443};
17444
291702f0 17445static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17446 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17447 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
17448
17449 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17450 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17451 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17452
17453 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17454 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17455 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17456 { } /* end */
17457};
17458
8c427226 17459static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17460 ALC262_HIPPO_MASTER_SWITCH,
17461 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17462 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17463 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17464 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17465 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17466 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17467 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17470 { } /* end */
17471};
17472
f1d4e28b
KY
17473static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17474 .ops = &snd_hda_bind_vol,
17475 .values = {
17476 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17477 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17478 0
17479 },
17480};
17481
17482static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17483 .ops = &snd_hda_bind_sw,
17484 .values = {
17485 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17486 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17487 0
17488 },
17489};
17490
6dda9f4a 17491static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17492 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17493 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17495 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17496 { } /* end */
17497};
17498
17499static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17500 .ops = &snd_hda_bind_sw,
17501 .values = {
17502 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17503 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17504 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17505 0
17506 },
17507};
17508
17509static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17510 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17511 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17512 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17513 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17514 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17515 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17516
17517 { } /* end */
17518};
17519
17520static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17521 .ops = &snd_hda_bind_sw,
17522 .values = {
17523 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17524 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17525 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17526 0
17527 },
17528};
17529
17530static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17531 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17532 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17535 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17536 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17537 { } /* end */
17538};
17539
17540static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17541 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17542 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17544 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17546 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17547 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17548 { } /* end */
17549};
17550
17551static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17552 .ops = &snd_hda_bind_vol,
17553 .values = {
17554 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17555 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17556 0
17557 },
17558};
17559
17560static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17561 .ops = &snd_hda_bind_sw,
17562 .values = {
17563 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17564 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17565 0
17566 },
17567};
17568
17569static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17570 HDA_BIND_VOL("Master Playback Volume",
17571 &alc663_asus_two_bind_master_vol),
17572 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17577 { } /* end */
17578};
17579
17580static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17581 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17582 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17583 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17587 { } /* end */
17588};
17589
17590static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17591 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17592 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17593 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17594 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17595 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17596
17597 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17598 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17599 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17600 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17601 { } /* end */
17602};
17603
17604static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17605 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17606 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17607 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17608
17609 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17611 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17612 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17613 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17614 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17615 { } /* end */
17616};
17617
ebb83eeb
KY
17618static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17619 .ops = &snd_hda_bind_sw,
17620 .values = {
17621 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17622 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17623 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17624 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17625 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17626 0
17627 },
17628};
17629
17630static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17631 .ops = &snd_hda_bind_sw,
17632 .values = {
17633 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17634 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17635 0
17636 },
17637};
17638
17639static struct snd_kcontrol_new alc663_mode7_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", 0x1b, 0x0, HDA_OUTPUT),
17644 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17645 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17646 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17649 { } /* end */
17650};
17651
17652static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17653 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17654 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17655 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17656 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17657 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17658 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17659 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17660 { } /* end */
17661};
17662
17663
bc9f98a9
KY
17664static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17665 {
17666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17667 .name = "Channel Mode",
17668 .info = alc_ch_mode_info,
17669 .get = alc_ch_mode_get,
17670 .put = alc_ch_mode_put,
17671 },
17672 { } /* end */
17673};
17674
17675static struct hda_verb alc662_init_verbs[] = {
17676 /* ADC: mute amp left and right */
17677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17678 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17679
b60dd394
KY
17680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17682 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17683 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17684 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17685 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17686
17687 /* Front Pin: output 0 (0x0c) */
17688 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17689 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17690
17691 /* Rear Pin: output 1 (0x0d) */
17692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17694
17695 /* CLFE Pin: output 2 (0x0e) */
17696 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17697 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17698
17699 /* Mic (rear) pin: input vref at 80% */
17700 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17701 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17702 /* Front Mic pin: input vref at 80% */
17703 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17705 /* Line In pin: input */
17706 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17708 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17711 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17712 /* CD pin widget for input */
17713 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17714
17715 /* FIXME: use matrix-type input source selection */
17716 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17717 /* Input mixer */
17718 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17720
17721 /* always trun on EAPD */
17722 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17723 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17724
bc9f98a9
KY
17725 { }
17726};
17727
cec27c89
KY
17728static struct hda_verb alc663_init_verbs[] = {
17729 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17730 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17731 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17732 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17733 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17734 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17735 { }
17736};
17737
17738static struct hda_verb alc272_init_verbs[] = {
17739 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17740 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17741 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17742 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17743 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17744 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17745 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17746 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17747 { }
17748};
17749
bc9f98a9
KY
17750static struct hda_verb alc662_sue_init_verbs[] = {
17751 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17752 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17753 {}
17754};
17755
17756static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17757 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17758 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17759 {}
bc9f98a9
KY
17760};
17761
8c427226
KY
17762/* Set Unsolicited Event*/
17763static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17764 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17765 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17766 {}
17767};
17768
6dda9f4a 17769static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17771 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17772 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17773 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17774 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17777 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17778 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17779 {}
17780};
17781
17782static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17783 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17784 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17785 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17786 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17788 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17789 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17790 {}
17791};
17792
17793static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17794 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17795 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17796 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17797 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17798 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17799 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17800 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17801 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17802 {}
17803};
6dda9f4a 17804
f1d4e28b
KY
17805static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17808 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17809 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17810 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17811 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17812 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17813 {}
17814};
6dda9f4a 17815
f1d4e28b
KY
17816static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17817 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17818 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17819 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17820 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17821 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17823 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17826 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17827 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17828 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17829 {}
17830};
17831
17832static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17833 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17834 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17835 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17836 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17837 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17838 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17839 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17840 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17842 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17843 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17844 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17845 {}
17846};
17847
17848static struct hda_verb alc663_g71v_init_verbs[] = {
17849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17850 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17851 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17852
17853 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17854 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17855 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17856
17857 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17858 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17859 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17860 {}
17861};
17862
17863static struct hda_verb alc663_g50v_init_verbs[] = {
17864 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17865 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17866 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17867
17868 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17869 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17870 {}
17871};
17872
f1d4e28b
KY
17873static struct hda_verb alc662_ecs_init_verbs[] = {
17874 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17875 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17876 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17877 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17878 {}
17879};
17880
622e84cd
KY
17881static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17882 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17883 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17885 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17886 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17887 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17888 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17889 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17890 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17891 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17892 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17893 {}
17894};
17895
17896static struct hda_verb alc272_dell_init_verbs[] = {
17897 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17898 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17899 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17900 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17901 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17902 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17903 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17904 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17906 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17907 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17908 {}
17909};
17910
ebb83eeb
KY
17911static struct hda_verb alc663_mode7_init_verbs[] = {
17912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17913 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17914 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17915 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17916 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17917 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17918 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17919 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17920 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17921 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17923 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17924 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17925 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17926 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17927 {}
17928};
17929
17930static struct hda_verb alc663_mode8_init_verbs[] = {
17931 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17932 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17933 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17934 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17935 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17936 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17937 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17939 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17940 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17941 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17942 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17943 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17944 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17945 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17946 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17947 {}
17948};
17949
f1d4e28b
KY
17950static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17951 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17952 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17953 { } /* end */
17954};
17955
622e84cd
KY
17956static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17957 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17958 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17959 { } /* end */
17960};
17961
bc9f98a9
KY
17962static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17963{
17964 unsigned int present;
f12ab1e0 17965 unsigned char bits;
bc9f98a9 17966
864f92be 17967 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17968 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17969
47fd830a
TI
17970 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17971 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17972}
17973
17974static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17975{
17976 unsigned int present;
f12ab1e0 17977 unsigned char bits;
bc9f98a9 17978
864f92be 17979 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17980 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17981
47fd830a
TI
17982 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17983 HDA_AMP_MUTE, bits);
17984 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17985 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17986}
17987
17988static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17989 unsigned int res)
17990{
17991 if ((res >> 26) == ALC880_HP_EVENT)
17992 alc662_lenovo_101e_all_automute(codec);
17993 if ((res >> 26) == ALC880_FRONT_EVENT)
17994 alc662_lenovo_101e_ispeaker_automute(codec);
17995}
17996
291702f0
KY
17997/* unsolicited event for HP jack sensing */
17998static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17999 unsigned int res)
18000{
291702f0 18001 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18002 alc_mic_automute(codec);
42171c17
TI
18003 else
18004 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18005}
18006
4f5d1706
TI
18007static void alc662_eeepc_setup(struct hda_codec *codec)
18008{
18009 struct alc_spec *spec = codec->spec;
18010
18011 alc262_hippo1_setup(codec);
18012 spec->ext_mic.pin = 0x18;
18013 spec->ext_mic.mux_idx = 0;
18014 spec->int_mic.pin = 0x19;
18015 spec->int_mic.mux_idx = 1;
18016 spec->auto_mic = 1;
18017}
18018
291702f0
KY
18019static void alc662_eeepc_inithook(struct hda_codec *codec)
18020{
4f5d1706
TI
18021 alc262_hippo_automute(codec);
18022 alc_mic_automute(codec);
291702f0
KY
18023}
18024
4f5d1706 18025static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18026{
42171c17
TI
18027 struct alc_spec *spec = codec->spec;
18028
18029 spec->autocfg.hp_pins[0] = 0x14;
18030 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18031}
18032
4f5d1706
TI
18033#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18034
6dda9f4a
KY
18035static void alc663_m51va_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);
6dda9f4a 18041 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 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
KY
18046}
18047
18048static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18049{
18050 unsigned int present;
18051 unsigned char bits;
18052
864f92be 18053 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18054 bits = present ? HDA_AMP_MUTE : 0;
18055 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18056 HDA_AMP_MUTE, bits);
f1d4e28b 18057 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18058 HDA_AMP_MUTE, bits);
f1d4e28b 18059 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18060 HDA_AMP_MUTE, bits);
f1d4e28b 18061 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18062 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18063}
18064
18065static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18066{
18067 unsigned int present;
18068 unsigned char bits;
18069
864f92be 18070 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18071 bits = present ? HDA_AMP_MUTE : 0;
18072 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18073 HDA_AMP_MUTE, bits);
f1d4e28b 18074 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18075 HDA_AMP_MUTE, bits);
f1d4e28b 18076 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18077 HDA_AMP_MUTE, bits);
f1d4e28b 18078 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18079 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18080}
18081
18082static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18083{
18084 unsigned int present;
18085 unsigned char bits;
18086
864f92be 18087 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18088 bits = present ? 0 : PIN_OUT;
18089 snd_hda_codec_write(codec, 0x14, 0,
18090 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18091}
18092
18093static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18094{
18095 unsigned int present1, present2;
18096
864f92be
WF
18097 present1 = snd_hda_jack_detect(codec, 0x21);
18098 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18099
18100 if (present1 || present2) {
18101 snd_hda_codec_write_cache(codec, 0x14, 0,
18102 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18103 } else {
18104 snd_hda_codec_write_cache(codec, 0x14, 0,
18105 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18106 }
18107}
18108
18109static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18110{
18111 unsigned int present1, present2;
18112
864f92be
WF
18113 present1 = snd_hda_jack_detect(codec, 0x1b);
18114 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18115
18116 if (present1 || present2) {
18117 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18118 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18119 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18120 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18121 } else {
18122 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18123 HDA_AMP_MUTE, 0);
f1d4e28b 18124 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18125 HDA_AMP_MUTE, 0);
f1d4e28b 18126 }
6dda9f4a
KY
18127}
18128
ebb83eeb
KY
18129static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18130{
18131 unsigned int present1, present2;
18132
18133 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18134 AC_VERB_GET_PIN_SENSE, 0)
18135 & AC_PINSENSE_PRESENCE;
18136 present2 = snd_hda_codec_read(codec, 0x21, 0,
18137 AC_VERB_GET_PIN_SENSE, 0)
18138 & AC_PINSENSE_PRESENCE;
18139
18140 if (present1 || present2) {
18141 snd_hda_codec_write_cache(codec, 0x14, 0,
18142 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18143 snd_hda_codec_write_cache(codec, 0x17, 0,
18144 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18145 } else {
18146 snd_hda_codec_write_cache(codec, 0x14, 0,
18147 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18148 snd_hda_codec_write_cache(codec, 0x17, 0,
18149 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18150 }
18151}
18152
18153static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18154{
18155 unsigned int present1, present2;
18156
18157 present1 = snd_hda_codec_read(codec, 0x21, 0,
18158 AC_VERB_GET_PIN_SENSE, 0)
18159 & AC_PINSENSE_PRESENCE;
18160 present2 = snd_hda_codec_read(codec, 0x15, 0,
18161 AC_VERB_GET_PIN_SENSE, 0)
18162 & AC_PINSENSE_PRESENCE;
18163
18164 if (present1 || present2) {
18165 snd_hda_codec_write_cache(codec, 0x14, 0,
18166 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18167 snd_hda_codec_write_cache(codec, 0x17, 0,
18168 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18169 } else {
18170 snd_hda_codec_write_cache(codec, 0x14, 0,
18171 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18172 snd_hda_codec_write_cache(codec, 0x17, 0,
18173 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18174 }
18175}
18176
6dda9f4a
KY
18177static void alc663_m51va_unsol_event(struct hda_codec *codec,
18178 unsigned int res)
18179{
18180 switch (res >> 26) {
18181 case ALC880_HP_EVENT:
18182 alc663_m51va_speaker_automute(codec);
18183 break;
18184 case ALC880_MIC_EVENT:
4f5d1706 18185 alc_mic_automute(codec);
6dda9f4a
KY
18186 break;
18187 }
18188}
18189
4f5d1706
TI
18190static void alc663_m51va_setup(struct hda_codec *codec)
18191{
18192 struct alc_spec *spec = codec->spec;
18193 spec->ext_mic.pin = 0x18;
18194 spec->ext_mic.mux_idx = 0;
18195 spec->int_mic.pin = 0x12;
ebb83eeb 18196 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18197 spec->auto_mic = 1;
18198}
18199
6dda9f4a
KY
18200static void alc663_m51va_inithook(struct hda_codec *codec)
18201{
18202 alc663_m51va_speaker_automute(codec);
4f5d1706 18203 alc_mic_automute(codec);
6dda9f4a
KY
18204}
18205
f1d4e28b 18206/* ***************** Mode1 ******************************/
4f5d1706 18207#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18208
18209static void alc663_mode1_setup(struct hda_codec *codec)
18210{
18211 struct alc_spec *spec = codec->spec;
18212 spec->ext_mic.pin = 0x18;
18213 spec->ext_mic.mux_idx = 0;
18214 spec->int_mic.pin = 0x19;
18215 spec->int_mic.mux_idx = 1;
18216 spec->auto_mic = 1;
18217}
18218
4f5d1706 18219#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18220
f1d4e28b
KY
18221/* ***************** Mode2 ******************************/
18222static void alc662_mode2_unsol_event(struct hda_codec *codec,
18223 unsigned int res)
18224{
18225 switch (res >> 26) {
18226 case ALC880_HP_EVENT:
18227 alc662_f5z_speaker_automute(codec);
18228 break;
18229 case ALC880_MIC_EVENT:
4f5d1706 18230 alc_mic_automute(codec);
f1d4e28b
KY
18231 break;
18232 }
18233}
18234
ebb83eeb 18235#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18236
f1d4e28b
KY
18237static void alc662_mode2_inithook(struct hda_codec *codec)
18238{
18239 alc662_f5z_speaker_automute(codec);
4f5d1706 18240 alc_mic_automute(codec);
f1d4e28b
KY
18241}
18242/* ***************** Mode3 ******************************/
18243static void alc663_mode3_unsol_event(struct hda_codec *codec,
18244 unsigned int res)
18245{
18246 switch (res >> 26) {
18247 case ALC880_HP_EVENT:
18248 alc663_two_hp_m1_speaker_automute(codec);
18249 break;
18250 case ALC880_MIC_EVENT:
4f5d1706 18251 alc_mic_automute(codec);
f1d4e28b
KY
18252 break;
18253 }
18254}
18255
ebb83eeb 18256#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18257
f1d4e28b
KY
18258static void alc663_mode3_inithook(struct hda_codec *codec)
18259{
18260 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18261 alc_mic_automute(codec);
f1d4e28b
KY
18262}
18263/* ***************** Mode4 ******************************/
18264static void alc663_mode4_unsol_event(struct hda_codec *codec,
18265 unsigned int res)
18266{
18267 switch (res >> 26) {
18268 case ALC880_HP_EVENT:
18269 alc663_21jd_two_speaker_automute(codec);
18270 break;
18271 case ALC880_MIC_EVENT:
4f5d1706 18272 alc_mic_automute(codec);
f1d4e28b
KY
18273 break;
18274 }
18275}
18276
ebb83eeb 18277#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18278
f1d4e28b
KY
18279static void alc663_mode4_inithook(struct hda_codec *codec)
18280{
18281 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18282 alc_mic_automute(codec);
f1d4e28b
KY
18283}
18284/* ***************** Mode5 ******************************/
18285static void alc663_mode5_unsol_event(struct hda_codec *codec,
18286 unsigned int res)
18287{
18288 switch (res >> 26) {
18289 case ALC880_HP_EVENT:
18290 alc663_15jd_two_speaker_automute(codec);
18291 break;
18292 case ALC880_MIC_EVENT:
4f5d1706 18293 alc_mic_automute(codec);
f1d4e28b
KY
18294 break;
18295 }
18296}
18297
ebb83eeb 18298#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18299
f1d4e28b
KY
18300static void alc663_mode5_inithook(struct hda_codec *codec)
18301{
18302 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18303 alc_mic_automute(codec);
f1d4e28b
KY
18304}
18305/* ***************** Mode6 ******************************/
18306static void alc663_mode6_unsol_event(struct hda_codec *codec,
18307 unsigned int res)
18308{
18309 switch (res >> 26) {
18310 case ALC880_HP_EVENT:
18311 alc663_two_hp_m2_speaker_automute(codec);
18312 break;
18313 case ALC880_MIC_EVENT:
4f5d1706 18314 alc_mic_automute(codec);
f1d4e28b
KY
18315 break;
18316 }
18317}
18318
ebb83eeb 18319#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18320
f1d4e28b
KY
18321static void alc663_mode6_inithook(struct hda_codec *codec)
18322{
18323 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18324 alc_mic_automute(codec);
f1d4e28b
KY
18325}
18326
ebb83eeb
KY
18327/* ***************** Mode7 ******************************/
18328static void alc663_mode7_unsol_event(struct hda_codec *codec,
18329 unsigned int res)
18330{
18331 switch (res >> 26) {
18332 case ALC880_HP_EVENT:
18333 alc663_two_hp_m7_speaker_automute(codec);
18334 break;
18335 case ALC880_MIC_EVENT:
18336 alc_mic_automute(codec);
18337 break;
18338 }
18339}
18340
18341#define alc663_mode7_setup alc663_mode1_setup
18342
18343static void alc663_mode7_inithook(struct hda_codec *codec)
18344{
18345 alc663_two_hp_m7_speaker_automute(codec);
18346 alc_mic_automute(codec);
18347}
18348
18349/* ***************** Mode8 ******************************/
18350static void alc663_mode8_unsol_event(struct hda_codec *codec,
18351 unsigned int res)
18352{
18353 switch (res >> 26) {
18354 case ALC880_HP_EVENT:
18355 alc663_two_hp_m8_speaker_automute(codec);
18356 break;
18357 case ALC880_MIC_EVENT:
18358 alc_mic_automute(codec);
18359 break;
18360 }
18361}
18362
18363#define alc663_mode8_setup alc663_m51va_setup
18364
18365static void alc663_mode8_inithook(struct hda_codec *codec)
18366{
18367 alc663_two_hp_m8_speaker_automute(codec);
18368 alc_mic_automute(codec);
18369}
18370
6dda9f4a
KY
18371static void alc663_g71v_hp_automute(struct hda_codec *codec)
18372{
18373 unsigned int present;
18374 unsigned char bits;
18375
864f92be 18376 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18377 bits = present ? HDA_AMP_MUTE : 0;
18378 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18379 HDA_AMP_MUTE, bits);
18380 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18381 HDA_AMP_MUTE, bits);
18382}
18383
18384static void alc663_g71v_front_automute(struct hda_codec *codec)
18385{
18386 unsigned int present;
18387 unsigned char bits;
18388
864f92be 18389 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18390 bits = present ? HDA_AMP_MUTE : 0;
18391 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18392 HDA_AMP_MUTE, bits);
18393}
18394
18395static void alc663_g71v_unsol_event(struct hda_codec *codec,
18396 unsigned int res)
18397{
18398 switch (res >> 26) {
18399 case ALC880_HP_EVENT:
18400 alc663_g71v_hp_automute(codec);
18401 break;
18402 case ALC880_FRONT_EVENT:
18403 alc663_g71v_front_automute(codec);
18404 break;
18405 case ALC880_MIC_EVENT:
4f5d1706 18406 alc_mic_automute(codec);
6dda9f4a
KY
18407 break;
18408 }
18409}
18410
4f5d1706
TI
18411#define alc663_g71v_setup alc663_m51va_setup
18412
6dda9f4a
KY
18413static void alc663_g71v_inithook(struct hda_codec *codec)
18414{
18415 alc663_g71v_front_automute(codec);
18416 alc663_g71v_hp_automute(codec);
4f5d1706 18417 alc_mic_automute(codec);
6dda9f4a
KY
18418}
18419
18420static void alc663_g50v_unsol_event(struct hda_codec *codec,
18421 unsigned int res)
18422{
18423 switch (res >> 26) {
18424 case ALC880_HP_EVENT:
18425 alc663_m51va_speaker_automute(codec);
18426 break;
18427 case ALC880_MIC_EVENT:
4f5d1706 18428 alc_mic_automute(codec);
6dda9f4a
KY
18429 break;
18430 }
18431}
18432
4f5d1706
TI
18433#define alc663_g50v_setup alc663_m51va_setup
18434
6dda9f4a
KY
18435static void alc663_g50v_inithook(struct hda_codec *codec)
18436{
18437 alc663_m51va_speaker_automute(codec);
4f5d1706 18438 alc_mic_automute(codec);
6dda9f4a
KY
18439}
18440
f1d4e28b
KY
18441static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18442 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18443 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
18444
18445 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18446 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18447 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18448
18449 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18450 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18451 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18452 { } /* end */
18453};
18454
9541ba1d
CP
18455static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18456 /* Master Playback automatically created from Speaker and Headphone */
18457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18458 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18459 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18461
18462 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18463 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18464 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18465
18466 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18467 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18468 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18469 { } /* end */
18470};
18471
cb53c626
TI
18472#ifdef CONFIG_SND_HDA_POWER_SAVE
18473#define alc662_loopbacks alc880_loopbacks
18474#endif
18475
bc9f98a9 18476
def319f9 18477/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18478#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18479#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18480#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18481#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18482
18483/*
18484 * configuration and preset
18485 */
18486static const char *alc662_models[ALC662_MODEL_LAST] = {
18487 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18488 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18489 [ALC662_3ST_6ch] = "3stack-6ch",
18490 [ALC662_5ST_DIG] = "6stack-dig",
18491 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18492 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18493 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18494 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18495 [ALC663_ASUS_M51VA] = "m51va",
18496 [ALC663_ASUS_G71V] = "g71v",
18497 [ALC663_ASUS_H13] = "h13",
18498 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18499 [ALC663_ASUS_MODE1] = "asus-mode1",
18500 [ALC662_ASUS_MODE2] = "asus-mode2",
18501 [ALC663_ASUS_MODE3] = "asus-mode3",
18502 [ALC663_ASUS_MODE4] = "asus-mode4",
18503 [ALC663_ASUS_MODE5] = "asus-mode5",
18504 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18505 [ALC663_ASUS_MODE7] = "asus-mode7",
18506 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18507 [ALC272_DELL] = "dell",
18508 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18509 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18510 [ALC662_AUTO] = "auto",
18511};
18512
18513static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18514 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18515 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18516 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18517 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18518 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18519 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18520 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18521 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18522 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18523 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18524 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18525 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18526 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18527 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18528 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18529 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18530 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18531 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18532 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18533 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18534 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18535 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18536 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18537 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18538 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18539 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18540 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18541 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18542 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18543 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18544 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18545 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18546 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18547 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18548 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18549 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18550 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18551 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18552 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18553 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18554 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18555 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18556 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18557 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18558 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18559 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18560 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18561 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18562 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18563 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18564 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18565 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18566 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18567 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18568 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18569 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18570 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18571 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18572 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18573 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18574 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18575 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18576 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18577 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18578 ALC662_3ST_6ch_DIG),
4dee8baa 18579 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18580 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18581 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18582 ALC662_3ST_6ch_DIG),
6227cdce 18583 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18584 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18585 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18586 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18587 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18588 ALC662_3ST_6ch_DIG),
dea0a509
TI
18589 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18590 ALC663_ASUS_H13),
bc9f98a9
KY
18591 {}
18592};
18593
18594static struct alc_config_preset alc662_presets[] = {
18595 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18596 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18597 .init_verbs = { alc662_init_verbs },
18598 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18599 .dac_nids = alc662_dac_nids,
18600 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18601 .dig_in_nid = ALC662_DIGIN_NID,
18602 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18603 .channel_mode = alc662_3ST_2ch_modes,
18604 .input_mux = &alc662_capture_source,
18605 },
18606 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18607 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18608 .init_verbs = { alc662_init_verbs },
18609 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18610 .dac_nids = alc662_dac_nids,
18611 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18612 .dig_in_nid = ALC662_DIGIN_NID,
18613 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18614 .channel_mode = alc662_3ST_6ch_modes,
18615 .need_dac_fix = 1,
18616 .input_mux = &alc662_capture_source,
f12ab1e0 18617 },
bc9f98a9 18618 [ALC662_3ST_6ch] = {
f9e336f6 18619 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18620 .init_verbs = { alc662_init_verbs },
18621 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18622 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18623 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18624 .channel_mode = alc662_3ST_6ch_modes,
18625 .need_dac_fix = 1,
18626 .input_mux = &alc662_capture_source,
f12ab1e0 18627 },
bc9f98a9 18628 [ALC662_5ST_DIG] = {
f9e336f6 18629 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18630 .init_verbs = { alc662_init_verbs },
18631 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18632 .dac_nids = alc662_dac_nids,
18633 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18634 .dig_in_nid = ALC662_DIGIN_NID,
18635 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18636 .channel_mode = alc662_5stack_modes,
18637 .input_mux = &alc662_capture_source,
18638 },
18639 [ALC662_LENOVO_101E] = {
f9e336f6 18640 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18641 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18642 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18643 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18644 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18645 .channel_mode = alc662_3ST_2ch_modes,
18646 .input_mux = &alc662_lenovo_101e_capture_source,
18647 .unsol_event = alc662_lenovo_101e_unsol_event,
18648 .init_hook = alc662_lenovo_101e_all_automute,
18649 },
291702f0 18650 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18651 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18652 .init_verbs = { alc662_init_verbs,
18653 alc662_eeepc_sue_init_verbs },
18654 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18655 .dac_nids = alc662_dac_nids,
291702f0
KY
18656 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18657 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18658 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18659 .setup = alc662_eeepc_setup,
291702f0
KY
18660 .init_hook = alc662_eeepc_inithook,
18661 },
8c427226 18662 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18663 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18664 alc662_chmode_mixer },
18665 .init_verbs = { alc662_init_verbs,
18666 alc662_eeepc_ep20_sue_init_verbs },
18667 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18668 .dac_nids = alc662_dac_nids,
8c427226
KY
18669 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18670 .channel_mode = alc662_3ST_6ch_modes,
18671 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18672 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18673 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18674 .init_hook = alc662_eeepc_ep20_inithook,
18675 },
f1d4e28b 18676 [ALC662_ECS] = {
f9e336f6 18677 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18678 .init_verbs = { alc662_init_verbs,
18679 alc662_ecs_init_verbs },
18680 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18681 .dac_nids = alc662_dac_nids,
18682 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18683 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18684 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18685 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18686 .init_hook = alc662_eeepc_inithook,
18687 },
6dda9f4a 18688 [ALC663_ASUS_M51VA] = {
f9e336f6 18689 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18690 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18691 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18692 .dac_nids = alc662_dac_nids,
18693 .dig_out_nid = ALC662_DIGOUT_NID,
18694 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18695 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18696 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18697 .setup = alc663_m51va_setup,
6dda9f4a
KY
18698 .init_hook = alc663_m51va_inithook,
18699 },
18700 [ALC663_ASUS_G71V] = {
f9e336f6 18701 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18702 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18703 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18704 .dac_nids = alc662_dac_nids,
18705 .dig_out_nid = ALC662_DIGOUT_NID,
18706 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18707 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18708 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18709 .setup = alc663_g71v_setup,
6dda9f4a
KY
18710 .init_hook = alc663_g71v_inithook,
18711 },
18712 [ALC663_ASUS_H13] = {
f9e336f6 18713 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18714 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18715 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18716 .dac_nids = alc662_dac_nids,
18717 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18718 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18719 .unsol_event = alc663_m51va_unsol_event,
18720 .init_hook = alc663_m51va_inithook,
18721 },
18722 [ALC663_ASUS_G50V] = {
f9e336f6 18723 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18724 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18725 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18726 .dac_nids = alc662_dac_nids,
18727 .dig_out_nid = ALC662_DIGOUT_NID,
18728 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18729 .channel_mode = alc662_3ST_6ch_modes,
18730 .input_mux = &alc663_capture_source,
18731 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18732 .setup = alc663_g50v_setup,
6dda9f4a
KY
18733 .init_hook = alc663_g50v_inithook,
18734 },
f1d4e28b 18735 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18736 .mixers = { alc663_m51va_mixer },
18737 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18738 .init_verbs = { alc662_init_verbs,
18739 alc663_21jd_amic_init_verbs },
18740 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18741 .hp_nid = 0x03,
18742 .dac_nids = alc662_dac_nids,
18743 .dig_out_nid = ALC662_DIGOUT_NID,
18744 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18745 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18746 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18747 .setup = alc663_mode1_setup,
f1d4e28b
KY
18748 .init_hook = alc663_mode1_inithook,
18749 },
18750 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18751 .mixers = { alc662_1bjd_mixer },
18752 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18753 .init_verbs = { alc662_init_verbs,
18754 alc662_1bjd_amic_init_verbs },
18755 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18756 .dac_nids = alc662_dac_nids,
18757 .dig_out_nid = ALC662_DIGOUT_NID,
18758 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18759 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18760 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18761 .setup = alc662_mode2_setup,
f1d4e28b
KY
18762 .init_hook = alc662_mode2_inithook,
18763 },
18764 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18765 .mixers = { alc663_two_hp_m1_mixer },
18766 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18767 .init_verbs = { alc662_init_verbs,
18768 alc663_two_hp_amic_m1_init_verbs },
18769 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18770 .hp_nid = 0x03,
18771 .dac_nids = alc662_dac_nids,
18772 .dig_out_nid = ALC662_DIGOUT_NID,
18773 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18774 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18775 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18776 .setup = alc663_mode3_setup,
f1d4e28b
KY
18777 .init_hook = alc663_mode3_inithook,
18778 },
18779 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18780 .mixers = { alc663_asus_21jd_clfe_mixer },
18781 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18782 .init_verbs = { alc662_init_verbs,
18783 alc663_21jd_amic_init_verbs},
18784 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18785 .hp_nid = 0x03,
18786 .dac_nids = alc662_dac_nids,
18787 .dig_out_nid = ALC662_DIGOUT_NID,
18788 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18789 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18790 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18791 .setup = alc663_mode4_setup,
f1d4e28b
KY
18792 .init_hook = alc663_mode4_inithook,
18793 },
18794 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18795 .mixers = { alc663_asus_15jd_clfe_mixer },
18796 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18797 .init_verbs = { alc662_init_verbs,
18798 alc663_15jd_amic_init_verbs },
18799 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18800 .hp_nid = 0x03,
18801 .dac_nids = alc662_dac_nids,
18802 .dig_out_nid = ALC662_DIGOUT_NID,
18803 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18804 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18805 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18806 .setup = alc663_mode5_setup,
f1d4e28b
KY
18807 .init_hook = alc663_mode5_inithook,
18808 },
18809 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18810 .mixers = { alc663_two_hp_m2_mixer },
18811 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18812 .init_verbs = { alc662_init_verbs,
18813 alc663_two_hp_amic_m2_init_verbs },
18814 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18815 .hp_nid = 0x03,
18816 .dac_nids = alc662_dac_nids,
18817 .dig_out_nid = ALC662_DIGOUT_NID,
18818 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18819 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18820 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18821 .setup = alc663_mode6_setup,
f1d4e28b
KY
18822 .init_hook = alc663_mode6_inithook,
18823 },
ebb83eeb
KY
18824 [ALC663_ASUS_MODE7] = {
18825 .mixers = { alc663_mode7_mixer },
18826 .cap_mixer = alc662_auto_capture_mixer,
18827 .init_verbs = { alc662_init_verbs,
18828 alc663_mode7_init_verbs },
18829 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18830 .hp_nid = 0x03,
18831 .dac_nids = alc662_dac_nids,
18832 .dig_out_nid = ALC662_DIGOUT_NID,
18833 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18834 .channel_mode = alc662_3ST_2ch_modes,
18835 .unsol_event = alc663_mode7_unsol_event,
18836 .setup = alc663_mode7_setup,
18837 .init_hook = alc663_mode7_inithook,
18838 },
18839 [ALC663_ASUS_MODE8] = {
18840 .mixers = { alc663_mode8_mixer },
18841 .cap_mixer = alc662_auto_capture_mixer,
18842 .init_verbs = { alc662_init_verbs,
18843 alc663_mode8_init_verbs },
18844 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18845 .hp_nid = 0x03,
18846 .dac_nids = alc662_dac_nids,
18847 .dig_out_nid = ALC662_DIGOUT_NID,
18848 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18849 .channel_mode = alc662_3ST_2ch_modes,
18850 .unsol_event = alc663_mode8_unsol_event,
18851 .setup = alc663_mode8_setup,
18852 .init_hook = alc663_mode8_inithook,
18853 },
622e84cd
KY
18854 [ALC272_DELL] = {
18855 .mixers = { alc663_m51va_mixer },
18856 .cap_mixer = alc272_auto_capture_mixer,
18857 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18858 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18859 .dac_nids = alc662_dac_nids,
18860 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18861 .adc_nids = alc272_adc_nids,
18862 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18863 .capsrc_nids = alc272_capsrc_nids,
18864 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18865 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18866 .setup = alc663_m51va_setup,
622e84cd
KY
18867 .init_hook = alc663_m51va_inithook,
18868 },
18869 [ALC272_DELL_ZM1] = {
18870 .mixers = { alc663_m51va_mixer },
18871 .cap_mixer = alc662_auto_capture_mixer,
18872 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18873 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18874 .dac_nids = alc662_dac_nids,
18875 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18876 .adc_nids = alc662_adc_nids,
b59bdf3b 18877 .num_adc_nids = 1,
622e84cd
KY
18878 .capsrc_nids = alc662_capsrc_nids,
18879 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18880 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18881 .setup = alc663_m51va_setup,
622e84cd
KY
18882 .init_hook = alc663_m51va_inithook,
18883 },
9541ba1d
CP
18884 [ALC272_SAMSUNG_NC10] = {
18885 .mixers = { alc272_nc10_mixer },
18886 .init_verbs = { alc662_init_verbs,
18887 alc663_21jd_amic_init_verbs },
18888 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18889 .dac_nids = alc272_dac_nids,
18890 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18891 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18892 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18893 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18894 .setup = alc663_mode4_setup,
9541ba1d
CP
18895 .init_hook = alc663_mode4_inithook,
18896 },
bc9f98a9
KY
18897};
18898
18899
18900/*
18901 * BIOS auto configuration
18902 */
18903
7085ec12
TI
18904/* convert from MIX nid to DAC */
18905static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18906{
18907 if (nid == 0x0f)
18908 return 0x02;
18909 else if (nid >= 0x0c && nid <= 0x0e)
18910 return nid - 0x0c + 0x02;
18911 else
18912 return 0;
18913}
18914
18915/* get MIX nid connected to the given pin targeted to DAC */
18916static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18917 hda_nid_t dac)
18918{
18919 hda_nid_t mix[4];
18920 int i, num;
18921
18922 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18923 for (i = 0; i < num; i++) {
18924 if (alc662_mix_to_dac(mix[i]) == dac)
18925 return mix[i];
18926 }
18927 return 0;
18928}
18929
18930/* look for an empty DAC slot */
18931static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18932{
18933 struct alc_spec *spec = codec->spec;
18934 hda_nid_t srcs[5];
18935 int i, j, num;
18936
18937 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18938 if (num < 0)
18939 return 0;
18940 for (i = 0; i < num; i++) {
18941 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18942 if (!nid)
18943 continue;
18944 for (j = 0; j < spec->multiout.num_dacs; j++)
18945 if (spec->multiout.dac_nids[j] == nid)
18946 break;
18947 if (j >= spec->multiout.num_dacs)
18948 return nid;
18949 }
18950 return 0;
18951}
18952
18953/* fill in the dac_nids table from the parsed pin configuration */
18954static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18955 const struct auto_pin_cfg *cfg)
18956{
18957 struct alc_spec *spec = codec->spec;
18958 int i;
18959 hda_nid_t dac;
18960
18961 spec->multiout.dac_nids = spec->private_dac_nids;
18962 for (i = 0; i < cfg->line_outs; i++) {
18963 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18964 if (!dac)
18965 continue;
18966 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18967 }
18968 return 0;
18969}
18970
0afe5f89 18971static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18972 hda_nid_t nid, unsigned int chs)
18973{
0afe5f89 18974 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18975 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18976}
18977
0afe5f89 18978static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18979 hda_nid_t nid, unsigned int chs)
18980{
0afe5f89 18981 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18982 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18983}
18984
18985#define alc662_add_stereo_vol(spec, pfx, nid) \
18986 alc662_add_vol_ctl(spec, pfx, nid, 3)
18987#define alc662_add_stereo_sw(spec, pfx, nid) \
18988 alc662_add_sw_ctl(spec, pfx, nid, 3)
18989
bc9f98a9 18990/* add playback controls from the parsed DAC table */
7085ec12 18991static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18992 const struct auto_pin_cfg *cfg)
18993{
7085ec12 18994 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18995 static const char *chname[4] = {
18996 "Front", "Surround", NULL /*CLFE*/, "Side"
18997 };
7085ec12 18998 hda_nid_t nid, mix;
bc9f98a9
KY
18999 int i, err;
19000
19001 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19002 nid = spec->multiout.dac_nids[i];
19003 if (!nid)
19004 continue;
19005 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19006 if (!mix)
bc9f98a9 19007 continue;
bc9f98a9
KY
19008 if (i == 2) {
19009 /* Center/LFE */
7085ec12 19010 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19011 if (err < 0)
19012 return err;
7085ec12 19013 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19014 if (err < 0)
19015 return err;
7085ec12 19016 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19017 if (err < 0)
19018 return err;
7085ec12 19019 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19020 if (err < 0)
19021 return err;
19022 } else {
0d884cb9
TI
19023 const char *pfx;
19024 if (cfg->line_outs == 1 &&
19025 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 19026 if (cfg->hp_outs)
0d884cb9
TI
19027 pfx = "Speaker";
19028 else
19029 pfx = "PCM";
19030 } else
19031 pfx = chname[i];
7085ec12 19032 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
19033 if (err < 0)
19034 return err;
0d884cb9
TI
19035 if (cfg->line_outs == 1 &&
19036 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19037 pfx = "Speaker";
7085ec12 19038 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
19039 if (err < 0)
19040 return err;
19041 }
19042 }
19043 return 0;
19044}
19045
19046/* add playback controls for speaker and HP outputs */
7085ec12
TI
19047/* return DAC nid if any new DAC is assigned */
19048static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19049 const char *pfx)
19050{
7085ec12
TI
19051 struct alc_spec *spec = codec->spec;
19052 hda_nid_t nid, mix;
bc9f98a9 19053 int err;
bc9f98a9
KY
19054
19055 if (!pin)
19056 return 0;
7085ec12
TI
19057 nid = alc662_look_for_dac(codec, pin);
19058 if (!nid) {
7085ec12
TI
19059 /* the corresponding DAC is already occupied */
19060 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19061 return 0; /* no way */
19062 /* create a switch only */
0afe5f89 19063 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19064 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19065 }
19066
7085ec12
TI
19067 mix = alc662_dac_to_mix(codec, pin, nid);
19068 if (!mix)
19069 return 0;
19070 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19071 if (err < 0)
19072 return err;
19073 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19074 if (err < 0)
19075 return err;
19076 return nid;
bc9f98a9
KY
19077}
19078
19079/* create playback/capture controls for input pins */
05f5f477 19080#define alc662_auto_create_input_ctls \
4b7348a1 19081 alc882_auto_create_input_ctls
bc9f98a9
KY
19082
19083static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19084 hda_nid_t nid, int pin_type,
7085ec12 19085 hda_nid_t dac)
bc9f98a9 19086{
7085ec12 19087 int i, num;
ce503f38 19088 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19089
f6c7e546 19090 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19091 /* need the manual connection? */
7085ec12
TI
19092 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19093 if (num <= 1)
19094 return;
19095 for (i = 0; i < num; i++) {
19096 if (alc662_mix_to_dac(srcs[i]) != dac)
19097 continue;
19098 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19099 return;
bc9f98a9
KY
19100 }
19101}
19102
19103static void alc662_auto_init_multi_out(struct hda_codec *codec)
19104{
19105 struct alc_spec *spec = codec->spec;
7085ec12 19106 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19107 int i;
19108
19109 for (i = 0; i <= HDA_SIDE; i++) {
19110 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19111 if (nid)
baba8ee9 19112 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19113 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19114 }
19115}
19116
19117static void alc662_auto_init_hp_out(struct hda_codec *codec)
19118{
19119 struct alc_spec *spec = codec->spec;
19120 hda_nid_t pin;
19121
19122 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19123 if (pin)
19124 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19125 spec->multiout.hp_nid);
f6c7e546
TI
19126 pin = spec->autocfg.speaker_pins[0];
19127 if (pin)
7085ec12
TI
19128 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19129 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19130}
19131
bc9f98a9
KY
19132#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19133
19134static void alc662_auto_init_analog_input(struct hda_codec *codec)
19135{
19136 struct alc_spec *spec = codec->spec;
66ceeb6b 19137 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19138 int i;
19139
66ceeb6b
TI
19140 for (i = 0; i < cfg->num_inputs; i++) {
19141 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19142 if (alc_is_input_pin(codec, nid)) {
30ea098f 19143 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19144 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19145 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19146 snd_hda_codec_write(codec, nid, 0,
19147 AC_VERB_SET_AMP_GAIN_MUTE,
19148 AMP_OUT_MUTE);
19149 }
19150 }
19151}
19152
f511b01c
TI
19153#define alc662_auto_init_input_src alc882_auto_init_input_src
19154
bc9f98a9
KY
19155static int alc662_parse_auto_config(struct hda_codec *codec)
19156{
19157 struct alc_spec *spec = codec->spec;
19158 int err;
19159 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19160
19161 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19162 alc662_ignore);
19163 if (err < 0)
19164 return err;
19165 if (!spec->autocfg.line_outs)
19166 return 0; /* can't find valid BIOS pin config */
19167
7085ec12 19168 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19169 if (err < 0)
19170 return err;
7085ec12 19171 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19172 if (err < 0)
19173 return err;
7085ec12 19174 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19175 spec->autocfg.speaker_pins[0],
19176 "Speaker");
19177 if (err < 0)
19178 return err;
7085ec12
TI
19179 if (err)
19180 spec->multiout.extra_out_nid[0] = err;
19181 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19182 "Headphone");
19183 if (err < 0)
19184 return err;
7085ec12
TI
19185 if (err)
19186 spec->multiout.hp_nid = err;
05f5f477 19187 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19188 if (err < 0)
bc9f98a9
KY
19189 return err;
19190
19191 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19192
757899ac 19193 alc_auto_parse_digital(codec);
bc9f98a9 19194
603c4019 19195 if (spec->kctls.list)
d88897ea 19196 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19197
19198 spec->num_mux_defs = 1;
61b9b9b1 19199 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19200
cec27c89
KY
19201 add_verb(spec, alc662_init_verbs);
19202 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19203 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19204 add_verb(spec, alc663_init_verbs);
19205
19206 if (codec->vendor_id == 0x10ec0272)
19207 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19208
19209 err = alc_auto_add_mic_boost(codec);
19210 if (err < 0)
19211 return err;
19212
6227cdce
KY
19213 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19214 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19215 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19216 else
19217 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19218
8c87286f 19219 return 1;
bc9f98a9
KY
19220}
19221
19222/* additional initialization for auto-configuration model */
19223static void alc662_auto_init(struct hda_codec *codec)
19224{
f6c7e546 19225 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19226 alc662_auto_init_multi_out(codec);
19227 alc662_auto_init_hp_out(codec);
19228 alc662_auto_init_analog_input(codec);
f511b01c 19229 alc662_auto_init_input_src(codec);
757899ac 19230 alc_auto_init_digital(codec);
f6c7e546 19231 if (spec->unsol_event)
7fb0d78f 19232 alc_inithook(codec);
bc9f98a9
KY
19233}
19234
6cb3b707
DH
19235enum {
19236 ALC662_FIXUP_IDEAPAD,
19237};
19238
19239static const struct alc_fixup alc662_fixups[] = {
19240 [ALC662_FIXUP_IDEAPAD] = {
19241 .pins = (const struct alc_pincfg[]) {
19242 { 0x17, 0x99130112 }, /* subwoofer */
19243 { }
19244 }
19245 },
19246};
19247
19248static struct snd_pci_quirk alc662_fixup_tbl[] = {
19249 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19250 {}
19251};
19252
19253
19254
bc9f98a9
KY
19255static int patch_alc662(struct hda_codec *codec)
19256{
19257 struct alc_spec *spec;
19258 int err, board_config;
19259
19260 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19261 if (!spec)
19262 return -ENOMEM;
19263
19264 codec->spec = spec;
19265
da00c244
KY
19266 alc_auto_parse_customize_define(codec);
19267
2c3bf9ab
TI
19268 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19269
c027ddcd
KY
19270 if (alc_read_coef_idx(codec, 0) == 0x8020)
19271 alc_codec_rename(codec, "ALC661");
19272 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
19273 codec->bus->pci->subsystem_vendor == 0x1025 &&
19274 spec->cdefine.platform_type == 1)
19275 alc_codec_rename(codec, "ALC272X");
274693f3 19276
bc9f98a9
KY
19277 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19278 alc662_models,
19279 alc662_cfg_tbl);
19280 if (board_config < 0) {
9a11f1aa
TI
19281 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19282 codec->chip_name);
bc9f98a9
KY
19283 board_config = ALC662_AUTO;
19284 }
19285
19286 if (board_config == ALC662_AUTO) {
6cb3b707 19287 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1);
bc9f98a9
KY
19288 /* automatic parse from the BIOS config */
19289 err = alc662_parse_auto_config(codec);
19290 if (err < 0) {
19291 alc_free(codec);
19292 return err;
8c87286f 19293 } else if (!err) {
bc9f98a9
KY
19294 printk(KERN_INFO
19295 "hda_codec: Cannot set up configuration "
19296 "from BIOS. Using base mode...\n");
19297 board_config = ALC662_3ST_2ch_DIG;
19298 }
19299 }
19300
dc1eae25 19301 if (has_cdefine_beep(codec)) {
8af2591d
TI
19302 err = snd_hda_attach_beep_device(codec, 0x1);
19303 if (err < 0) {
19304 alc_free(codec);
19305 return err;
19306 }
680cd536
KK
19307 }
19308
bc9f98a9 19309 if (board_config != ALC662_AUTO)
e9c364c0 19310 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19311
bc9f98a9
KY
19312 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19313 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19314
bc9f98a9
KY
19315 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19316 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19317
dd704698
TI
19318 if (!spec->adc_nids) {
19319 spec->adc_nids = alc662_adc_nids;
19320 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19321 }
19322 if (!spec->capsrc_nids)
19323 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19324
f9e336f6 19325 if (!spec->cap_mixer)
b59bdf3b 19326 set_capture_mixer(codec);
cec27c89 19327
dc1eae25 19328 if (has_cdefine_beep(codec)) {
da00c244
KY
19329 switch (codec->vendor_id) {
19330 case 0x10ec0662:
19331 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19332 break;
19333 case 0x10ec0272:
19334 case 0x10ec0663:
19335 case 0x10ec0665:
19336 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19337 break;
19338 case 0x10ec0273:
19339 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19340 break;
19341 }
cec27c89 19342 }
2134ea4f
TI
19343 spec->vmaster_nid = 0x02;
19344
bc9f98a9 19345 codec->patch_ops = alc_patch_ops;
6cb3b707 19346 if (board_config == ALC662_AUTO) {
bc9f98a9 19347 spec->init_hook = alc662_auto_init;
6cb3b707
DH
19348 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0);
19349 }
19350
cb53c626
TI
19351#ifdef CONFIG_SND_HDA_POWER_SAVE
19352 if (!spec->loopback.amplist)
19353 spec->loopback.amplist = alc662_loopbacks;
19354#endif
bc9f98a9
KY
19355
19356 return 0;
19357}
19358
274693f3
KY
19359static int patch_alc888(struct hda_codec *codec)
19360{
19361 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19362 kfree(codec->chip_name);
19363 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19364 if (!codec->chip_name) {
19365 alc_free(codec);
274693f3 19366 return -ENOMEM;
ac2c92e0
TI
19367 }
19368 return patch_alc662(codec);
274693f3 19369 }
ac2c92e0 19370 return patch_alc882(codec);
274693f3
KY
19371}
19372
d1eb57f4
KY
19373/*
19374 * ALC680 support
19375 */
c69aefab 19376#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19377#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19378#define alc680_modes alc260_modes
19379
19380static hda_nid_t alc680_dac_nids[3] = {
19381 /* Lout1, Lout2, hp */
19382 0x02, 0x03, 0x04
19383};
19384
19385static hda_nid_t alc680_adc_nids[3] = {
19386 /* ADC0-2 */
19387 /* DMIC, MIC, Line-in*/
19388 0x07, 0x08, 0x09
19389};
19390
c69aefab
KY
19391/*
19392 * Analog capture ADC cgange
19393 */
66ceeb6b
TI
19394static void alc680_rec_autoswitch(struct hda_codec *codec)
19395{
19396 struct alc_spec *spec = codec->spec;
19397 struct auto_pin_cfg *cfg = &spec->autocfg;
19398 int pin_found = 0;
19399 int type_found = AUTO_PIN_LAST;
19400 hda_nid_t nid;
19401 int i;
19402
19403 for (i = 0; i < cfg->num_inputs; i++) {
19404 nid = cfg->inputs[i].pin;
19405 if (!(snd_hda_query_pin_caps(codec, nid) &
19406 AC_PINCAP_PRES_DETECT))
19407 continue;
19408 if (snd_hda_jack_detect(codec, nid)) {
19409 if (cfg->inputs[i].type < type_found) {
19410 type_found = cfg->inputs[i].type;
19411 pin_found = nid;
19412 }
19413 }
19414 }
19415
19416 nid = 0x07;
19417 if (pin_found)
19418 snd_hda_get_connections(codec, pin_found, &nid, 1);
19419
19420 if (nid != spec->cur_adc)
19421 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19422 spec->cur_adc = nid;
19423 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19424 spec->cur_adc_format);
19425}
19426
c69aefab
KY
19427static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19428 struct hda_codec *codec,
19429 unsigned int stream_tag,
19430 unsigned int format,
19431 struct snd_pcm_substream *substream)
19432{
19433 struct alc_spec *spec = codec->spec;
c69aefab 19434
66ceeb6b 19435 spec->cur_adc = 0x07;
c69aefab
KY
19436 spec->cur_adc_stream_tag = stream_tag;
19437 spec->cur_adc_format = format;
19438
66ceeb6b 19439 alc680_rec_autoswitch(codec);
c69aefab
KY
19440 return 0;
19441}
19442
19443static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19444 struct hda_codec *codec,
19445 struct snd_pcm_substream *substream)
19446{
19447 snd_hda_codec_cleanup_stream(codec, 0x07);
19448 snd_hda_codec_cleanup_stream(codec, 0x08);
19449 snd_hda_codec_cleanup_stream(codec, 0x09);
19450 return 0;
19451}
19452
19453static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19454 .substreams = 1, /* can be overridden */
19455 .channels_min = 2,
19456 .channels_max = 2,
19457 /* NID is set in alc_build_pcms */
19458 .ops = {
19459 .prepare = alc680_capture_pcm_prepare,
19460 .cleanup = alc680_capture_pcm_cleanup
19461 },
19462};
19463
d1eb57f4
KY
19464static struct snd_kcontrol_new alc680_base_mixer[] = {
19465 /* output mixer control */
19466 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19467 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19468 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19469 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
c69aefab 19470 HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT),
d1eb57f4 19471 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c69aefab 19472 HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19473 { }
19474};
19475
c69aefab
KY
19476static struct hda_bind_ctls alc680_bind_cap_vol = {
19477 .ops = &snd_hda_bind_vol,
19478 .values = {
19479 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19480 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19481 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19482 0
19483 },
19484};
19485
19486static struct hda_bind_ctls alc680_bind_cap_switch = {
19487 .ops = &snd_hda_bind_sw,
19488 .values = {
19489 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19490 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19491 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19492 0
19493 },
19494};
19495
19496static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19497 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19498 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19499 { } /* end */
19500};
19501
19502/*
19503 * generic initialization of ADC, input mixers and output mixers
19504 */
19505static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19506 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19507 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19508 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19509
c69aefab
KY
19510 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19511 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19513 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19514 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19515 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19516
19517 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19519 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19520 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19521 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19522
19523 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19524 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19525 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19526
d1eb57f4
KY
19527 { }
19528};
19529
c69aefab
KY
19530/* toggle speaker-output according to the hp-jack state */
19531static void alc680_base_setup(struct hda_codec *codec)
19532{
19533 struct alc_spec *spec = codec->spec;
19534
19535 spec->autocfg.hp_pins[0] = 0x16;
19536 spec->autocfg.speaker_pins[0] = 0x14;
19537 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19538 spec->autocfg.num_inputs = 2;
19539 spec->autocfg.inputs[0].pin = 0x18;
19540 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19541 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19542 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19543}
19544
19545static void alc680_unsol_event(struct hda_codec *codec,
19546 unsigned int res)
19547{
19548 if ((res >> 26) == ALC880_HP_EVENT)
19549 alc_automute_amp(codec);
19550 if ((res >> 26) == ALC880_MIC_EVENT)
19551 alc680_rec_autoswitch(codec);
19552}
19553
19554static void alc680_inithook(struct hda_codec *codec)
19555{
19556 alc_automute_amp(codec);
19557 alc680_rec_autoswitch(codec);
19558}
19559
d1eb57f4
KY
19560/* create input playback/capture controls for the given pin */
19561static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19562 const char *ctlname, int idx)
19563{
19564 hda_nid_t dac;
19565 int err;
19566
19567 switch (nid) {
19568 case 0x14:
19569 dac = 0x02;
19570 break;
19571 case 0x15:
19572 dac = 0x03;
19573 break;
19574 case 0x16:
19575 dac = 0x04;
19576 break;
19577 default:
19578 return 0;
19579 }
19580 if (spec->multiout.dac_nids[0] != dac &&
19581 spec->multiout.dac_nids[1] != dac) {
19582 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19583 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19584 HDA_OUTPUT));
19585 if (err < 0)
19586 return err;
19587
19588 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19589 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19590
19591 if (err < 0)
19592 return err;
19593 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19594 }
19595
19596 return 0;
19597}
19598
19599/* add playback controls from the parsed DAC table */
19600static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19601 const struct auto_pin_cfg *cfg)
19602{
19603 hda_nid_t nid;
19604 int err;
19605
19606 spec->multiout.dac_nids = spec->private_dac_nids;
19607
19608 nid = cfg->line_out_pins[0];
19609 if (nid) {
19610 const char *name;
19611 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19612 name = "Speaker";
19613 else
19614 name = "Front";
19615 err = alc680_new_analog_output(spec, nid, name, 0);
19616 if (err < 0)
19617 return err;
19618 }
19619
19620 nid = cfg->speaker_pins[0];
19621 if (nid) {
19622 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19623 if (err < 0)
19624 return err;
19625 }
19626 nid = cfg->hp_pins[0];
19627 if (nid) {
19628 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19629 if (err < 0)
19630 return err;
19631 }
19632
19633 return 0;
19634}
19635
19636static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19637 hda_nid_t nid, int pin_type)
19638{
19639 alc_set_pin_output(codec, nid, pin_type);
19640}
19641
19642static void alc680_auto_init_multi_out(struct hda_codec *codec)
19643{
19644 struct alc_spec *spec = codec->spec;
19645 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19646 if (nid) {
19647 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19648 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19649 }
19650}
19651
19652static void alc680_auto_init_hp_out(struct hda_codec *codec)
19653{
19654 struct alc_spec *spec = codec->spec;
19655 hda_nid_t pin;
19656
19657 pin = spec->autocfg.hp_pins[0];
19658 if (pin)
19659 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19660 pin = spec->autocfg.speaker_pins[0];
19661 if (pin)
19662 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19663}
19664
19665/* pcm configuration: identical with ALC880 */
19666#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19667#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19668#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19669#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19670#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19671
19672/*
19673 * BIOS auto configuration
19674 */
19675static int alc680_parse_auto_config(struct hda_codec *codec)
19676{
19677 struct alc_spec *spec = codec->spec;
19678 int err;
19679 static hda_nid_t alc680_ignore[] = { 0 };
19680
19681 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19682 alc680_ignore);
19683 if (err < 0)
19684 return err;
c69aefab 19685
d1eb57f4
KY
19686 if (!spec->autocfg.line_outs) {
19687 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19688 spec->multiout.max_channels = 2;
19689 spec->no_analog = 1;
19690 goto dig_only;
19691 }
19692 return 0; /* can't find valid BIOS pin config */
19693 }
19694 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19695 if (err < 0)
19696 return err;
19697
19698 spec->multiout.max_channels = 2;
19699
19700 dig_only:
19701 /* digital only support output */
757899ac 19702 alc_auto_parse_digital(codec);
d1eb57f4
KY
19703 if (spec->kctls.list)
19704 add_mixer(spec, spec->kctls.list);
19705
19706 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19707
19708 err = alc_auto_add_mic_boost(codec);
19709 if (err < 0)
19710 return err;
19711
19712 return 1;
19713}
19714
19715#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19716
19717/* init callback for auto-configuration model -- overriding the default init */
19718static void alc680_auto_init(struct hda_codec *codec)
19719{
19720 struct alc_spec *spec = codec->spec;
19721 alc680_auto_init_multi_out(codec);
19722 alc680_auto_init_hp_out(codec);
19723 alc680_auto_init_analog_input(codec);
757899ac 19724 alc_auto_init_digital(codec);
d1eb57f4
KY
19725 if (spec->unsol_event)
19726 alc_inithook(codec);
19727}
19728
19729/*
19730 * configuration and preset
19731 */
19732static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19733 [ALC680_BASE] = "base",
19734 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19735};
19736
19737static struct snd_pci_quirk alc680_cfg_tbl[] = {
19738 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19739 {}
19740};
19741
19742static struct alc_config_preset alc680_presets[] = {
19743 [ALC680_BASE] = {
19744 .mixers = { alc680_base_mixer },
c69aefab 19745 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19746 .init_verbs = { alc680_init_verbs },
19747 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19748 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19749 .dig_out_nid = ALC680_DIGOUT_NID,
19750 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19751 .channel_mode = alc680_modes,
c69aefab
KY
19752 .unsol_event = alc680_unsol_event,
19753 .setup = alc680_base_setup,
19754 .init_hook = alc680_inithook,
19755
d1eb57f4
KY
19756 },
19757};
19758
19759static int patch_alc680(struct hda_codec *codec)
19760{
19761 struct alc_spec *spec;
19762 int board_config;
19763 int err;
19764
19765 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19766 if (spec == NULL)
19767 return -ENOMEM;
19768
19769 codec->spec = spec;
19770
19771 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19772 alc680_models,
19773 alc680_cfg_tbl);
19774
19775 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19776 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19777 codec->chip_name);
19778 board_config = ALC680_AUTO;
19779 }
19780
19781 if (board_config == ALC680_AUTO) {
19782 /* automatic parse from the BIOS config */
19783 err = alc680_parse_auto_config(codec);
19784 if (err < 0) {
19785 alc_free(codec);
19786 return err;
19787 } else if (!err) {
19788 printk(KERN_INFO
19789 "hda_codec: Cannot set up configuration "
19790 "from BIOS. Using base mode...\n");
19791 board_config = ALC680_BASE;
19792 }
19793 }
19794
19795 if (board_config != ALC680_AUTO)
19796 setup_preset(codec, &alc680_presets[board_config]);
19797
19798 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19799 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19800 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19801 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19802
19803 if (!spec->adc_nids) {
19804 spec->adc_nids = alc680_adc_nids;
19805 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19806 }
19807
19808 if (!spec->cap_mixer)
19809 set_capture_mixer(codec);
19810
19811 spec->vmaster_nid = 0x02;
19812
19813 codec->patch_ops = alc_patch_ops;
19814 if (board_config == ALC680_AUTO)
19815 spec->init_hook = alc680_auto_init;
19816
19817 return 0;
19818}
19819
1da177e4
LT
19820/*
19821 * patch entries
19822 */
1289e9e8 19823static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19824 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19825 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19826 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19827 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19828 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19829 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19830 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19831 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19832 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19833 .patch = patch_alc861 },
f32610ed
JS
19834 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19835 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19836 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19837 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19838 .patch = patch_alc882 },
bc9f98a9
KY
19839 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19840 .patch = patch_alc662 },
6dda9f4a 19841 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19842 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19843 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19844 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19845 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19846 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19847 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19848 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19849 .patch = patch_alc882 },
cb308f97 19850 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19851 .patch = patch_alc882 },
df694daa 19852 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 19853 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 19854 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19855 .patch = patch_alc882 },
274693f3 19856 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19857 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19858 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
19859 {} /* terminator */
19860};
1289e9e8
TI
19861
19862MODULE_ALIAS("snd-hda-codec-id:10ec*");
19863
19864MODULE_LICENSE("GPL");
19865MODULE_DESCRIPTION("Realtek HD-audio codec");
19866
19867static struct hda_codec_preset_list realtek_list = {
19868 .preset = snd_hda_preset_realtek,
19869 .owner = THIS_MODULE,
19870};
19871
19872static int __init patch_realtek_init(void)
19873{
19874 return snd_hda_add_codec_preset(&realtek_list);
19875}
19876
19877static void __exit patch_realtek_exit(void)
19878{
19879 snd_hda_delete_codec_preset(&realtek_list);
19880}
19881
19882module_init(patch_realtek_init)
19883module_exit(patch_realtek_exit)